2 * Copyright (c) 2015, Linaro Limited
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.
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.
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/arm-smccc.h>
18 #include <linux/errno.h>
20 #include <linux/module.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"
32 #define DRIVER_NAME "optee"
34 #define OPTEE_SHM_NUM_PRIV_PAGES 1
37 * optee_from_msg_param() - convert from OPTEE_MSG parameters to
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
44 int optee_from_msg_param(struct tee_param
*params
, size_t num_params
,
45 const struct optee_msg_param
*msg_params
)
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
;
58 case OPTEE_MSG_ATTR_TYPE_NONE
:
59 p
->attr
= TEE_IOCTL_PARAM_ATTR_TYPE_NONE
;
60 memset(&p
->u
, 0, sizeof(p
->u
));
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
;
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)
80 p
->u
.memref
.shm_offs
= 0;
81 p
->u
.memref
.shm
= NULL
;
84 rc
= tee_shm_get_pa(shm
, 0, &pa
);
87 p
->u
.memref
.shm_offs
= mp
->u
.tmem
.buf_ptr
- pa
;
88 p
->u
.memref
.shm
= shm
;
90 /* Check that the memref is covered by the shm object */
91 if (p
->u
.memref
.size
) {
92 size_t o
= p
->u
.memref
.shm_offs
+
95 rc
= tee_shm_get_pa(shm
, o
, NULL
);
108 * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
109 * @msg_params: OPTEE_MSG parameters
110 * @num_params: number of elements in the parameter arrays
111 * @params: subsystem itnernal parameter representation
112 * Returns 0 on success or <0 on failure
114 int optee_to_msg_param(struct optee_msg_param
*msg_params
, size_t num_params
,
115 const struct tee_param
*params
)
121 for (n
= 0; n
< num_params
; n
++) {
122 const struct tee_param
*p
= params
+ n
;
123 struct optee_msg_param
*mp
= msg_params
+ n
;
126 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE
:
127 mp
->attr
= TEE_IOCTL_PARAM_ATTR_TYPE_NONE
;
128 memset(&mp
->u
, 0, sizeof(mp
->u
));
130 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT
:
131 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT
:
132 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT
:
133 mp
->attr
= OPTEE_MSG_ATTR_TYPE_VALUE_INPUT
+ p
->attr
-
134 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT
;
135 mp
->u
.value
.a
= p
->u
.value
.a
;
136 mp
->u
.value
.b
= p
->u
.value
.b
;
137 mp
->u
.value
.c
= p
->u
.value
.c
;
139 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT
:
140 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT
:
141 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT
:
142 mp
->attr
= OPTEE_MSG_ATTR_TYPE_TMEM_INPUT
+
144 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT
;
145 mp
->u
.tmem
.shm_ref
= (unsigned long)p
->u
.memref
.shm
;
146 mp
->u
.tmem
.size
= p
->u
.memref
.size
;
147 if (!p
->u
.memref
.shm
) {
148 mp
->u
.tmem
.buf_ptr
= 0;
151 rc
= tee_shm_get_pa(p
->u
.memref
.shm
,
152 p
->u
.memref
.shm_offs
, &pa
);
155 mp
->u
.tmem
.buf_ptr
= pa
;
156 mp
->attr
|= OPTEE_MSG_ATTR_CACHE_PREDEFINED
<<
157 OPTEE_MSG_ATTR_CACHE_SHIFT
;
166 static void optee_get_version(struct tee_device
*teedev
,
167 struct tee_ioctl_version_data
*vers
)
169 struct tee_ioctl_version_data v
= {
170 .impl_id
= TEE_IMPL_ID_OPTEE
,
171 .impl_caps
= TEE_OPTEE_CAP_TZ
,
172 .gen_caps
= TEE_GEN_CAP_GP
,
177 static int optee_open(struct tee_context
*ctx
)
179 struct optee_context_data
*ctxdata
;
180 struct tee_device
*teedev
= ctx
->teedev
;
181 struct optee
*optee
= tee_get_drvdata(teedev
);
183 ctxdata
= kzalloc(sizeof(*ctxdata
), GFP_KERNEL
);
187 if (teedev
== optee
->supp_teedev
) {
190 mutex_lock(&optee
->supp
.ctx_mutex
);
191 if (!optee
->supp
.ctx
) {
193 optee
->supp
.ctx
= ctx
;
195 mutex_unlock(&optee
->supp
.ctx_mutex
);
202 mutex_init(&ctxdata
->mutex
);
203 INIT_LIST_HEAD(&ctxdata
->sess_list
);
209 static void optee_release(struct tee_context
*ctx
)
211 struct optee_context_data
*ctxdata
= ctx
->data
;
212 struct tee_device
*teedev
= ctx
->teedev
;
213 struct optee
*optee
= tee_get_drvdata(teedev
);
215 struct optee_msg_arg
*arg
= NULL
;
217 struct optee_session
*sess
;
218 struct optee_session
*sess_tmp
;
223 shm
= tee_shm_alloc(ctx
, sizeof(struct optee_msg_arg
), TEE_SHM_MAPPED
);
225 arg
= tee_shm_get_va(shm
, 0);
227 * If va2pa fails for some reason, we can't call into
228 * secure world, only free the memory. Secure OS will leak
229 * sessions and finally refuse more sessions, but we will
230 * at least let normal world reclaim its memory.
233 if (tee_shm_va2pa(shm
, arg
, &parg
))
234 arg
= NULL
; /* prevent usage of parg below */
237 list_for_each_entry_safe(sess
, sess_tmp
, &ctxdata
->sess_list
,
239 list_del(&sess
->list_node
);
240 if (!IS_ERR_OR_NULL(arg
)) {
241 memset(arg
, 0, sizeof(*arg
));
242 arg
->cmd
= OPTEE_MSG_CMD_CLOSE_SESSION
;
243 arg
->session
= sess
->session_id
;
244 optee_do_call_with_arg(ctx
, parg
);
255 if (teedev
== optee
->supp_teedev
) {
256 mutex_lock(&optee
->supp
.ctx_mutex
);
257 optee
->supp
.ctx
= NULL
;
258 mutex_unlock(&optee
->supp
.ctx_mutex
);
262 static const struct tee_driver_ops optee_ops
= {
263 .get_version
= optee_get_version
,
265 .release
= optee_release
,
266 .open_session
= optee_open_session
,
267 .close_session
= optee_close_session
,
268 .invoke_func
= optee_invoke_func
,
269 .cancel_req
= optee_cancel_req
,
272 static const struct tee_desc optee_desc
= {
273 .name
= DRIVER_NAME
"-clnt",
275 .owner
= THIS_MODULE
,
278 static const struct tee_driver_ops optee_supp_ops
= {
279 .get_version
= optee_get_version
,
281 .release
= optee_release
,
282 .supp_recv
= optee_supp_recv
,
283 .supp_send
= optee_supp_send
,
286 static const struct tee_desc optee_supp_desc
= {
287 .name
= DRIVER_NAME
"-supp",
288 .ops
= &optee_supp_ops
,
289 .owner
= THIS_MODULE
,
290 .flags
= TEE_DESC_PRIVILEGED
,
293 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn
*invoke_fn
)
295 struct arm_smccc_res res
;
297 invoke_fn(OPTEE_SMC_CALLS_UID
, 0, 0, 0, 0, 0, 0, 0, &res
);
299 if (res
.a0
== OPTEE_MSG_UID_0
&& res
.a1
== OPTEE_MSG_UID_1
&&
300 res
.a2
== OPTEE_MSG_UID_2
&& res
.a3
== OPTEE_MSG_UID_3
)
305 static bool optee_msg_api_revision_is_compatible(optee_invoke_fn
*invoke_fn
)
308 struct arm_smccc_res smccc
;
309 struct optee_smc_calls_revision_result result
;
312 invoke_fn(OPTEE_SMC_CALLS_REVISION
, 0, 0, 0, 0, 0, 0, 0, &res
.smccc
);
314 if (res
.result
.major
== OPTEE_MSG_REVISION_MAJOR
&&
315 (int)res
.result
.minor
>= OPTEE_MSG_REVISION_MINOR
)
320 static bool optee_msg_exchange_capabilities(optee_invoke_fn
*invoke_fn
,
324 struct arm_smccc_res smccc
;
325 struct optee_smc_exchange_capabilities_result result
;
330 * TODO This isn't enough to tell if it's UP system (from kernel
331 * point of view) or not, is_smp() returns the the information
332 * needed, but can't be called directly from here.
334 if (!IS_ENABLED(CONFIG_SMP
) || nr_cpu_ids
== 1)
335 a1
|= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR
;
337 invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES
, a1
, 0, 0, 0, 0, 0, 0,
340 if (res
.result
.status
!= OPTEE_SMC_RETURN_OK
)
343 *sec_caps
= res
.result
.capabilities
;
347 static struct tee_shm_pool
*
348 optee_config_shm_memremap(optee_invoke_fn
*invoke_fn
, void **memremaped_shm
)
351 struct arm_smccc_res smccc
;
352 struct optee_smc_get_shm_config_result result
;
354 struct tee_shm_pool
*pool
;
361 struct tee_shm_pool_mem_info priv_info
;
362 struct tee_shm_pool_mem_info dmabuf_info
;
364 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG
, 0, 0, 0, 0, 0, 0, 0, &res
.smccc
);
365 if (res
.result
.status
!= OPTEE_SMC_RETURN_OK
) {
366 pr_info("shm service not available\n");
367 return ERR_PTR(-ENOENT
);
370 if (res
.result
.settings
!= OPTEE_SMC_SHM_CACHED
) {
371 pr_err("only normal cached shared memory supported\n");
372 return ERR_PTR(-EINVAL
);
375 begin
= roundup(res
.result
.start
, PAGE_SIZE
);
376 end
= rounddown(res
.result
.start
+ res
.result
.size
, PAGE_SIZE
);
380 if (size
< 2 * OPTEE_SHM_NUM_PRIV_PAGES
* PAGE_SIZE
) {
381 pr_err("too small shared memory area\n");
382 return ERR_PTR(-EINVAL
);
385 va
= memremap(paddr
, size
, MEMREMAP_WB
);
387 pr_err("shared memory ioremap failed\n");
388 return ERR_PTR(-EINVAL
);
390 vaddr
= (unsigned long)va
;
392 priv_info
.vaddr
= vaddr
;
393 priv_info
.paddr
= paddr
;
394 priv_info
.size
= OPTEE_SHM_NUM_PRIV_PAGES
* PAGE_SIZE
;
395 dmabuf_info
.vaddr
= vaddr
+ OPTEE_SHM_NUM_PRIV_PAGES
* PAGE_SIZE
;
396 dmabuf_info
.paddr
= paddr
+ OPTEE_SHM_NUM_PRIV_PAGES
* PAGE_SIZE
;
397 dmabuf_info
.size
= size
- OPTEE_SHM_NUM_PRIV_PAGES
* PAGE_SIZE
;
399 pool
= tee_shm_pool_alloc_res_mem(&priv_info
, &dmabuf_info
);
405 *memremaped_shm
= va
;
410 /* Simple wrapper functions to be able to use a function pointer */
411 static void optee_smccc_smc(unsigned long a0
, unsigned long a1
,
412 unsigned long a2
, unsigned long a3
,
413 unsigned long a4
, unsigned long a5
,
414 unsigned long a6
, unsigned long a7
,
415 struct arm_smccc_res
*res
)
417 arm_smccc_smc(a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, res
);
420 static void optee_smccc_hvc(unsigned long a0
, unsigned long a1
,
421 unsigned long a2
, unsigned long a3
,
422 unsigned long a4
, unsigned long a5
,
423 unsigned long a6
, unsigned long a7
,
424 struct arm_smccc_res
*res
)
426 arm_smccc_hvc(a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, res
);
429 static optee_invoke_fn
*get_invoke_func(struct device_node
*np
)
433 pr_info("probing for conduit method from DT.\n");
435 if (of_property_read_string(np
, "method", &method
)) {
436 pr_warn("missing \"method\" property\n");
437 return ERR_PTR(-ENXIO
);
440 if (!strcmp("hvc", method
))
441 return optee_smccc_hvc
;
442 else if (!strcmp("smc", method
))
443 return optee_smccc_smc
;
445 pr_warn("invalid \"method\" property: %s\n", method
);
446 return ERR_PTR(-EINVAL
);
449 static struct optee
*optee_probe(struct device_node
*np
)
451 optee_invoke_fn
*invoke_fn
;
452 struct tee_shm_pool
*pool
;
453 struct optee
*optee
= NULL
;
454 void *memremaped_shm
= NULL
;
455 struct tee_device
*teedev
;
459 invoke_fn
= get_invoke_func(np
);
460 if (IS_ERR(invoke_fn
))
461 return (void *)invoke_fn
;
463 if (!optee_msg_api_uid_is_optee_api(invoke_fn
)) {
464 pr_warn("api uid mismatch\n");
465 return ERR_PTR(-EINVAL
);
468 if (!optee_msg_api_revision_is_compatible(invoke_fn
)) {
469 pr_warn("api revision mismatch\n");
470 return ERR_PTR(-EINVAL
);
473 if (!optee_msg_exchange_capabilities(invoke_fn
, &sec_caps
)) {
474 pr_warn("capabilities mismatch\n");
475 return ERR_PTR(-EINVAL
);
479 * We have no other option for shared memory, if secure world
480 * doesn't have any reserved memory we can use we can't continue.
482 if (!(sec_caps
& OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM
))
483 return ERR_PTR(-EINVAL
);
485 pool
= optee_config_shm_memremap(invoke_fn
, &memremaped_shm
);
489 optee
= kzalloc(sizeof(*optee
), GFP_KERNEL
);
495 optee
->invoke_fn
= invoke_fn
;
497 teedev
= tee_device_alloc(&optee_desc
, NULL
, pool
, optee
);
498 if (IS_ERR(teedev
)) {
499 rc
= PTR_ERR(teedev
);
502 optee
->teedev
= teedev
;
504 teedev
= tee_device_alloc(&optee_supp_desc
, NULL
, pool
, optee
);
505 if (IS_ERR(teedev
)) {
506 rc
= PTR_ERR(teedev
);
509 optee
->supp_teedev
= teedev
;
511 rc
= tee_device_register(optee
->teedev
);
515 rc
= tee_device_register(optee
->supp_teedev
);
519 mutex_init(&optee
->call_queue
.mutex
);
520 INIT_LIST_HEAD(&optee
->call_queue
.waiters
);
521 optee_wait_queue_init(&optee
->wait_queue
);
522 optee_supp_init(&optee
->supp
);
523 optee
->memremaped_shm
= memremaped_shm
;
526 optee_enable_shm_cache(optee
);
528 pr_info("initialized driver\n");
533 * tee_device_unregister() is safe to call even if the
534 * devices hasn't been registered with
535 * tee_device_register() yet.
537 tee_device_unregister(optee
->supp_teedev
);
538 tee_device_unregister(optee
->teedev
);
542 tee_shm_pool_free(pool
);
544 memunmap(memremaped_shm
);
548 static void optee_remove(struct optee
*optee
)
551 * Ask OP-TEE to free all cached shared memory objects to decrease
552 * reference counters and also avoid wild pointers in secure world
553 * into the old shared memory range.
555 optee_disable_shm_cache(optee
);
558 * The two devices has to be unregistered before we can free the
561 tee_device_unregister(optee
->supp_teedev
);
562 tee_device_unregister(optee
->teedev
);
564 tee_shm_pool_free(optee
->pool
);
565 if (optee
->memremaped_shm
)
566 memunmap(optee
->memremaped_shm
);
567 optee_wait_queue_exit(&optee
->wait_queue
);
568 optee_supp_uninit(&optee
->supp
);
569 mutex_destroy(&optee
->call_queue
.mutex
);
574 static const struct of_device_id optee_match
[] = {
575 { .compatible
= "linaro,optee-tz" },
579 static struct optee
*optee_svc
;
581 static int __init
optee_driver_init(void)
583 struct device_node
*fw_np
;
584 struct device_node
*np
;
587 /* Node is supposed to be below /firmware */
588 fw_np
= of_find_node_by_name(NULL
, "firmware");
592 np
= of_find_matching_node(fw_np
, optee_match
);
596 optee
= optee_probe(np
);
600 return PTR_ERR(optee
);
606 module_init(optee_driver_init
);
608 static void __exit
optee_driver_exit(void)
610 struct optee
*optee
= optee_svc
;
616 module_exit(optee_driver_exit
);
618 MODULE_AUTHOR("Linaro");
619 MODULE_DESCRIPTION("OP-TEE driver");
620 MODULE_SUPPORTED_DEVICE("");
621 MODULE_VERSION("1.0");
622 MODULE_LICENSE("GPL v2");