aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2015-04-14 08:33:20 -0400
committerJens Wiklander <jens.wiklander@linaro.org>2017-03-10 08:51:52 -0500
commit4fb0a5eb364d239722e745c02aef0dbd4e0f1ad2 (patch)
tree42f9c838c6edf35b7d56c8dc28d50a650b50edcd
parent967c9cca2cc50569efc65945325c173cecba83bd (diff)
tee: add OP-TEE driver
Adds a OP-TEE driver which also can be compiled as a loadable module. * Targets ARM and ARM64 * Supports using reserved memory from OP-TEE as shared memory * Probes OP-TEE version using SMCs * Accepts requests on privileged and unprivileged device * Uses OPTEE message protocol version 2 to communicate with secure world Acked-by: Andreas Dannenberg <dannenberg@ti.com> Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey) Tested-by: Volodymyr Babchuk <vlad.babchuk@gmail.com> (RCAR H3) Tested-by: Scott Branden <scott.branden@broadcom.com> Reviewed-by: Javier González <javier@javigon.com> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/tee/Kconfig10
-rw-r--r--drivers/tee/Makefile1
-rw-r--r--drivers/tee/optee/Kconfig7
-rw-r--r--drivers/tee/optee/Makefile5
-rw-r--r--drivers/tee/optee/call.c444
-rw-r--r--drivers/tee/optee/core.c622
-rw-r--r--drivers/tee/optee/optee_msg.h418
-rw-r--r--drivers/tee/optee/optee_private.h183
-rw-r--r--drivers/tee/optee/optee_smc.h450
-rw-r--r--drivers/tee/optee/rpc.c396
-rw-r--r--drivers/tee/optee/supp.c273
12 files changed, 2814 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 017521958c86..ffcc4a841b64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9369,6 +9369,11 @@ F: arch/*/oprofile/
9369F: drivers/oprofile/ 9369F: drivers/oprofile/
9370F: include/linux/oprofile.h 9370F: include/linux/oprofile.h
9371 9371
9372OP-TEE DRIVER
9373M: Jens Wiklander <jens.wiklander@linaro.org>
9374S: Maintained
9375F: drivers/tee/optee/
9376
9372ORACLE CLUSTER FILESYSTEM 2 (OCFS2) 9377ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
9373M: Mark Fasheh <mfasheh@versity.com> 9378M: Mark Fasheh <mfasheh@versity.com>
9374M: Joel Becker <jlbec@evilplan.org> 9379M: Joel Becker <jlbec@evilplan.org>
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 50c244ead46d..2330a4eb4e8b 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -6,3 +6,13 @@ config TEE
6 help 6 help
7 This implements a generic interface towards a Trusted Execution 7 This implements a generic interface towards a Trusted Execution
8 Environment (TEE). 8 Environment (TEE).
9
10if TEE
11
12menu "TEE drivers"
13
14source "drivers/tee/optee/Kconfig"
15
16endmenu
17
18endif
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index ec64047a86e2..7a4e4a1ac39c 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_TEE) += tee.o
2tee-objs += tee_core.o 2tee-objs += tee_core.o
3tee-objs += tee_shm.o 3tee-objs += tee_shm.o
4tee-objs += tee_shm_pool.o 4tee-objs += tee_shm_pool.o
5obj-$(CONFIG_OPTEE) += optee/
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
new file mode 100644
index 000000000000..0126de898036
--- /dev/null
+++ b/drivers/tee/optee/Kconfig
@@ -0,0 +1,7 @@
1# OP-TEE Trusted Execution Environment Configuration
2config OPTEE
3 tristate "OP-TEE"
4 depends on HAVE_ARM_SMCCC
5 help
6 This implements the OP-TEE Trusted Execution Environment (TEE)
7 driver.
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
new file mode 100644
index 000000000000..92fe5789bcce
--- /dev/null
+++ b/drivers/tee/optee/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_OPTEE) += optee.o
2optee-objs += core.o
3optee-objs += call.o
4optee-objs += rpc.o
5optee-objs += supp.o
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
new file mode 100644
index 000000000000..f7b7b404c990
--- /dev/null
+++ b/drivers/tee/optee/call.c
@@ -0,0 +1,444 @@
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#include <linux/arm-smccc.h>
15#include <linux/device.h>
16#include <linux/err.h>
17#include <linux/errno.h>
18#include <linux/slab.h>
19#include <linux/tee_drv.h>
20#include <linux/types.h>
21#include <linux/uaccess.h>
22#include "optee_private.h"
23#include "optee_smc.h"
24
25struct optee_call_waiter {
26 struct list_head list_node;
27 struct completion c;
28};
29
30static void optee_cq_wait_init(struct optee_call_queue *cq,
31 struct optee_call_waiter *w)
32{
33 /*
34 * We're preparing to make a call to secure world. In case we can't
35 * allocate a thread in secure world we'll end up waiting in
36 * optee_cq_wait_for_completion().
37 *
38 * Normally if there's no contention in secure world the call will
39 * complete and we can cleanup directly with optee_cq_wait_final().
40 */
41 mutex_lock(&cq->mutex);
42
43 /*
44 * We add ourselves to the queue, but we don't wait. This
45 * guarantees that we don't lose a completion if secure world
46 * returns busy and another thread just exited and try to complete
47 * someone.
48 */
49 init_completion(&w->c);
50 list_add_tail(&w->list_node, &cq->waiters);
51
52 mutex_unlock(&cq->mutex);
53}
54
55static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
56 struct optee_call_waiter *w)
57{
58 wait_for_completion(&w->c);
59
60 mutex_lock(&cq->mutex);
61
62 /* Move to end of list to get out of the way for other waiters */
63 list_del(&w->list_node);
64 reinit_completion(&w->c);
65 list_add_tail(&w->list_node, &cq->waiters);
66
67 mutex_unlock(&cq->mutex);
68}
69
70static void optee_cq_complete_one(struct optee_call_queue *cq)
71{
72 struct optee_call_waiter *w;
73
74 list_for_each_entry(w, &cq->waiters, list_node) {
75 if (!completion_done(&w->c)) {
76 complete(&w->c);
77 break;
78 }
79 }
80}
81
82static void optee_cq_wait_final(struct optee_call_queue *cq,
83 struct optee_call_waiter *w)
84{
85 /*
86 * We're done with the call to secure world. The thread in secure
87 * world that was used for this call is now available for some
88 * other task to use.
89 */
90 mutex_lock(&cq->mutex);
91
92 /* Get out of the list */
93 list_del(&w->list_node);
94
95 /* Wake up one eventual waiting task */
96 optee_cq_complete_one(cq);
97
98 /*
99 * If we're completed we've got a completion from another task that
100 * was just done with its call to secure world. Since yet another
101 * thread now is available in secure world wake up another eventual
102 * waiting task.
103 */
104 if (completion_done(&w->c))
105 optee_cq_complete_one(cq);
106
107 mutex_unlock(&cq->mutex);
108}
109
110/* Requires the filpstate mutex to be held */
111static struct optee_session *find_session(struct optee_context_data *ctxdata,
112 u32 session_id)
113{
114 struct optee_session *sess;
115
116 list_for_each_entry(sess, &ctxdata->sess_list, list_node)
117 if (sess->session_id == session_id)
118 return sess;
119
120 return NULL;
121}
122
123/**
124 * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
125 * @ctx: calling context
126 * @parg: physical address of message to pass to secure world
127 *
128 * Does and SMC to OP-TEE in secure world and handles eventual resulting
129 * Remote Procedure Calls (RPC) from OP-TEE.
130 *
131 * Returns return code from secure world, 0 is OK
132 */
133u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
134{
135 struct optee *optee = tee_get_drvdata(ctx->teedev);
136 struct optee_call_waiter w;
137 struct optee_rpc_param param = { };
138 u32 ret;
139
140 param.a0 = OPTEE_SMC_CALL_WITH_ARG;
141 reg_pair_from_64(&param.a1, &param.a2, parg);
142 /* Initialize waiter */
143 optee_cq_wait_init(&optee->call_queue, &w);
144 while (true) {
145 struct arm_smccc_res res;
146
147 optee->invoke_fn(param.a0, param.a1, param.a2, param.a3,
148 param.a4, param.a5, param.a6, param.a7,
149 &res);
150
151 if (res.a0 == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
152 /*
153 * Out of threads in secure world, wait for a thread
154 * become available.
155 */
156 optee_cq_wait_for_completion(&optee->call_queue, &w);
157 } else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
158 param.a0 = res.a0;
159 param.a1 = res.a1;
160 param.a2 = res.a2;
161 param.a3 = res.a3;
162 optee_handle_rpc(ctx, &param);
163 } else {
164 ret = res.a0;
165 break;
166 }
167 }
168
169 /*
170 * We're done with our thread in secure world, if there's any
171 * thread waiters wake up one.
172 */
173 optee_cq_wait_final(&optee->call_queue, &w);
174
175 return ret;
176}
177
178static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
179 struct optee_msg_arg **msg_arg,
180 phys_addr_t *msg_parg)
181{
182 int rc;
183 struct tee_shm *shm;
184 struct optee_msg_arg *ma;
185
186 shm = tee_shm_alloc(ctx, OPTEE_MSG_GET_ARG_SIZE(num_params),
187 TEE_SHM_MAPPED);
188 if (IS_ERR(shm))
189 return shm;
190
191 ma = tee_shm_get_va(shm, 0);
192 if (IS_ERR(ma)) {
193 rc = PTR_ERR(ma);
194 goto out;
195 }
196
197 rc = tee_shm_get_pa(shm, 0, msg_parg);
198 if (rc)
199 goto out;
200
201 memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
202 ma->num_params = num_params;
203 *msg_arg = ma;
204out:
205 if (rc) {
206 tee_shm_free(shm);
207 return ERR_PTR(rc);
208 }
209
210 return shm;
211}
212
213int optee_open_session(struct tee_context *ctx,
214 struct tee_ioctl_open_session_arg *arg,
215 struct tee_param *param)
216{
217 struct optee_context_data *ctxdata = ctx->data;
218 int rc;
219 struct tee_shm *shm;
220 struct optee_msg_arg *msg_arg;
221 phys_addr_t msg_parg;
222 struct optee_session *sess = NULL;
223
224 /* +2 for the meta parameters added below */
225 shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
226 if (IS_ERR(shm))
227 return PTR_ERR(shm);
228
229 msg_arg->cmd = OPTEE_MSG_CMD_OPEN_SESSION;
230 msg_arg->cancel_id = arg->cancel_id;
231
232 /*
233 * Initialize and add the meta parameters needed when opening a
234 * session.
235 */
236 msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
237 OPTEE_MSG_ATTR_META;
238 msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
239 OPTEE_MSG_ATTR_META;
240 memcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid));
241 memcpy(&msg_arg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
242 msg_arg->params[1].u.value.c = arg->clnt_login;
243
244 rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
245 if (rc)
246 goto out;
247
248 sess = kzalloc(sizeof(*sess), GFP_KERNEL);
249 if (!sess) {
250 rc = -ENOMEM;
251 goto out;
252 }
253
254 if (optee_do_call_with_arg(ctx, msg_parg)) {
255 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
256 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
257 }
258
259 if (msg_arg->ret == TEEC_SUCCESS) {
260 /* A new session has been created, add it to the list. */
261 sess->session_id = msg_arg->session;
262 mutex_lock(&ctxdata->mutex);
263 list_add(&sess->list_node, &ctxdata->sess_list);
264 mutex_unlock(&ctxdata->mutex);
265 } else {
266 kfree(sess);
267 }
268
269 if (optee_from_msg_param(param, arg->num_params, msg_arg->params + 2)) {
270 arg->ret = TEEC_ERROR_COMMUNICATION;
271 arg->ret_origin = TEEC_ORIGIN_COMMS;
272 /* Close session again to avoid leakage */
273 optee_close_session(ctx, msg_arg->session);
274 } else {
275 arg->session = msg_arg->session;
276 arg->ret = msg_arg->ret;
277 arg->ret_origin = msg_arg->ret_origin;
278 }
279out:
280 tee_shm_free(shm);
281
282 return rc;
283}
284
285int optee_close_session(struct tee_context *ctx, u32 session)
286{
287 struct optee_context_data *ctxdata = ctx->data;
288 struct tee_shm *shm;
289 struct optee_msg_arg *msg_arg;
290 phys_addr_t msg_parg;
291 struct optee_session *sess;
292
293 /* Check that the session is valid and remove it from the list */
294 mutex_lock(&ctxdata->mutex);
295 sess = find_session(ctxdata, session);
296 if (sess)
297 list_del(&sess->list_node);
298 mutex_unlock(&ctxdata->mutex);
299 if (!sess)
300 return -EINVAL;
301 kfree(sess);
302
303 shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
304 if (IS_ERR(shm))
305 return PTR_ERR(shm);
306
307 msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
308 msg_arg->session = session;
309 optee_do_call_with_arg(ctx, msg_parg);
310
311 tee_shm_free(shm);
312 return 0;
313}
314
315int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
316 struct tee_param *param)
317{
318 struct optee_context_data *ctxdata = ctx->data;
319 struct tee_shm *shm;
320 struct optee_msg_arg *msg_arg;
321 phys_addr_t msg_parg;
322 struct optee_session *sess;
323 int rc;
324
325 /* Check that the session is valid */
326 mutex_lock(&ctxdata->mutex);
327 sess = find_session(ctxdata, arg->session);
328 mutex_unlock(&ctxdata->mutex);
329 if (!sess)
330 return -EINVAL;
331
332 shm = get_msg_arg(ctx, arg->num_params, &msg_arg, &msg_parg);
333 if (IS_ERR(shm))
334 return PTR_ERR(shm);
335 msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
336 msg_arg->func = arg->func;
337 msg_arg->session = arg->session;
338 msg_arg->cancel_id = arg->cancel_id;
339
340 rc = optee_to_msg_param(msg_arg->params, arg->num_params, param);
341 if (rc)
342 goto out;
343
344 if (optee_do_call_with_arg(ctx, msg_parg)) {
345 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
346 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
347 }
348
349 if (optee_from_msg_param(param, arg->num_params, msg_arg->params)) {
350 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
351 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
352 }
353
354 arg->ret = msg_arg->ret;
355 arg->ret_origin = msg_arg->ret_origin;
356out:
357 tee_shm_free(shm);
358 return rc;
359}
360
361int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
362{
363 struct optee_context_data *ctxdata = ctx->data;
364 struct tee_shm *shm;
365 struct optee_msg_arg *msg_arg;
366 phys_addr_t msg_parg;
367 struct optee_session *sess;
368
369 /* Check that the session is valid */
370 mutex_lock(&ctxdata->mutex);
371 sess = find_session(ctxdata, session);
372 mutex_unlock(&ctxdata->mutex);
373 if (!sess)
374 return -EINVAL;
375
376 shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
377 if (IS_ERR(shm))
378 return PTR_ERR(shm);
379
380 msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
381 msg_arg->session = session;
382 msg_arg->cancel_id = cancel_id;
383 optee_do_call_with_arg(ctx, msg_parg);
384
385 tee_shm_free(shm);
386 return 0;
387}
388
389/**
390 * optee_enable_shm_cache() - Enables caching of some shared memory allocation
391 * in OP-TEE
392 * @optee: main service struct
393 */
394void optee_enable_shm_cache(struct optee *optee)
395{
396 struct optee_call_waiter w;
397
398 /* We need to retry until secure world isn't busy. */
399 optee_cq_wait_init(&optee->call_queue, &w);
400 while (true) {
401 struct arm_smccc_res res;
402
403 optee->invoke_fn(OPTEE_SMC_ENABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
404 0, &res);
405 if (res.a0 == OPTEE_SMC_RETURN_OK)
406 break;
407 optee_cq_wait_for_completion(&optee->call_queue, &w);
408 }
409 optee_cq_wait_final(&optee->call_queue, &w);
410}
411
412/**
413 * optee_disable_shm_cache() - Disables caching of some shared memory allocation
414 * in OP-TEE
415 * @optee: main service struct
416 */
417void optee_disable_shm_cache(struct optee *optee)
418{
419 struct optee_call_waiter w;
420
421 /* We need to retry until secure world isn't busy. */
422 optee_cq_wait_init(&optee->call_queue, &w);
423 while (true) {
424 union {
425 struct arm_smccc_res smccc;
426 struct optee_smc_disable_shm_cache_result result;
427 } res;
428
429 optee->invoke_fn(OPTEE_SMC_DISABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
430 0, &res.smccc);
431 if (res.result.status == OPTEE_SMC_RETURN_ENOTAVAIL)
432 break; /* All shm's freed */
433 if (res.result.status == OPTEE_SMC_RETURN_OK) {
434 struct tee_shm *shm;
435
436 shm = reg_pair_to_ptr(res.result.shm_upper32,
437 res.result.shm_lower32);
438 tee_shm_free(shm);
439 } else {
440 optee_cq_wait_for_completion(&optee->call_queue, &w);
441 }
442 }
443 optee_cq_wait_final(&optee->call_queue, &w);
444}
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
new file mode 100644
index 000000000000..58169e519422
--- /dev/null
+++ b/drivers/tee/optee/core.c
@@ -0,0 +1,622 @@
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 */
44int 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
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 +
93 p->u.memref.size - 1;
94
95 rc = tee_shm_get_pa(shm, o, NULL);
96 if (rc)
97 return rc;
98 }
99 break;
100 default:
101 return -EINVAL;
102 }
103 }
104 return 0;
105}
106
107/**
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
113 */
114int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
115 const struct tee_param *params)
116{
117 int rc;
118 size_t n;
119 phys_addr_t pa;
120
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;
124
125 switch (p->attr) {
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));
129 break;
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;
138 break;
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 +
143 p->attr -
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;
149 break;
150 }
151 rc = tee_shm_get_pa(p->u.memref.shm,
152 p->u.memref.shm_offs, &pa);
153 if (rc)
154 return rc;
155 mp->u.tmem.buf_ptr = pa;
156 mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
157 OPTEE_MSG_ATTR_CACHE_SHIFT;
158 break;
159 default:
160 return -EINVAL;
161 }
162 }
163 return 0;
164}
165
166static void optee_get_version(struct tee_device *teedev,
167 struct tee_ioctl_version_data *vers)
168{
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,
173 };
174 *vers = v;
175}
176
177static int optee_open(struct tee_context *ctx)
178{
179 struct optee_context_data *ctxdata;
180 struct tee_device *teedev = ctx->teedev;
181 struct optee *optee = tee_get_drvdata(teedev);
182
183 ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
184 if (!ctxdata)
185 return -ENOMEM;
186
187 if (teedev == optee->supp_teedev) {
188 bool busy = true;
189
190 mutex_lock(&optee->supp.ctx_mutex);
191 if (!optee->supp.ctx) {
192 busy = false;
193 optee->supp.ctx = ctx;
194 }
195 mutex_unlock(&optee->supp.ctx_mutex);
196 if (busy) {
197 kfree(ctxdata);
198 return -EBUSY;
199 }
200 }
201
202 mutex_init(&ctxdata->mutex);
203 INIT_LIST_HEAD(&ctxdata->sess_list);
204
205 ctx->data = ctxdata;
206 return 0;
207}
208
209static void optee_release(struct tee_context *ctx)
210{
211 struct optee_context_data *ctxdata = ctx->data;
212 struct tee_device *teedev = ctx->teedev;
213 struct optee *optee = tee_get_drvdata(teedev);
214 struct tee_shm *shm;
215 struct optee_msg_arg *arg = NULL;
216 phys_addr_t parg;
217 struct optee_session *sess;
218 struct optee_session *sess_tmp;
219
220 if (!ctxdata)
221 return;
222
223 shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED);
224 if (!IS_ERR(shm)) {
225 arg = tee_shm_get_va(shm, 0);
226 /*
227 * If va2pa fails for some reason, we can't call
228 * optee_close_session(), only free the memory. Secure OS
229 * will leak sessions and finally refuse more sessions, but
230 * we will at least let normal world reclaim its memory.
231 */
232 if (!IS_ERR(arg))
233 tee_shm_va2pa(shm, arg, &parg);
234 }
235
236 list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
237 list_node) {
238 list_del(&sess->list_node);
239 if (!IS_ERR_OR_NULL(arg)) {
240 memset(arg, 0, sizeof(*arg));
241 arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
242 arg->session = sess->session_id;
243 optee_do_call_with_arg(ctx, parg);
244 }
245 kfree(sess);
246 }
247 kfree(ctxdata);
248
249 if (!IS_ERR(shm))
250 tee_shm_free(shm);
251
252 ctx->data = NULL;
253
254 if (teedev == optee->supp_teedev) {
255 mutex_lock(&optee->supp.ctx_mutex);
256 optee->supp.ctx = NULL;
257 mutex_unlock(&optee->supp.ctx_mutex);
258 }
259}
260
261static struct tee_driver_ops optee_ops = {
262 .get_version = optee_get_version,
263 .open = optee_open,
264 .release = optee_release,
265 .open_session = optee_open_session,
266 .close_session = optee_close_session,
267 .invoke_func = optee_invoke_func,
268 .cancel_req = optee_cancel_req,
269};
270
271static struct tee_desc optee_desc = {
272 .name = DRIVER_NAME "-clnt",
273 .ops = &optee_ops,
274 .owner = THIS_MODULE,
275};
276
277static struct tee_driver_ops optee_supp_ops = {
278 .get_version = optee_get_version,
279 .open = optee_open,
280 .release = optee_release,
281 .supp_recv = optee_supp_recv,
282 .supp_send = optee_supp_send,
283};
284
285static struct tee_desc optee_supp_desc = {
286 .name = DRIVER_NAME "-supp",
287 .ops = &optee_supp_ops,
288 .owner = THIS_MODULE,
289 .flags = TEE_DESC_PRIVILEGED,
290};
291
292static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
293{
294 struct arm_smccc_res res;
295
296 invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
297
298 if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
299 res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
300 return true;
301 return false;
302}
303
304static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
305{
306 union {
307 struct arm_smccc_res smccc;
308 struct optee_smc_calls_revision_result result;
309 } res;
310
311 invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
312
313 if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
314 (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
315 return true;
316 return false;
317}
318
319static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
320 u32 *sec_caps)
321{
322 union {
323 struct arm_smccc_res smccc;
324 struct optee_smc_exchange_capabilities_result result;
325 } res;
326 u32 a1 = 0;
327
328 /*
329 * TODO This isn't enough to tell if it's UP system (from kernel
330 * point of view) or not, is_smp() returns the the information
331 * needed, but can't be called directly from here.
332 */
333 if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
334 a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
335
336 invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
337 &res.smccc);
338
339 if (res.result.status != OPTEE_SMC_RETURN_OK)
340 return false;
341
342 *sec_caps = res.result.capabilities;
343 return true;
344}
345
346static struct tee_shm_pool *
347optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
348{
349 union {
350 struct arm_smccc_res smccc;
351 struct optee_smc_get_shm_config_result result;
352 } res;
353 struct tee_shm_pool *pool;
354 unsigned long vaddr;
355 phys_addr_t paddr;
356 size_t size;
357 phys_addr_t begin;
358 phys_addr_t end;
359 void *va;
360 struct tee_shm_pool_mem_info priv_info;
361 struct tee_shm_pool_mem_info dmabuf_info;
362
363 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
364 if (res.result.status != OPTEE_SMC_RETURN_OK) {
365 pr_info("shm service not available\n");
366 return ERR_PTR(-ENOENT);
367 }
368
369 if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
370 pr_err("only normal cached shared memory supported\n");
371 return ERR_PTR(-EINVAL);
372 }
373
374 begin = roundup(res.result.start, PAGE_SIZE);
375 end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
376 paddr = begin;
377 size = end - begin;
378
379 if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
380 pr_err("too small shared memory area\n");
381 return ERR_PTR(-EINVAL);
382 }
383
384 va = memremap(paddr, size, MEMREMAP_WB);
385 if (!va) {
386 pr_err("shared memory ioremap failed\n");
387 return ERR_PTR(-EINVAL);
388 }
389 vaddr = (unsigned long)va;
390
391 priv_info.vaddr = vaddr;
392 priv_info.paddr = paddr;
393 priv_info.size = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
394 dmabuf_info.vaddr = vaddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
395 dmabuf_info.paddr = paddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
396 dmabuf_info.size = size - OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
397
398 pool = tee_shm_pool_alloc_res_mem(&priv_info, &dmabuf_info);
399 if (IS_ERR(pool)) {
400 memunmap(va);
401 goto out;
402 }
403
404 *memremaped_shm = va;
405out:
406 return pool;
407}
408
409/* Simple wrapper functions to be able to use a function pointer */
410static void optee_smccc_smc(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_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
417}
418
419static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
420 unsigned long a2, unsigned long a3,
421 unsigned long a4, unsigned long a5,
422 unsigned long a6, unsigned long a7,
423 struct arm_smccc_res *res)
424{
425 arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
426}
427
428static optee_invoke_fn *get_invoke_func(struct device_node *np)
429{
430 const char *method;
431
432 pr_info("probing for conduit method from DT.\n");
433
434 if (of_property_read_string(np, "method", &method)) {
435 pr_warn("missing \"method\" property\n");
436 return ERR_PTR(-ENXIO);
437 }
438
439 if (!strcmp("hvc", method))
440 return optee_smccc_hvc;
441 else if (!strcmp("smc", method))
442 return optee_smccc_smc;
443
444 pr_warn("invalid \"method\" property: %s\n", method);
445 return ERR_PTR(-EINVAL);
446}
447
448static struct optee *optee_probe(struct device_node *np)
449{
450 optee_invoke_fn *invoke_fn;
451 struct tee_shm_pool *pool;
452 struct optee *optee = NULL;
453 void *memremaped_shm = NULL;
454 struct tee_device *teedev;
455 u32 sec_caps;
456 int rc;
457
458 invoke_fn = get_invoke_func(np);
459 if (IS_ERR(invoke_fn))
460 return (void *)invoke_fn;
461
462 if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
463 pr_warn("api uid mismatch\n");
464 return ERR_PTR(-EINVAL);
465 }
466
467 if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
468 pr_warn("api revision mismatch\n");
469 return ERR_PTR(-EINVAL);
470 }
471
472 if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
473 pr_warn("capabilities mismatch\n");
474 return ERR_PTR(-EINVAL);
475 }
476
477 /*
478 * We have no other option for shared memory, if secure world
479 * doesn't have any reserved memory we can use we can't continue.
480 */
481 if (!(sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
482 return ERR_PTR(-EINVAL);
483
484 pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
485 if (IS_ERR(pool))
486 return (void *)pool;
487
488 optee = kzalloc(sizeof(*optee), GFP_KERNEL);
489 if (!optee) {
490 rc = -ENOMEM;
491 goto err;
492 }
493
494 optee->invoke_fn = invoke_fn;
495
496 teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
497 if (IS_ERR(teedev)) {
498 rc = PTR_ERR(teedev);
499 goto err;
500 }
501 optee->teedev = teedev;
502
503 teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
504 if (IS_ERR(teedev)) {
505 rc = PTR_ERR(teedev);
506 goto err;
507 }
508 optee->supp_teedev = teedev;
509
510 rc = tee_device_register(optee->teedev);
511 if (rc)
512 goto err;
513
514 rc = tee_device_register(optee->supp_teedev);
515 if (rc)
516 goto err;
517
518 mutex_init(&optee->call_queue.mutex);
519 INIT_LIST_HEAD(&optee->call_queue.waiters);
520 optee_wait_queue_init(&optee->wait_queue);
521 optee_supp_init(&optee->supp);
522 optee->memremaped_shm = memremaped_shm;
523 optee->pool = pool;
524
525 optee_enable_shm_cache(optee);
526
527 pr_info("initialized driver\n");
528 return optee;
529err:
530 if (optee) {
531 /*
532 * tee_device_unregister() is safe to call even if the
533 * devices hasn't been registered with
534 * tee_device_register() yet.
535 */
536 tee_device_unregister(optee->supp_teedev);
537 tee_device_unregister(optee->teedev);
538 kfree(optee);
539 }
540 if (pool)
541 tee_shm_pool_free(pool);
542 if (memremaped_shm)
543 memunmap(memremaped_shm);
544 return ERR_PTR(rc);
545}
546
547static void optee_remove(struct optee *optee)
548{
549 /*
550 * Ask OP-TEE to free all cached shared memory objects to decrease
551 * reference counters and also avoid wild pointers in secure world
552 * into the old shared memory range.
553 */
554 optee_disable_shm_cache(optee);
555
556 /*
557 * The two devices has to be unregistered before we can free the
558 * other resources.
559 */
560 tee_device_unregister(optee->supp_teedev);
561 tee_device_unregister(optee->teedev);
562
563 tee_shm_pool_free(optee->pool);
564 if (optee->memremaped_shm)
565 memunmap(optee->memremaped_shm);
566 optee_wait_queue_exit(&optee->wait_queue);
567 optee_supp_uninit(&optee->supp);
568 mutex_destroy(&optee->call_queue.mutex);
569
570 kfree(optee);
571}
572
573static const struct of_device_id optee_match[] = {
574 { .compatible = "linaro,optee-tz" },
575 {},
576};
577
578static struct optee *optee_svc;
579
580static int __init optee_driver_init(void)
581{
582 struct device_node *fw_np;
583 struct device_node *np;
584 struct optee *optee;
585
586 /* Node is supposed to be below /firmware */
587 fw_np = of_find_node_by_name(NULL, "firmware");
588 if (!fw_np)
589 return -ENODEV;
590
591 np = of_find_matching_node(fw_np, optee_match);
592 of_node_put(fw_np);
593 if (!np)
594 return -ENODEV;
595
596 optee = optee_probe(np);
597 of_node_put(np);
598
599 if (IS_ERR(optee))
600 return PTR_ERR(optee);
601
602 optee_svc = optee;
603
604 return 0;
605}
606module_init(optee_driver_init);
607
608static void __exit optee_driver_exit(void)
609{
610 struct optee *optee = optee_svc;
611
612 optee_svc = NULL;
613 if (optee)
614 optee_remove(optee);
615}
616module_exit(optee_driver_exit);
617
618MODULE_AUTHOR("Linaro");
619MODULE_DESCRIPTION("OP-TEE driver");
620MODULE_SUPPORTED_DEVICE("");
621MODULE_VERSION("1.0");
622MODULE_LICENSE("GPL v2");
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
new file mode 100644
index 000000000000..dd7a06ee0462
--- /dev/null
+++ b/drivers/tee/optee/optee_msg.h
@@ -0,0 +1,418 @@
1/*
2 * Copyright (c) 2015-2016, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27#ifndef _OPTEE_MSG_H
28#define _OPTEE_MSG_H
29
30#include <linux/bitops.h>
31#include <linux/types.h>
32
33/*
34 * This file defines the OP-TEE message protocol used to communicate
35 * with an instance of OP-TEE running in secure world.
36 *
37 * This file is divided into three sections.
38 * 1. Formatting of messages.
39 * 2. Requests from normal world
40 * 3. Requests from secure world, Remote Procedure Call (RPC), handled by
41 * tee-supplicant.
42 */
43
44/*****************************************************************************
45 * Part 1 - formatting of messages
46 *****************************************************************************/
47
48#define OPTEE_MSG_ATTR_TYPE_NONE 0x0
49#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT 0x1
50#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT 0x2
51#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT 0x3
52#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT 0x5
53#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT 0x6
54#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT 0x7
55#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT 0x9
56#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT 0xa
57#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb
58
59#define OPTEE_MSG_ATTR_TYPE_MASK GENMASK(7, 0)
60
61/*
62 * Meta parameter to be absorbed by the Secure OS and not passed
63 * to the Trusted Application.
64 *
65 * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION.
66 */
67#define OPTEE_MSG_ATTR_META BIT(8)
68
69/*
70 * The temporary shared memory object is not physically contigous and this
71 * temp memref is followed by another fragment until the last temp memref
72 * that doesn't have this bit set.
73 */
74#define OPTEE_MSG_ATTR_FRAGMENT BIT(9)
75
76/*
77 * Memory attributes for caching passed with temp memrefs. The actual value
78 * used is defined outside the message protocol with the exception of
79 * OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already
80 * defined for the memory range should be used. If optee_smc.h is used as
81 * bearer of this protocol OPTEE_SMC_SHM_* is used for values.
82 */
83#define OPTEE_MSG_ATTR_CACHE_SHIFT 16
84#define OPTEE_MSG_ATTR_CACHE_MASK GENMASK(2, 0)
85#define OPTEE_MSG_ATTR_CACHE_PREDEFINED 0
86
87/*
88 * Same values as TEE_LOGIN_* from TEE Internal API
89 */
90#define OPTEE_MSG_LOGIN_PUBLIC 0x00000000
91#define OPTEE_MSG_LOGIN_USER 0x00000001
92#define OPTEE_MSG_LOGIN_GROUP 0x00000002
93#define OPTEE_MSG_LOGIN_APPLICATION 0x00000004
94#define OPTEE_MSG_LOGIN_APPLICATION_USER 0x00000005
95#define OPTEE_MSG_LOGIN_APPLICATION_GROUP 0x00000006
96
97/**
98 * struct optee_msg_param_tmem - temporary memory reference parameter
99 * @buf_ptr: Address of the buffer
100 * @size: Size of the buffer
101 * @shm_ref: Temporary shared memory reference, pointer to a struct tee_shm
102 *
103 * Secure and normal world communicates pointers as physical address
104 * instead of the virtual address. This is because secure and normal world
105 * have completely independent memory mapping. Normal world can even have a
106 * hypervisor which need to translate the guest physical address (AKA IPA
107 * in ARM documentation) to a real physical address before passing the
108 * structure to secure world.
109 */
110struct optee_msg_param_tmem {
111 u64 buf_ptr;
112 u64 size;
113 u64 shm_ref;
114};
115
116/**
117 * struct optee_msg_param_rmem - registered memory reference parameter
118 * @offs: Offset into shared memory reference
119 * @size: Size of the buffer
120 * @shm_ref: Shared memory reference, pointer to a struct tee_shm
121 */
122struct optee_msg_param_rmem {
123 u64 offs;
124 u64 size;
125 u64 shm_ref;
126};
127
128/**
129 * struct optee_msg_param_value - opaque value parameter
130 *
131 * Value parameters are passed unchecked between normal and secure world.
132 */
133struct optee_msg_param_value {
134 u64 a;
135 u64 b;
136 u64 c;
137};
138
139/**
140 * struct optee_msg_param - parameter used together with struct optee_msg_arg
141 * @attr: attributes
142 * @tmem: parameter by temporary memory reference
143 * @rmem: parameter by registered memory reference
144 * @value: parameter by opaque value
145 *
146 * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
147 * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value,
148 * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates tmem and
149 * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates rmem.
150 * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
151 */
152struct optee_msg_param {
153 u64 attr;
154 union {
155 struct optee_msg_param_tmem tmem;
156 struct optee_msg_param_rmem rmem;
157 struct optee_msg_param_value value;
158 } u;
159};
160
161/**
162 * struct optee_msg_arg - call argument
163 * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_*
164 * @func: Trusted Application function, specific to the Trusted Application,
165 * used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND
166 * @session: In parameter for all OPTEE_MSG_CMD_* except
167 * OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead
168 * @cancel_id: Cancellation id, a unique value to identify this request
169 * @ret: return value
170 * @ret_origin: origin of the return value
171 * @num_params: number of parameters supplied to the OS Command
172 * @params: the parameters supplied to the OS Command
173 *
174 * All normal calls to Trusted OS uses this struct. If cmd requires further
175 * information than what these field holds it can be passed as a parameter
176 * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding
177 * attrs field). All parameters tagged as meta has to come first.
178 *
179 * Temp memref parameters can be fragmented if supported by the Trusted OS
180 * (when optee_smc.h is bearer of this protocol this is indicated with
181 * OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM). If a logical memref parameter is
182 * fragmented then has all but the last fragment the
183 * OPTEE_MSG_ATTR_FRAGMENT bit set in attrs. Even if a memref is fragmented
184 * it will still be presented as a single logical memref to the Trusted
185 * Application.
186 */
187struct optee_msg_arg {
188 u32 cmd;
189 u32 func;
190 u32 session;
191 u32 cancel_id;
192 u32 pad;
193 u32 ret;
194 u32 ret_origin;
195 u32 num_params;
196
197 /* num_params tells the actual number of element in params */
198 struct optee_msg_param params[0];
199};
200
201/**
202 * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg
203 *
204 * @num_params: Number of parameters embedded in the struct optee_msg_arg
205 *
206 * Returns the size of the struct optee_msg_arg together with the number
207 * of embedded parameters.
208 */
209#define OPTEE_MSG_GET_ARG_SIZE(num_params) \
210 (sizeof(struct optee_msg_arg) + \
211 sizeof(struct optee_msg_param) * (num_params))
212
213/*****************************************************************************
214 * Part 2 - requests from normal world
215 *****************************************************************************/
216
217/*
218 * Return the following UID if using API specified in this file without
219 * further extensions:
220 * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b.
221 * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1,
222 * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3.
223 */
224#define OPTEE_MSG_UID_0 0x384fb3e0
225#define OPTEE_MSG_UID_1 0xe7f811e3
226#define OPTEE_MSG_UID_2 0xaf630002
227#define OPTEE_MSG_UID_3 0xa5d5c51b
228#define OPTEE_MSG_FUNCID_CALLS_UID 0xFF01
229
230/*
231 * Returns 2.0 if using API specified in this file without further
232 * extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR
233 * and OPTEE_MSG_REVISION_MINOR
234 */
235#define OPTEE_MSG_REVISION_MAJOR 2
236#define OPTEE_MSG_REVISION_MINOR 0
237#define OPTEE_MSG_FUNCID_CALLS_REVISION 0xFF03
238
239/*
240 * Get UUID of Trusted OS.
241 *
242 * Used by non-secure world to figure out which Trusted OS is installed.
243 * Note that returned UUID is the UUID of the Trusted OS, not of the API.
244 *
245 * Returns UUID in 4 32-bit words in the same way as
246 * OPTEE_MSG_FUNCID_CALLS_UID described above.
247 */
248#define OPTEE_MSG_OS_OPTEE_UUID_0 0x486178e0
249#define OPTEE_MSG_OS_OPTEE_UUID_1 0xe7f811e3
250#define OPTEE_MSG_OS_OPTEE_UUID_2 0xbc5e0002
251#define OPTEE_MSG_OS_OPTEE_UUID_3 0xa5d5c51b
252#define OPTEE_MSG_FUNCID_GET_OS_UUID 0x0000
253
254/*
255 * Get revision of Trusted OS.
256 *
257 * Used by non-secure world to figure out which version of the Trusted OS
258 * is installed. Note that the returned revision is the revision of the
259 * Trusted OS, not of the API.
260 *
261 * Returns revision in 2 32-bit words in the same way as
262 * OPTEE_MSG_CALLS_REVISION described above.
263 */
264#define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001
265
266/*
267 * Do a secure call with struct optee_msg_arg as argument
268 * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
269 *
270 * OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application.
271 * The first two parameters are tagged as meta, holding two value
272 * parameters to pass the following information:
273 * param[0].u.value.a-b uuid of Trusted Application
274 * param[1].u.value.a-b uuid of Client
275 * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_*
276 *
277 * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened
278 * session to a Trusted Application. struct optee_msg_arg::func is Trusted
279 * Application function, specific to the Trusted Application.
280 *
281 * OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to
282 * Trusted Application.
283 *
284 * OPTEE_MSG_CMD_CANCEL cancels a currently invoked command.
285 *
286 * OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The
287 * information is passed as:
288 * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_TMEM_INPUT
289 * [| OPTEE_MSG_ATTR_FRAGMENT]
290 * [in] param[0].u.tmem.buf_ptr physical address (of first fragment)
291 * [in] param[0].u.tmem.size size (of first fragment)
292 * [in] param[0].u.tmem.shm_ref holds shared memory reference
293 * ...
294 * The shared memory can optionally be fragmented, temp memrefs can follow
295 * each other with all but the last with the OPTEE_MSG_ATTR_FRAGMENT bit set.
296 *
297 * OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared
298 * memory reference. The information is passed as:
299 * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
300 * [in] param[0].u.rmem.shm_ref holds shared memory reference
301 * [in] param[0].u.rmem.offs 0
302 * [in] param[0].u.rmem.size 0
303 */
304#define OPTEE_MSG_CMD_OPEN_SESSION 0
305#define OPTEE_MSG_CMD_INVOKE_COMMAND 1
306#define OPTEE_MSG_CMD_CLOSE_SESSION 2
307#define OPTEE_MSG_CMD_CANCEL 3
308#define OPTEE_MSG_CMD_REGISTER_SHM 4
309#define OPTEE_MSG_CMD_UNREGISTER_SHM 5
310#define OPTEE_MSG_FUNCID_CALL_WITH_ARG 0x0004
311
312/*****************************************************************************
313 * Part 3 - Requests from secure world, RPC
314 *****************************************************************************/
315
316/*
317 * All RPC is done with a struct optee_msg_arg as bearer of information,
318 * struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below
319 *
320 * RPC communication with tee-supplicant is reversed compared to normal
321 * client communication desribed above. The supplicant receives requests
322 * and sends responses.
323 */
324
325/*
326 * Load a TA into memory, defined in tee-supplicant
327 */
328#define OPTEE_MSG_RPC_CMD_LOAD_TA 0
329
330/*
331 * Reserved
332 */
333#define OPTEE_MSG_RPC_CMD_RPMB 1
334
335/*
336 * File system access, defined in tee-supplicant
337 */
338#define OPTEE_MSG_RPC_CMD_FS 2
339
340/*
341 * Get time
342 *
343 * Returns number of seconds and nano seconds since the Epoch,
344 * 1970-01-01 00:00:00 +0000 (UTC).
345 *
346 * [out] param[0].u.value.a Number of seconds
347 * [out] param[0].u.value.b Number of nano seconds.
348 */
349#define OPTEE_MSG_RPC_CMD_GET_TIME 3
350
351/*
352 * Wait queue primitive, helper for secure world to implement a wait queue.
353 *
354 * If secure world need to wait for a secure world mutex it issues a sleep
355 * request instead of spinning in secure world. Conversely is a wakeup
356 * request issued when a secure world mutex with a thread waiting thread is
357 * unlocked.
358 *
359 * Waiting on a key
360 * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP
361 * [in] param[0].u.value.b wait key
362 *
363 * Waking up a key
364 * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP
365 * [in] param[0].u.value.b wakeup key
366 */
367#define OPTEE_MSG_RPC_CMD_WAIT_QUEUE 4
368#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP 0
369#define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP 1
370
371/*
372 * Suspend execution
373 *
374 * [in] param[0].value .a number of milliseconds to suspend
375 */
376#define OPTEE_MSG_RPC_CMD_SUSPEND 5
377
378/*
379 * Allocate a piece of shared memory
380 *
381 * Shared memory can optionally be fragmented, to support that additional
382 * spare param entries are allocated to make room for eventual fragments.
383 * The spare param entries has .attr = OPTEE_MSG_ATTR_TYPE_NONE when
384 * unused. All returned temp memrefs except the last should have the
385 * OPTEE_MSG_ATTR_FRAGMENT bit set in the attr field.
386 *
387 * [in] param[0].u.value.a type of memory one of
388 * OPTEE_MSG_RPC_SHM_TYPE_* below
389 * [in] param[0].u.value.b requested size
390 * [in] param[0].u.value.c required alignment
391 *
392 * [out] param[0].u.tmem.buf_ptr physical address (of first fragment)
393 * [out] param[0].u.tmem.size size (of first fragment)
394 * [out] param[0].u.tmem.shm_ref shared memory reference
395 * ...
396 * [out] param[n].u.tmem.buf_ptr physical address
397 * [out] param[n].u.tmem.size size
398 * [out] param[n].u.tmem.shm_ref shared memory reference (same value
399 * as in param[n-1].u.tmem.shm_ref)
400 */
401#define OPTEE_MSG_RPC_CMD_SHM_ALLOC 6
402/* Memory that can be shared with a non-secure user space application */
403#define OPTEE_MSG_RPC_SHM_TYPE_APPL 0
404/* Memory only shared with non-secure kernel */
405#define OPTEE_MSG_RPC_SHM_TYPE_KERNEL 1
406
407/*
408 * Free shared memory previously allocated with OPTEE_MSG_RPC_CMD_SHM_ALLOC
409 *
410 * [in] param[0].u.value.a type of memory one of
411 * OPTEE_MSG_RPC_SHM_TYPE_* above
412 * [in] param[0].u.value.b value of shared memory reference
413 * returned in param[0].u.tmem.shm_ref
414 * above
415 */
416#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
417
418#endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
new file mode 100644
index 000000000000..c374cd594314
--- /dev/null
+++ b/drivers/tee/optee/optee_private.h
@@ -0,0 +1,183 @@
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#ifndef OPTEE_PRIVATE_H
16#define OPTEE_PRIVATE_H
17
18#include <linux/arm-smccc.h>
19#include <linux/semaphore.h>
20#include <linux/tee_drv.h>
21#include <linux/types.h>
22#include "optee_msg.h"
23
24#define OPTEE_MAX_ARG_SIZE 1024
25
26/* Some Global Platform error codes used in this driver */
27#define TEEC_SUCCESS 0x00000000
28#define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006
29#define TEEC_ERROR_COMMUNICATION 0xFFFF000E
30#define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C
31
32#define TEEC_ORIGIN_COMMS 0x00000002
33
34typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
35 unsigned long, unsigned long, unsigned long,
36 unsigned long, unsigned long,
37 struct arm_smccc_res *);
38
39struct optee_call_queue {
40 /* Serializes access to this struct */
41 struct mutex mutex;
42 struct list_head waiters;
43};
44
45struct optee_wait_queue {
46 /* Serializes access to this struct */
47 struct mutex mu;
48 struct list_head db;
49};
50
51/**
52 * struct optee_supp - supplicant synchronization struct
53 * @ctx the context of current connected supplicant.
54 * if !NULL the supplicant device is available for use,
55 * else busy
56 * @ctx_mutex: held while accessing @ctx
57 * @func: supplicant function id to call
58 * @ret: call return value
59 * @num_params: number of elements in @param
60 * @param: parameters for @func
61 * @req_posted: if true, a request has been posted to the supplicant
62 * @supp_next_send: if true, next step is for supplicant to send response
63 * @thrd_mutex: held by the thread doing a request to supplicant
64 * @supp_mutex: held by supplicant while operating on this struct
65 * @data_to_supp: supplicant is waiting on this for next request
66 * @data_from_supp: requesting thread is waiting on this to get the result
67 */
68struct optee_supp {
69 struct tee_context *ctx;
70 /* Serializes access of ctx */
71 struct mutex ctx_mutex;
72
73 u32 func;
74 u32 ret;
75 size_t num_params;
76 struct tee_param *param;
77
78 bool req_posted;
79 bool supp_next_send;
80 /* Serializes access to this struct for requesting thread */
81 struct mutex thrd_mutex;
82 /* Serializes access to this struct for supplicant threads */
83 struct mutex supp_mutex;
84 struct completion data_to_supp;
85 struct completion data_from_supp;
86};
87
88/**
89 * struct optee - main service struct
90 * @supp_teedev: supplicant device
91 * @teedev: client device
92 * @invoke_fn: function to issue smc or hvc
93 * @call_queue: queue of threads waiting to call @invoke_fn
94 * @wait_queue: queue of threads from secure world waiting for a
95 * secure world sync object
96 * @supp: supplicant synchronization struct for RPC to supplicant
97 * @pool: shared memory pool
98 * @memremaped_shm virtual address of memory in shared memory pool
99 */
100struct optee {
101 struct tee_device *supp_teedev;
102 struct tee_device *teedev;
103 optee_invoke_fn *invoke_fn;
104 struct optee_call_queue call_queue;
105 struct optee_wait_queue wait_queue;
106 struct optee_supp supp;
107 struct tee_shm_pool *pool;
108 void *memremaped_shm;
109};
110
111struct optee_session {
112 struct list_head list_node;
113 u32 session_id;
114};
115
116struct optee_context_data {
117 /* Serializes access to this struct */
118 struct mutex mutex;
119 struct list_head sess_list;
120};
121
122struct optee_rpc_param {
123 u32 a0;
124 u32 a1;
125 u32 a2;
126 u32 a3;
127 u32 a4;
128 u32 a5;
129 u32 a6;
130 u32 a7;
131};
132
133void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param);
134
135void optee_wait_queue_init(struct optee_wait_queue *wq);
136void optee_wait_queue_exit(struct optee_wait_queue *wq);
137
138u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
139 struct tee_param *param);
140
141int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len);
142int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len);
143void optee_supp_init(struct optee_supp *supp);
144void optee_supp_uninit(struct optee_supp *supp);
145
146int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
147 struct tee_param *param);
148int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
149 struct tee_param *param);
150
151u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
152int optee_open_session(struct tee_context *ctx,
153 struct tee_ioctl_open_session_arg *arg,
154 struct tee_param *param);
155int optee_close_session(struct tee_context *ctx, u32 session);
156int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
157 struct tee_param *param);
158int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
159
160void optee_enable_shm_cache(struct optee *optee);
161void optee_disable_shm_cache(struct optee *optee);
162
163int optee_from_msg_param(struct tee_param *params, size_t num_params,
164 const struct optee_msg_param *msg_params);
165int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
166 const struct tee_param *params);
167
168/*
169 * Small helpers
170 */
171
172static inline void *reg_pair_to_ptr(u32 reg0, u32 reg1)
173{
174 return (void *)(unsigned long)(((u64)reg0 << 32) | reg1);
175}
176
177static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
178{
179 *reg0 = val >> 32;
180 *reg1 = val;
181}
182
183#endif /*OPTEE_PRIVATE_H*/
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
new file mode 100644
index 000000000000..13b7c98cdf25
--- /dev/null
+++ b/drivers/tee/optee/optee_smc.h
@@ -0,0 +1,450 @@
1/*
2 * Copyright (c) 2015-2016, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27#ifndef OPTEE_SMC_H
28#define OPTEE_SMC_H
29
30#include <linux/arm-smccc.h>
31#include <linux/bitops.h>
32
33#define OPTEE_SMC_STD_CALL_VAL(func_num) \
34 ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \
35 ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
36#define OPTEE_SMC_FAST_CALL_VAL(func_num) \
37 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
38 ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
39
40/*
41 * Function specified by SMC Calling convention.
42 */
43#define OPTEE_SMC_FUNCID_CALLS_COUNT 0xFF00
44#define OPTEE_SMC_CALLS_COUNT \
45 ARM_SMCCC_CALL_VAL(OPTEE_SMC_FAST_CALL, SMCCC_SMC_32, \
46 SMCCC_OWNER_TRUSTED_OS_END, \
47 OPTEE_SMC_FUNCID_CALLS_COUNT)
48
49/*
50 * Normal cached memory (write-back), shareable for SMP systems and not
51 * shareable for UP systems.
52 */
53#define OPTEE_SMC_SHM_CACHED 1
54
55/*
56 * a0..a7 is used as register names in the descriptions below, on arm32
57 * that translates to r0..r7 and on arm64 to w0..w7. In both cases it's
58 * 32-bit registers.
59 */
60
61/*
62 * Function specified by SMC Calling convention
63 *
64 * Return one of the following UIDs if using API specified in this file
65 * without further extentions:
66 * 65cb6b93-af0c-4617-8ed6-644a8d1140f8
67 * see also OPTEE_SMC_UID_* in optee_msg.h
68 */
69#define OPTEE_SMC_FUNCID_CALLS_UID OPTEE_MSG_FUNCID_CALLS_UID
70#define OPTEE_SMC_CALLS_UID \
71 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
72 ARM_SMCCC_OWNER_TRUSTED_OS_END, \
73 OPTEE_SMC_FUNCID_CALLS_UID)
74
75/*
76 * Function specified by SMC Calling convention
77 *
78 * Returns 2.0 if using API specified in this file without further extentions.
79 * see also OPTEE_MSG_REVISION_* in optee_msg.h
80 */
81#define OPTEE_SMC_FUNCID_CALLS_REVISION OPTEE_MSG_FUNCID_CALLS_REVISION
82#define OPTEE_SMC_CALLS_REVISION \
83 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
84 ARM_SMCCC_OWNER_TRUSTED_OS_END, \
85 OPTEE_SMC_FUNCID_CALLS_REVISION)
86
87struct optee_smc_calls_revision_result {
88 unsigned long major;
89 unsigned long minor;
90 unsigned long reserved0;
91 unsigned long reserved1;
92};
93
94/*
95 * Get UUID of Trusted OS.
96 *
97 * Used by non-secure world to figure out which Trusted OS is installed.
98 * Note that returned UUID is the UUID of the Trusted OS, not of the API.
99 *
100 * Returns UUID in a0-4 in the same way as OPTEE_SMC_CALLS_UID
101 * described above.
102 */
103#define OPTEE_SMC_FUNCID_GET_OS_UUID OPTEE_MSG_FUNCID_GET_OS_UUID
104#define OPTEE_SMC_CALL_GET_OS_UUID \
105 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_UUID)
106
107/*
108 * Get revision of Trusted OS.
109 *
110 * Used by non-secure world to figure out which version of the Trusted OS
111 * is installed. Note that the returned revision is the revision of the
112 * Trusted OS, not of the API.
113 *
114 * Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION
115 * described above.
116 */
117#define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION
118#define OPTEE_SMC_CALL_GET_OS_REVISION \
119 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION)
120
121/*
122 * Call with struct optee_msg_arg as argument
123 *
124 * Call register usage:
125 * a0 SMC Function ID, OPTEE_SMC*CALL_WITH_ARG
126 * a1 Upper 32bit of a 64bit physical pointer to a struct optee_msg_arg
127 * a2 Lower 32bit of a 64bit physical pointer to a struct optee_msg_arg
128 * a3 Cache settings, not used if physical pointer is in a predefined shared
129 * memory area else per OPTEE_SMC_SHM_*
130 * a4-6 Not used
131 * a7 Hypervisor Client ID register
132 *
133 * Normal return register usage:
134 * a0 Return value, OPTEE_SMC_RETURN_*
135 * a1-3 Not used
136 * a4-7 Preserved
137 *
138 * OPTEE_SMC_RETURN_ETHREAD_LIMIT return register usage:
139 * a0 Return value, OPTEE_SMC_RETURN_ETHREAD_LIMIT
140 * a1-3 Preserved
141 * a4-7 Preserved
142 *
143 * RPC return register usage:
144 * a0 Return value, OPTEE_SMC_RETURN_IS_RPC(val)
145 * a1-2 RPC parameters
146 * a3-7 Resume information, must be preserved
147 *
148 * Possible return values:
149 * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this
150 * function.
151 * OPTEE_SMC_RETURN_OK Call completed, result updated in
152 * the previously supplied struct
153 * optee_msg_arg.
154 * OPTEE_SMC_RETURN_ETHREAD_LIMIT Number of Trusted OS threads exceeded,
155 * try again later.
156 * OPTEE_SMC_RETURN_EBADADDR Bad physcial pointer to struct
157 * optee_msg_arg.
158 * OPTEE_SMC_RETURN_EBADCMD Bad/unknown cmd in struct optee_msg_arg
159 * OPTEE_SMC_RETURN_IS_RPC() Call suspended by RPC call to normal
160 * world.
161 */
162#define OPTEE_SMC_FUNCID_CALL_WITH_ARG OPTEE_MSG_FUNCID_CALL_WITH_ARG
163#define OPTEE_SMC_CALL_WITH_ARG \
164 OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_ARG)
165
166/*
167 * Get Shared Memory Config
168 *
169 * Returns the Secure/Non-secure shared memory config.
170 *
171 * Call register usage:
172 * a0 SMC Function ID, OPTEE_SMC_GET_SHM_CONFIG
173 * a1-6 Not used
174 * a7 Hypervisor Client ID register
175 *
176 * Have config return register usage:
177 * a0 OPTEE_SMC_RETURN_OK
178 * a1 Physical address of start of SHM
179 * a2 Size of of SHM
180 * a3 Cache settings of memory, as defined by the
181 * OPTEE_SMC_SHM_* values above
182 * a4-7 Preserved
183 *
184 * Not available register usage:
185 * a0 OPTEE_SMC_RETURN_ENOTAVAIL
186 * a1-3 Not used
187 * a4-7 Preserved
188 */
189#define OPTEE_SMC_FUNCID_GET_SHM_CONFIG 7
190#define OPTEE_SMC_GET_SHM_CONFIG \
191 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SHM_CONFIG)
192
193struct optee_smc_get_shm_config_result {
194 unsigned long status;
195 unsigned long start;
196 unsigned long size;
197 unsigned long settings;
198};
199
200/*
201 * Exchanges capabilities between normal world and secure world
202 *
203 * Call register usage:
204 * a0 SMC Function ID, OPTEE_SMC_EXCHANGE_CAPABILITIES
205 * a1 bitfield of normal world capabilities OPTEE_SMC_NSEC_CAP_*
206 * a2-6 Not used
207 * a7 Hypervisor Client ID register
208 *
209 * Normal return register usage:
210 * a0 OPTEE_SMC_RETURN_OK
211 * a1 bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
212 * a2-7 Preserved
213 *
214 * Error return register usage:
215 * a0 OPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world
216 * a1 bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
217 * a2-7 Preserved
218 */
219/* Normal world works as a uniprocessor system */
220#define OPTEE_SMC_NSEC_CAP_UNIPROCESSOR BIT(0)
221/* Secure world has reserved shared memory for normal world to use */
222#define OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM BIT(0)
223/* Secure world can communicate via previously unregistered shared memory */
224#define OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM BIT(1)
225#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9
226#define OPTEE_SMC_EXCHANGE_CAPABILITIES \
227 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)
228
229struct optee_smc_exchange_capabilities_result {
230 unsigned long status;
231 unsigned long capabilities;
232 unsigned long reserved0;
233 unsigned long reserved1;
234};
235
236/*
237 * Disable and empties cache of shared memory objects
238 *
239 * Secure world can cache frequently used shared memory objects, for
240 * example objects used as RPC arguments. When secure world is idle this
241 * function returns one shared memory reference to free. To disable the
242 * cache and free all cached objects this function has to be called until
243 * it returns OPTEE_SMC_RETURN_ENOTAVAIL.
244 *
245 * Call register usage:
246 * a0 SMC Function ID, OPTEE_SMC_DISABLE_SHM_CACHE
247 * a1-6 Not used
248 * a7 Hypervisor Client ID register
249 *
250 * Normal return register usage:
251 * a0 OPTEE_SMC_RETURN_OK
252 * a1 Upper 32bit of a 64bit Shared memory cookie
253 * a2 Lower 32bit of a 64bit Shared memory cookie
254 * a3-7 Preserved
255 *
256 * Cache empty return register usage:
257 * a0 OPTEE_SMC_RETURN_ENOTAVAIL
258 * a1-7 Preserved
259 *
260 * Not idle return register usage:
261 * a0 OPTEE_SMC_RETURN_EBUSY
262 * a1-7 Preserved
263 */
264#define OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE 10
265#define OPTEE_SMC_DISABLE_SHM_CACHE \
266 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE)
267
268struct optee_smc_disable_shm_cache_result {
269 unsigned long status;
270 unsigned long shm_upper32;
271 unsigned long shm_lower32;
272 unsigned long reserved0;
273};
274
275/*
276 * Enable cache of shared memory objects
277 *
278 * Secure world can cache frequently used shared memory objects, for
279 * example objects used as RPC arguments. When secure world is idle this
280 * function returns OPTEE_SMC_RETURN_OK and the cache is enabled. If
281 * secure world isn't idle OPTEE_SMC_RETURN_EBUSY is returned.
282 *
283 * Call register usage:
284 * a0 SMC Function ID, OPTEE_SMC_ENABLE_SHM_CACHE
285 * a1-6 Not used
286 * a7 Hypervisor Client ID register
287 *
288 * Normal return register usage:
289 * a0 OPTEE_SMC_RETURN_OK
290 * a1-7 Preserved
291 *
292 * Not idle return register usage:
293 * a0 OPTEE_SMC_RETURN_EBUSY
294 * a1-7 Preserved
295 */
296#define OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE 11
297#define OPTEE_SMC_ENABLE_SHM_CACHE \
298 OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)
299
300/*
301 * Resume from RPC (for example after processing an IRQ)
302 *
303 * Call register usage:
304 * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC
305 * a1-3 Value of a1-3 when OPTEE_SMC_CALL_WITH_ARG returned
306 * OPTEE_SMC_RETURN_RPC in a0
307 *
308 * Return register usage is the same as for OPTEE_SMC_*CALL_WITH_ARG above.
309 *
310 * Possible return values
311 * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this
312 * function.
313 * OPTEE_SMC_RETURN_OK Original call completed, result
314 * updated in the previously supplied.
315 * struct optee_msg_arg
316 * OPTEE_SMC_RETURN_RPC Call suspended by RPC call to normal
317 * world.
318 * OPTEE_SMC_RETURN_ERESUME Resume failed, the opaque resume
319 * information was corrupt.
320 */
321#define OPTEE_SMC_FUNCID_RETURN_FROM_RPC 3
322#define OPTEE_SMC_CALL_RETURN_FROM_RPC \
323 OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_RETURN_FROM_RPC)
324
325#define OPTEE_SMC_RETURN_RPC_PREFIX_MASK 0xFFFF0000
326#define OPTEE_SMC_RETURN_RPC_PREFIX 0xFFFF0000
327#define OPTEE_SMC_RETURN_RPC_FUNC_MASK 0x0000FFFF
328
329#define OPTEE_SMC_RETURN_GET_RPC_FUNC(ret) \
330 ((ret) & OPTEE_SMC_RETURN_RPC_FUNC_MASK)
331
332#define OPTEE_SMC_RPC_VAL(func) ((func) | OPTEE_SMC_RETURN_RPC_PREFIX)
333
334/*
335 * Allocate memory for RPC parameter passing. The memory is used to hold a
336 * struct optee_msg_arg.
337 *
338 * "Call" register usage:
339 * a0 This value, OPTEE_SMC_RETURN_RPC_ALLOC
340 * a1 Size in bytes of required argument memory
341 * a2 Not used
342 * a3 Resume information, must be preserved
343 * a4-5 Not used
344 * a6-7 Resume information, must be preserved
345 *
346 * "Return" register usage:
347 * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
348 * a1 Upper 32bits of 64bit physical pointer to allocated
349 * memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
350 * be allocated.
351 * a2 Lower 32bits of 64bit physical pointer to allocated
352 * memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
353 * be allocated
354 * a3 Preserved
355 * a4 Upper 32bits of 64bit Shared memory cookie used when freeing
356 * the memory or doing an RPC
357 * a5 Lower 32bits of 64bit Shared memory cookie used when freeing
358 * the memory or doing an RPC
359 * a6-7 Preserved
360 */
361#define OPTEE_SMC_RPC_FUNC_ALLOC 0
362#define OPTEE_SMC_RETURN_RPC_ALLOC \
363 OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_ALLOC)
364
365/*
366 * Free memory previously allocated by OPTEE_SMC_RETURN_RPC_ALLOC
367 *
368 * "Call" register usage:
369 * a0 This value, OPTEE_SMC_RETURN_RPC_FREE
370 * a1 Upper 32bits of 64bit shared memory cookie belonging to this
371 * argument memory
372 * a2 Lower 32bits of 64bit shared memory cookie belonging to this
373 * argument memory
374 * a3-7 Resume information, must be preserved
375 *
376 * "Return" register usage:
377 * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
378 * a1-2 Not used
379 * a3-7 Preserved
380 */
381#define OPTEE_SMC_RPC_FUNC_FREE 2
382#define OPTEE_SMC_RETURN_RPC_FREE \
383 OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE)
384
385/*
386 * Deliver an IRQ in normal world.
387 *
388 * "Call" register usage:
389 * a0 OPTEE_SMC_RETURN_RPC_IRQ
390 * a1-7 Resume information, must be preserved
391 *
392 * "Return" register usage:
393 * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
394 * a1-7 Preserved
395 */
396#define OPTEE_SMC_RPC_FUNC_IRQ 4
397#define OPTEE_SMC_RETURN_RPC_IRQ \
398 OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ)
399
400/*
401 * Do an RPC request. The supplied struct optee_msg_arg tells which
402 * request to do and the parameters for the request. The following fields
403 * are used (the rest are unused):
404 * - cmd the Request ID
405 * - ret return value of the request, filled in by normal world
406 * - num_params number of parameters for the request
407 * - params the parameters
408 * - param_attrs attributes of the parameters
409 *
410 * "Call" register usage:
411 * a0 OPTEE_SMC_RETURN_RPC_CMD
412 * a1 Upper 32bit of a 64bit Shared memory cookie holding a
413 * struct optee_msg_arg, must be preserved, only the data should
414 * be updated
415 * a2 Lower 32bit of a 64bit Shared memory cookie holding a
416 * struct optee_msg_arg, must be preserved, only the data should
417 * be updated
418 * a3-7 Resume information, must be preserved
419 *
420 * "Return" register usage:
421 * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
422 * a1-2 Not used
423 * a3-7 Preserved
424 */
425#define OPTEE_SMC_RPC_FUNC_CMD 5
426#define OPTEE_SMC_RETURN_RPC_CMD \
427 OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_CMD)
428
429/* Returned in a0 */
430#define OPTEE_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
431
432/* Returned in a0 only from Trusted OS functions */
433#define OPTEE_SMC_RETURN_OK 0x0
434#define OPTEE_SMC_RETURN_ETHREAD_LIMIT 0x1
435#define OPTEE_SMC_RETURN_EBUSY 0x2
436#define OPTEE_SMC_RETURN_ERESUME 0x3
437#define OPTEE_SMC_RETURN_EBADADDR 0x4
438#define OPTEE_SMC_RETURN_EBADCMD 0x5
439#define OPTEE_SMC_RETURN_ENOMEM 0x6
440#define OPTEE_SMC_RETURN_ENOTAVAIL 0x7
441#define OPTEE_SMC_RETURN_IS_RPC(ret) __optee_smc_return_is_rpc((ret))
442
443static inline bool __optee_smc_return_is_rpc(u32 ret)
444{
445 return ret != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION &&
446 (ret & OPTEE_SMC_RETURN_RPC_PREFIX_MASK) ==
447 OPTEE_SMC_RETURN_RPC_PREFIX;
448}
449
450#endif /* OPTEE_SMC_H */
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
new file mode 100644
index 000000000000..8814eca06021
--- /dev/null
+++ b/drivers/tee/optee/rpc.c
@@ -0,0 +1,396 @@
1/*
2 * Copyright (c) 2015-2016, 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/delay.h>
18#include <linux/device.h>
19#include <linux/slab.h>
20#include <linux/tee_drv.h>
21#include "optee_private.h"
22#include "optee_smc.h"
23
24struct wq_entry {
25 struct list_head link;
26 struct completion c;
27 u32 key;
28};
29
30void optee_wait_queue_init(struct optee_wait_queue *priv)
31{
32 mutex_init(&priv->mu);
33 INIT_LIST_HEAD(&priv->db);
34}
35
36void optee_wait_queue_exit(struct optee_wait_queue *priv)
37{
38 mutex_destroy(&priv->mu);
39}
40
41static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
42{
43 struct timespec64 ts;
44
45 if (arg->num_params != 1)
46 goto bad;
47 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
48 OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT)
49 goto bad;
50
51 getnstimeofday64(&ts);
52 arg->params[0].u.value.a = ts.tv_sec;
53 arg->params[0].u.value.b = ts.tv_nsec;
54
55 arg->ret = TEEC_SUCCESS;
56 return;
57bad:
58 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
59}
60
61static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
62{
63 struct wq_entry *w;
64
65 mutex_lock(&wq->mu);
66
67 list_for_each_entry(w, &wq->db, link)
68 if (w->key == key)
69 goto out;
70
71 w = kmalloc(sizeof(*w), GFP_KERNEL);
72 if (w) {
73 init_completion(&w->c);
74 w->key = key;
75 list_add_tail(&w->link, &wq->db);
76 }
77out:
78 mutex_unlock(&wq->mu);
79 return w;
80}
81
82static void wq_sleep(struct optee_wait_queue *wq, u32 key)
83{
84 struct wq_entry *w = wq_entry_get(wq, key);
85
86 if (w) {
87 wait_for_completion(&w->c);
88 mutex_lock(&wq->mu);
89 list_del(&w->link);
90 mutex_unlock(&wq->mu);
91 kfree(w);
92 }
93}
94
95static void wq_wakeup(struct optee_wait_queue *wq, u32 key)
96{
97 struct wq_entry *w = wq_entry_get(wq, key);
98
99 if (w)
100 complete(&w->c);
101}
102
103static void handle_rpc_func_cmd_wq(struct optee *optee,
104 struct optee_msg_arg *arg)
105{
106 if (arg->num_params != 1)
107 goto bad;
108
109 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
110 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
111 goto bad;
112
113 switch (arg->params[0].u.value.a) {
114 case OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP:
115 wq_sleep(&optee->wait_queue, arg->params[0].u.value.b);
116 break;
117 case OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP:
118 wq_wakeup(&optee->wait_queue, arg->params[0].u.value.b);
119 break;
120 default:
121 goto bad;
122 }
123
124 arg->ret = TEEC_SUCCESS;
125 return;
126bad:
127 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
128}
129
130static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
131{
132 u32 msec_to_wait;
133
134 if (arg->num_params != 1)
135 goto bad;
136
137 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
138 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
139 goto bad;
140
141 msec_to_wait = arg->params[0].u.value.a;
142
143 /* set task's state to interruptible sleep */
144 set_current_state(TASK_INTERRUPTIBLE);
145
146 /* take a nap */
147 msleep(msec_to_wait);
148
149 arg->ret = TEEC_SUCCESS;
150 return;
151bad:
152 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
153}
154
155static void handle_rpc_supp_cmd(struct tee_context *ctx,
156 struct optee_msg_arg *arg)
157{
158 struct tee_param *params;
159
160 arg->ret_origin = TEEC_ORIGIN_COMMS;
161
162 params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
163 GFP_KERNEL);
164 if (!params) {
165 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
166 return;
167 }
168
169 if (optee_from_msg_param(params, arg->num_params, arg->params)) {
170 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
171 goto out;
172 }
173
174 arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
175
176 if (optee_to_msg_param(arg->params, arg->num_params, params))
177 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
178out:
179 kfree(params);
180}
181
182static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
183{
184 u32 ret;
185 struct tee_param param;
186 struct optee *optee = tee_get_drvdata(ctx->teedev);
187 struct tee_shm *shm;
188
189 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
190 param.u.value.a = OPTEE_MSG_RPC_SHM_TYPE_APPL;
191 param.u.value.b = sz;
192 param.u.value.c = 0;
193
194 ret = optee_supp_thrd_req(ctx, OPTEE_MSG_RPC_CMD_SHM_ALLOC, 1, &param);
195 if (ret)
196 return ERR_PTR(-ENOMEM);
197
198 mutex_lock(&optee->supp.ctx_mutex);
199 /* Increases count as secure world doesn't have a reference */
200 shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
201 mutex_unlock(&optee->supp.ctx_mutex);
202 return shm;
203}
204
205static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
206 struct optee_msg_arg *arg)
207{
208 phys_addr_t pa;
209 struct tee_shm *shm;
210 size_t sz;
211 size_t n;
212
213 arg->ret_origin = TEEC_ORIGIN_COMMS;
214
215 if (!arg->num_params ||
216 arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
217 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
218 return;
219 }
220
221 for (n = 1; n < arg->num_params; n++) {
222 if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) {
223 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
224 return;
225 }
226 }
227
228 sz = arg->params[0].u.value.b;
229 switch (arg->params[0].u.value.a) {
230 case OPTEE_MSG_RPC_SHM_TYPE_APPL:
231 shm = cmd_alloc_suppl(ctx, sz);
232 break;
233 case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
234 shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
235 break;
236 default:
237 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
238 return;
239 }
240
241 if (IS_ERR(shm)) {
242 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
243 return;
244 }
245
246 if (tee_shm_get_pa(shm, 0, &pa)) {
247 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
248 goto bad;
249 }
250
251 arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
252 arg->params[0].u.tmem.buf_ptr = pa;
253 arg->params[0].u.tmem.size = sz;
254 arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
255 arg->ret = TEEC_SUCCESS;
256 return;
257bad:
258 tee_shm_free(shm);
259}
260
261static void cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
262{
263 struct tee_param param;
264
265 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
266 param.u.value.a = OPTEE_MSG_RPC_SHM_TYPE_APPL;
267 param.u.value.b = tee_shm_get_id(shm);
268 param.u.value.c = 0;
269
270 /*
271 * Match the tee_shm_get_from_id() in cmd_alloc_suppl() as secure
272 * world has released its reference.
273 *
274 * It's better to do this before sending the request to supplicant
275 * as we'd like to let the process doing the initial allocation to
276 * do release the last reference too in order to avoid stacking
277 * many pending fput() on the client process. This could otherwise
278 * happen if secure world does many allocate and free in a single
279 * invoke.
280 */
281 tee_shm_put(shm);
282
283 optee_supp_thrd_req(ctx, OPTEE_MSG_RPC_CMD_SHM_FREE, 1, &param);
284}
285
286static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
287 struct optee_msg_arg *arg)
288{
289 struct tee_shm *shm;
290
291 arg->ret_origin = TEEC_ORIGIN_COMMS;
292
293 if (arg->num_params != 1 ||
294 arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
295 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
296 return;
297 }
298
299 shm = (struct tee_shm *)(unsigned long)arg->params[0].u.value.b;
300 switch (arg->params[0].u.value.a) {
301 case OPTEE_MSG_RPC_SHM_TYPE_APPL:
302 cmd_free_suppl(ctx, shm);
303 break;
304 case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
305 tee_shm_free(shm);
306 break;
307 default:
308 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
309 }
310 arg->ret = TEEC_SUCCESS;
311}
312
313static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
314 struct tee_shm *shm)
315{
316 struct optee_msg_arg *arg;
317
318 arg = tee_shm_get_va(shm, 0);
319 if (IS_ERR(arg)) {
320 pr_err("%s: tee_shm_get_va %p failed\n", __func__, shm);
321 return;
322 }
323
324 switch (arg->cmd) {
325 case OPTEE_MSG_RPC_CMD_GET_TIME:
326 handle_rpc_func_cmd_get_time(arg);
327 break;
328 case OPTEE_MSG_RPC_CMD_WAIT_QUEUE:
329 handle_rpc_func_cmd_wq(optee, arg);
330 break;
331 case OPTEE_MSG_RPC_CMD_SUSPEND:
332 handle_rpc_func_cmd_wait(arg);
333 break;
334 case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
335 handle_rpc_func_cmd_shm_alloc(ctx, arg);
336 break;
337 case OPTEE_MSG_RPC_CMD_SHM_FREE:
338 handle_rpc_func_cmd_shm_free(ctx, arg);
339 break;
340 default:
341 handle_rpc_supp_cmd(ctx, arg);
342 }
343}
344
345/**
346 * optee_handle_rpc() - handle RPC from secure world
347 * @ctx: context doing the RPC
348 * @param: value of registers for the RPC
349 *
350 * Result of RPC is written back into @param.
351 */
352void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param)
353{
354 struct tee_device *teedev = ctx->teedev;
355 struct optee *optee = tee_get_drvdata(teedev);
356 struct tee_shm *shm;
357 phys_addr_t pa;
358
359 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
360 case OPTEE_SMC_RPC_FUNC_ALLOC:
361 shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
362 if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
363 reg_pair_from_64(&param->a1, &param->a2, pa);
364 reg_pair_from_64(&param->a4, &param->a5,
365 (unsigned long)shm);
366 } else {
367 param->a1 = 0;
368 param->a2 = 0;
369 param->a4 = 0;
370 param->a5 = 0;
371 }
372 break;
373 case OPTEE_SMC_RPC_FUNC_FREE:
374 shm = reg_pair_to_ptr(param->a1, param->a2);
375 tee_shm_free(shm);
376 break;
377 case OPTEE_SMC_RPC_FUNC_IRQ:
378 /*
379 * An IRQ was raised while secure world was executing,
380 * since all IRQs are handled in Linux a dummy RPC is
381 * performed to let Linux take the IRQ through the normal
382 * vector.
383 */
384 break;
385 case OPTEE_SMC_RPC_FUNC_CMD:
386 shm = reg_pair_to_ptr(param->a1, param->a2);
387 handle_rpc_func_cmd(ctx, optee, shm);
388 break;
389 default:
390 pr_warn("Unknown RPC func 0x%x\n",
391 (u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
392 break;
393 }
394
395 param->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;
396}
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
new file mode 100644
index 000000000000..b4ea0678a436
--- /dev/null
+++ b/drivers/tee/optee/supp.c
@@ -0,0 +1,273 @@
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#include <linux/device.h>
15#include <linux/slab.h>
16#include <linux/uaccess.h>
17#include "optee_private.h"
18
19void optee_supp_init(struct optee_supp *supp)
20{
21 memset(supp, 0, sizeof(*supp));
22 mutex_init(&supp->ctx_mutex);
23 mutex_init(&supp->thrd_mutex);
24 mutex_init(&supp->supp_mutex);
25 init_completion(&supp->data_to_supp);
26 init_completion(&supp->data_from_supp);
27}
28
29void optee_supp_uninit(struct optee_supp *supp)
30{
31 mutex_destroy(&supp->ctx_mutex);
32 mutex_destroy(&supp->thrd_mutex);
33 mutex_destroy(&supp->supp_mutex);
34}
35
36/**
37 * optee_supp_thrd_req() - request service from supplicant
38 * @ctx: context doing the request
39 * @func: function requested
40 * @num_params: number of elements in @param array
41 * @param: parameters for function
42 *
43 * Returns result of operation to be passed to secure world
44 */
45u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
46 struct tee_param *param)
47{
48 bool interruptable;
49 struct optee *optee = tee_get_drvdata(ctx->teedev);
50 struct optee_supp *supp = &optee->supp;
51 u32 ret;
52
53 /*
54 * Other threads blocks here until we've copied our answer from
55 * supplicant.
56 */
57 while (mutex_lock_interruptible(&supp->thrd_mutex)) {
58 /* See comment below on when the RPC can be interrupted. */
59 mutex_lock(&supp->ctx_mutex);
60 interruptable = !supp->ctx;
61 mutex_unlock(&supp->ctx_mutex);
62 if (interruptable)
63 return TEEC_ERROR_COMMUNICATION;
64 }
65
66 /*
67 * We have exclusive access now since the supplicant at this
68 * point is either doing a
69 * wait_for_completion_interruptible(&supp->data_to_supp) or is in
70 * userspace still about to do the ioctl() to enter
71 * optee_supp_recv() below.
72 */
73
74 supp->func = func;
75 supp->num_params = num_params;
76 supp->param = param;
77 supp->req_posted = true;
78
79 /* Let supplicant get the data */
80 complete(&supp->data_to_supp);
81
82 /*
83 * Wait for supplicant to process and return result, once we've
84 * returned from wait_for_completion(data_from_supp) we have
85 * exclusive access again.
86 */
87 while (wait_for_completion_interruptible(&supp->data_from_supp)) {
88 mutex_lock(&supp->ctx_mutex);
89 interruptable = !supp->ctx;
90 if (interruptable) {
91 /*
92 * There's no supplicant available and since the
93 * supp->ctx_mutex currently is held none can
94 * become available until the mutex released
95 * again.
96 *
97 * Interrupting an RPC to supplicant is only
98 * allowed as a way of slightly improving the user
99 * experience in case the supplicant hasn't been
100 * started yet. During normal operation the supplicant
101 * will serve all requests in a timely manner and
102 * interrupting then wouldn't make sense.
103 */
104 supp->ret = TEEC_ERROR_COMMUNICATION;
105 init_completion(&supp->data_to_supp);
106 }
107 mutex_unlock(&supp->ctx_mutex);
108 if (interruptable)
109 break;
110 }
111
112 ret = supp->ret;
113 supp->param = NULL;
114 supp->req_posted = false;
115
116 /* We're done, let someone else talk to the supplicant now. */
117 mutex_unlock(&supp->thrd_mutex);
118
119 return ret;
120}
121
122/**
123 * optee_supp_recv() - receive request for supplicant
124 * @ctx: context receiving the request
125 * @func: requested function in supplicant
126 * @num_params: number of elements allocated in @param, updated with number
127 * used elements
128 * @param: space for parameters for @func
129 *
130 * Returns 0 on success or <0 on failure
131 */
132int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
133 struct tee_param *param)
134{
135 struct tee_device *teedev = ctx->teedev;
136 struct optee *optee = tee_get_drvdata(teedev);
137 struct optee_supp *supp = &optee->supp;
138 int rc;
139
140 /*
141 * In case two threads in one supplicant is calling this function
142 * simultaneously we need to protect the data with a mutex which
143 * we'll release before returning.
144 */
145 mutex_lock(&supp->supp_mutex);
146
147 if (supp->supp_next_send) {
148 /*
149 * optee_supp_recv() has been called again without
150 * a optee_supp_send() in between. Supplicant has
151 * probably been restarted before it was able to
152 * write back last result. Abort last request and
153 * wait for a new.
154 */
155 if (supp->req_posted) {
156 supp->ret = TEEC_ERROR_COMMUNICATION;
157 supp->supp_next_send = false;
158 complete(&supp->data_from_supp);
159 }
160 }
161
162 /*
163 * This is where supplicant will be hanging most of the
164 * time, let's make this interruptable so we can easily
165 * restart supplicant if needed.
166 */
167 if (wait_for_completion_interruptible(&supp->data_to_supp)) {
168 rc = -ERESTARTSYS;
169 goto out;
170 }
171
172 /* We have exlusive access to the data */
173
174 if (*num_params < supp->num_params) {
175 /*
176 * Not enough room for parameters, tell supplicant
177 * it failed and abort last request.
178 */
179 supp->ret = TEEC_ERROR_COMMUNICATION;
180 rc = -EINVAL;
181 complete(&supp->data_from_supp);
182 goto out;
183 }
184
185 *func = supp->func;
186 *num_params = supp->num_params;
187 memcpy(param, supp->param,
188 sizeof(struct tee_param) * supp->num_params);
189
190 /* Allow optee_supp_send() below to do its work */
191 supp->supp_next_send = true;
192
193 rc = 0;
194out:
195 mutex_unlock(&supp->supp_mutex);
196 return rc;
197}
198
199/**
200 * optee_supp_send() - send result of request from supplicant
201 * @ctx: context sending result
202 * @ret: return value of request
203 * @num_params: number of parameters returned
204 * @param: returned parameters
205 *
206 * Returns 0 on success or <0 on failure.
207 */
208int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
209 struct tee_param *param)
210{
211 struct tee_device *teedev = ctx->teedev;
212 struct optee *optee = tee_get_drvdata(teedev);
213 struct optee_supp *supp = &optee->supp;
214 size_t n;
215 int rc = 0;
216
217 /*
218 * We still have exclusive access to the data since that's how we
219 * left it when returning from optee_supp_read().
220 */
221
222 /* See comment on mutex in optee_supp_read() above */
223 mutex_lock(&supp->supp_mutex);
224
225 if (!supp->supp_next_send) {
226 /*
227 * Something strange is going on, supplicant shouldn't
228 * enter optee_supp_send() in this state
229 */
230 rc = -ENOENT;
231 goto out;
232 }
233
234 if (num_params != supp->num_params) {
235 /*
236 * Something is wrong, let supplicant restart. Next call to
237 * optee_supp_recv() will give an error to the requesting
238 * thread and release it.
239 */
240 rc = -EINVAL;
241 goto out;
242 }
243
244 /* Update out and in/out parameters */
245 for (n = 0; n < num_params; n++) {
246 struct tee_param *p = supp->param + n;
247
248 switch (p->attr) {
249 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
250 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
251 p->u.value.a = param[n].u.value.a;
252 p->u.value.b = param[n].u.value.b;
253 p->u.value.c = param[n].u.value.c;
254 break;
255 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
256 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
257 p->u.memref.size = param[n].u.memref.size;
258 break;
259 default:
260 break;
261 }
262 }
263 supp->ret = ret;
264
265 /* Allow optee_supp_recv() above to do its work */
266 supp->supp_next_send = false;
267
268 /* Let the requesting thread continue */
269 complete(&supp->data_from_supp);
270out:
271 mutex_unlock(&supp->supp_mutex);
272 return rc;
273}