GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / tee / optee / core.c
1 /*
2  * Copyright (c) 2015, Linaro Limited
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17 #include <linux/arm-smccc.h>
18 #include <linux/errno.h>
19 #include <linux/io.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/of_platform.h>
23 #include <linux/platform_device.h>
24 #include <linux/slab.h>
25 #include <linux/string.h>
26 #include <linux/tee_drv.h>
27 #include <linux/types.h>
28 #include <linux/uaccess.h>
29 #include "optee_private.h"
30 #include "optee_smc.h"
31
32 #define DRIVER_NAME "optee"
33
34 #define OPTEE_SHM_NUM_PRIV_PAGES        1
35
36 /**
37  * optee_from_msg_param() - convert from OPTEE_MSG parameters to
38  *                          struct tee_param
39  * @params:     subsystem internal parameter representation
40  * @num_params: number of elements in the parameter arrays
41  * @msg_params: OPTEE_MSG parameters
42  * Returns 0 on success or <0 on failure
43  */
44 int optee_from_msg_param(struct tee_param *params, size_t num_params,
45                          const struct optee_msg_param *msg_params)
46 {
47         int rc;
48         size_t n;
49         struct tee_shm *shm;
50         phys_addr_t pa;
51
52         for (n = 0; n < num_params; n++) {
53                 struct tee_param *p = params + n;
54                 const struct optee_msg_param *mp = msg_params + n;
55                 u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
56
57                 switch (attr) {
58                 case OPTEE_MSG_ATTR_TYPE_NONE:
59                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
60                         memset(&p->u, 0, sizeof(p->u));
61                         break;
62                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
63                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
64                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
65                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
66                                   attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
67                         p->u.value.a = mp->u.value.a;
68                         p->u.value.b = mp->u.value.b;
69                         p->u.value.c = mp->u.value.c;
70                         break;
71                 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
72                 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
73                 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
74                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
75                                   attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
76                         p->u.memref.size = mp->u.tmem.size;
77                         shm = (struct tee_shm *)(unsigned long)
78                                 mp->u.tmem.shm_ref;
79                         if (!shm) {
80                                 p->u.memref.shm_offs = 0;
81                                 p->u.memref.shm = NULL;
82                                 break;
83                         }
84                         rc = tee_shm_get_pa(shm, 0, &pa);
85                         if (rc)
86                                 return rc;
87                         p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
88                         p->u.memref.shm = shm;
89                         break;
90                 default:
91                         return -EINVAL;
92                 }
93         }
94         return 0;
95 }
96
97 /**
98  * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
99  * @msg_params: OPTEE_MSG parameters
100  * @num_params: number of elements in the parameter arrays
101  * @params:     subsystem itnernal parameter representation
102  * Returns 0 on success or <0 on failure
103  */
104 int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
105                        const struct tee_param *params)
106 {
107         int rc;
108         size_t n;
109         phys_addr_t pa;
110
111         for (n = 0; n < num_params; n++) {
112                 const struct tee_param *p = params + n;
113                 struct optee_msg_param *mp = msg_params + n;
114
115                 switch (p->attr) {
116                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
117                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
118                         memset(&mp->u, 0, sizeof(mp->u));
119                         break;
120                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
121                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
122                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
123                         mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
124                                    TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
125                         mp->u.value.a = p->u.value.a;
126                         mp->u.value.b = p->u.value.b;
127                         mp->u.value.c = p->u.value.c;
128                         break;
129                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
130                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
131                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
132                         mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT +
133                                    p->attr -
134                                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
135                         mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
136                         mp->u.tmem.size = p->u.memref.size;
137                         if (!p->u.memref.shm) {
138                                 mp->u.tmem.buf_ptr = 0;
139                                 break;
140                         }
141                         rc = tee_shm_get_pa(p->u.memref.shm,
142                                             p->u.memref.shm_offs, &pa);
143                         if (rc)
144                                 return rc;
145                         mp->u.tmem.buf_ptr = pa;
146                         mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
147                                         OPTEE_MSG_ATTR_CACHE_SHIFT;
148                         break;
149                 default:
150                         return -EINVAL;
151                 }
152         }
153         return 0;
154 }
155
156 static void optee_get_version(struct tee_device *teedev,
157                               struct tee_ioctl_version_data *vers)
158 {
159         struct tee_ioctl_version_data v = {
160                 .impl_id = TEE_IMPL_ID_OPTEE,
161                 .impl_caps = TEE_OPTEE_CAP_TZ,
162                 .gen_caps = TEE_GEN_CAP_GP,
163         };
164         *vers = v;
165 }
166
167 static int optee_open(struct tee_context *ctx)
168 {
169         struct optee_context_data *ctxdata;
170         struct tee_device *teedev = ctx->teedev;
171         struct optee *optee = tee_get_drvdata(teedev);
172
173         ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
174         if (!ctxdata)
175                 return -ENOMEM;
176
177         if (teedev == optee->supp_teedev) {
178                 bool busy = true;
179
180                 mutex_lock(&optee->supp.ctx_mutex);
181                 if (!optee->supp.ctx) {
182                         busy = false;
183                         optee->supp.ctx = ctx;
184                 }
185                 mutex_unlock(&optee->supp.ctx_mutex);
186                 if (busy) {
187                         kfree(ctxdata);
188                         return -EBUSY;
189                 }
190         }
191
192         mutex_init(&ctxdata->mutex);
193         INIT_LIST_HEAD(&ctxdata->sess_list);
194
195         ctx->data = ctxdata;
196         return 0;
197 }
198
199 static void optee_release(struct tee_context *ctx)
200 {
201         struct optee_context_data *ctxdata = ctx->data;
202         struct tee_device *teedev = ctx->teedev;
203         struct optee *optee = tee_get_drvdata(teedev);
204         struct tee_shm *shm;
205         struct optee_msg_arg *arg = NULL;
206         phys_addr_t parg;
207         struct optee_session *sess;
208         struct optee_session *sess_tmp;
209
210         if (!ctxdata)
211                 return;
212
213         shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED);
214         if (!IS_ERR(shm)) {
215                 arg = tee_shm_get_va(shm, 0);
216                 /*
217                  * If va2pa fails for some reason, we can't call into
218                  * secure world, only free the memory. Secure OS will leak
219                  * sessions and finally refuse more sessions, but we will
220                  * at least let normal world reclaim its memory.
221                  */
222                 if (!IS_ERR(arg))
223                         if (tee_shm_va2pa(shm, arg, &parg))
224                                 arg = NULL; /* prevent usage of parg below */
225         }
226
227         list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
228                                  list_node) {
229                 list_del(&sess->list_node);
230                 if (!IS_ERR_OR_NULL(arg)) {
231                         memset(arg, 0, sizeof(*arg));
232                         arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
233                         arg->session = sess->session_id;
234                         optee_do_call_with_arg(ctx, parg);
235                 }
236                 kfree(sess);
237         }
238         kfree(ctxdata);
239
240         if (!IS_ERR(shm))
241                 tee_shm_free(shm);
242
243         ctx->data = NULL;
244
245         if (teedev == optee->supp_teedev) {
246                 mutex_lock(&optee->supp.ctx_mutex);
247                 optee->supp.ctx = NULL;
248                 mutex_unlock(&optee->supp.ctx_mutex);
249         }
250 }
251
252 static const struct tee_driver_ops optee_ops = {
253         .get_version = optee_get_version,
254         .open = optee_open,
255         .release = optee_release,
256         .open_session = optee_open_session,
257         .close_session = optee_close_session,
258         .invoke_func = optee_invoke_func,
259         .cancel_req = optee_cancel_req,
260 };
261
262 static const struct tee_desc optee_desc = {
263         .name = DRIVER_NAME "-clnt",
264         .ops = &optee_ops,
265         .owner = THIS_MODULE,
266 };
267
268 static const struct tee_driver_ops optee_supp_ops = {
269         .get_version = optee_get_version,
270         .open = optee_open,
271         .release = optee_release,
272         .supp_recv = optee_supp_recv,
273         .supp_send = optee_supp_send,
274 };
275
276 static const struct tee_desc optee_supp_desc = {
277         .name = DRIVER_NAME "-supp",
278         .ops = &optee_supp_ops,
279         .owner = THIS_MODULE,
280         .flags = TEE_DESC_PRIVILEGED,
281 };
282
283 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
284 {
285         struct arm_smccc_res res;
286
287         invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
288
289         if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
290             res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
291                 return true;
292         return false;
293 }
294
295 static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
296 {
297         union {
298                 struct arm_smccc_res smccc;
299                 struct optee_smc_calls_revision_result result;
300         } res;
301
302         invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
303
304         if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
305             (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
306                 return true;
307         return false;
308 }
309
310 static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
311                                             u32 *sec_caps)
312 {
313         union {
314                 struct arm_smccc_res smccc;
315                 struct optee_smc_exchange_capabilities_result result;
316         } res;
317         u32 a1 = 0;
318
319         /*
320          * TODO This isn't enough to tell if it's UP system (from kernel
321          * point of view) or not, is_smp() returns the the information
322          * needed, but can't be called directly from here.
323          */
324         if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
325                 a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
326
327         invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
328                   &res.smccc);
329
330         if (res.result.status != OPTEE_SMC_RETURN_OK)
331                 return false;
332
333         *sec_caps = res.result.capabilities;
334         return true;
335 }
336
337 static struct tee_shm_pool *
338 optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
339 {
340         union {
341                 struct arm_smccc_res smccc;
342                 struct optee_smc_get_shm_config_result result;
343         } res;
344         struct tee_shm_pool *pool;
345         unsigned long vaddr;
346         phys_addr_t paddr;
347         size_t size;
348         phys_addr_t begin;
349         phys_addr_t end;
350         void *va;
351         struct tee_shm_pool_mem_info priv_info;
352         struct tee_shm_pool_mem_info dmabuf_info;
353
354         invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
355         if (res.result.status != OPTEE_SMC_RETURN_OK) {
356                 pr_info("shm service not available\n");
357                 return ERR_PTR(-ENOENT);
358         }
359
360         if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
361                 pr_err("only normal cached shared memory supported\n");
362                 return ERR_PTR(-EINVAL);
363         }
364
365         begin = roundup(res.result.start, PAGE_SIZE);
366         end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
367         paddr = begin;
368         size = end - begin;
369
370         if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
371                 pr_err("too small shared memory area\n");
372                 return ERR_PTR(-EINVAL);
373         }
374
375         va = memremap(paddr, size, MEMREMAP_WB);
376         if (!va) {
377                 pr_err("shared memory ioremap failed\n");
378                 return ERR_PTR(-EINVAL);
379         }
380         vaddr = (unsigned long)va;
381
382         priv_info.vaddr = vaddr;
383         priv_info.paddr = paddr;
384         priv_info.size = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
385         dmabuf_info.vaddr = vaddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
386         dmabuf_info.paddr = paddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
387         dmabuf_info.size = size - OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
388
389         pool = tee_shm_pool_alloc_res_mem(&priv_info, &dmabuf_info);
390         if (IS_ERR(pool)) {
391                 memunmap(va);
392                 goto out;
393         }
394
395         *memremaped_shm = va;
396 out:
397         return pool;
398 }
399
400 /* Simple wrapper functions to be able to use a function pointer */
401 static void optee_smccc_smc(unsigned long a0, unsigned long a1,
402                             unsigned long a2, unsigned long a3,
403                             unsigned long a4, unsigned long a5,
404                             unsigned long a6, unsigned long a7,
405                             struct arm_smccc_res *res)
406 {
407         arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
408 }
409
410 static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
411                             unsigned long a2, unsigned long a3,
412                             unsigned long a4, unsigned long a5,
413                             unsigned long a6, unsigned long a7,
414                             struct arm_smccc_res *res)
415 {
416         arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
417 }
418
419 static optee_invoke_fn *get_invoke_func(struct device_node *np)
420 {
421         const char *method;
422
423         pr_info("probing for conduit method from DT.\n");
424
425         if (of_property_read_string(np, "method", &method)) {
426                 pr_warn("missing \"method\" property\n");
427                 return ERR_PTR(-ENXIO);
428         }
429
430         if (!strcmp("hvc", method))
431                 return optee_smccc_hvc;
432         else if (!strcmp("smc", method))
433                 return optee_smccc_smc;
434
435         pr_warn("invalid \"method\" property: %s\n", method);
436         return ERR_PTR(-EINVAL);
437 }
438
439 static struct optee *optee_probe(struct device_node *np)
440 {
441         optee_invoke_fn *invoke_fn;
442         struct tee_shm_pool *pool;
443         struct optee *optee = NULL;
444         void *memremaped_shm = NULL;
445         struct tee_device *teedev;
446         u32 sec_caps;
447         int rc;
448
449         invoke_fn = get_invoke_func(np);
450         if (IS_ERR(invoke_fn))
451                 return (void *)invoke_fn;
452
453         if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
454                 pr_warn("api uid mismatch\n");
455                 return ERR_PTR(-EINVAL);
456         }
457
458         if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
459                 pr_warn("api revision mismatch\n");
460                 return ERR_PTR(-EINVAL);
461         }
462
463         if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
464                 pr_warn("capabilities mismatch\n");
465                 return ERR_PTR(-EINVAL);
466         }
467
468         /*
469          * We have no other option for shared memory, if secure world
470          * doesn't have any reserved memory we can use we can't continue.
471          */
472         if (!(sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
473                 return ERR_PTR(-EINVAL);
474
475         pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
476         if (IS_ERR(pool))
477                 return (void *)pool;
478
479         optee = kzalloc(sizeof(*optee), GFP_KERNEL);
480         if (!optee) {
481                 rc = -ENOMEM;
482                 goto err;
483         }
484
485         optee->invoke_fn = invoke_fn;
486
487         teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
488         if (IS_ERR(teedev)) {
489                 rc = PTR_ERR(teedev);
490                 goto err;
491         }
492         optee->teedev = teedev;
493
494         teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
495         if (IS_ERR(teedev)) {
496                 rc = PTR_ERR(teedev);
497                 goto err;
498         }
499         optee->supp_teedev = teedev;
500
501         rc = tee_device_register(optee->teedev);
502         if (rc)
503                 goto err;
504
505         rc = tee_device_register(optee->supp_teedev);
506         if (rc)
507                 goto err;
508
509         mutex_init(&optee->call_queue.mutex);
510         INIT_LIST_HEAD(&optee->call_queue.waiters);
511         optee_wait_queue_init(&optee->wait_queue);
512         optee_supp_init(&optee->supp);
513         optee->memremaped_shm = memremaped_shm;
514         optee->pool = pool;
515
516         optee_enable_shm_cache(optee);
517
518         pr_info("initialized driver\n");
519         return optee;
520 err:
521         if (optee) {
522                 /*
523                  * tee_device_unregister() is safe to call even if the
524                  * devices hasn't been registered with
525                  * tee_device_register() yet.
526                  */
527                 tee_device_unregister(optee->supp_teedev);
528                 tee_device_unregister(optee->teedev);
529                 kfree(optee);
530         }
531         if (pool)
532                 tee_shm_pool_free(pool);
533         if (memremaped_shm)
534                 memunmap(memremaped_shm);
535         return ERR_PTR(rc);
536 }
537
538 static void optee_remove(struct optee *optee)
539 {
540         /*
541          * Ask OP-TEE to free all cached shared memory objects to decrease
542          * reference counters and also avoid wild pointers in secure world
543          * into the old shared memory range.
544          */
545         optee_disable_shm_cache(optee);
546
547         /*
548          * The two devices has to be unregistered before we can free the
549          * other resources.
550          */
551         tee_device_unregister(optee->supp_teedev);
552         tee_device_unregister(optee->teedev);
553
554         tee_shm_pool_free(optee->pool);
555         if (optee->memremaped_shm)
556                 memunmap(optee->memremaped_shm);
557         optee_wait_queue_exit(&optee->wait_queue);
558         optee_supp_uninit(&optee->supp);
559         mutex_destroy(&optee->call_queue.mutex);
560
561         kfree(optee);
562 }
563
564 static const struct of_device_id optee_match[] = {
565         { .compatible = "linaro,optee-tz" },
566         {},
567 };
568
569 static struct optee *optee_svc;
570
571 static int __init optee_driver_init(void)
572 {
573         struct device_node *fw_np;
574         struct device_node *np;
575         struct optee *optee;
576
577         /* Node is supposed to be below /firmware */
578         fw_np = of_find_node_by_name(NULL, "firmware");
579         if (!fw_np)
580                 return -ENODEV;
581
582         np = of_find_matching_node(fw_np, optee_match);
583         if (!np || !of_device_is_available(np)) {
584                 of_node_put(np);
585                 return -ENODEV;
586         }
587
588         optee = optee_probe(np);
589         of_node_put(np);
590
591         if (IS_ERR(optee))
592                 return PTR_ERR(optee);
593
594         optee_svc = optee;
595
596         return 0;
597 }
598 module_init(optee_driver_init);
599
600 static void __exit optee_driver_exit(void)
601 {
602         struct optee *optee = optee_svc;
603
604         optee_svc = NULL;
605         if (optee)
606                 optee_remove(optee);
607 }
608 module_exit(optee_driver_exit);
609
610 MODULE_AUTHOR("Linaro");
611 MODULE_DESCRIPTION("OP-TEE driver");
612 MODULE_SUPPORTED_DEVICE("");
613 MODULE_VERSION("1.0");
614 MODULE_LICENSE("GPL v2");