blob: cc6863c76b4835c9220c633cb0346a4071f8cce4 [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From cbb24d5b6b4e6704da79bb3df76179a88a6ee14f Mon Sep 17 00:00:00 2001
Brad Bishopbec4ebc2022-08-03 09:55:16 -04002From: Jens Wiklander <jens.wiklander@linaro.org>
3Date: Thu, 25 Mar 2021 15:08:50 +0100
Patrick Williams2194f502022-10-16 14:26:09 -05004Subject: [PATCH 10/40] optee: refactor driver with internal callbacks
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005
6The OP-TEE driver is refactored with three internal callbacks replacing
7direct calls to optee_from_msg_param(), optee_to_msg_param() and
8optee_do_call_with_arg().
9
10These functions a central to communicating with OP-TEE in secure world
11by using the SMC Calling Convention directly.
12
13This refactoring makes room for using other primitives to communicate
14with OP-TEE in secure world while being able to reuse as much as
15possible from the present driver.
16
Patrick Williams2194f502022-10-16 14:26:09 -050017Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Brad Bishopbec4ebc2022-08-03 09:55:16 -040018Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Brad Bishopbec4ebc2022-08-03 09:55:16 -040019Upstream-Status: Pending [Not submitted to upstream yet]
Patrick Williams2194f502022-10-16 14:26:09 -050020Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com>
Brad Bishopbec4ebc2022-08-03 09:55:16 -040021---
22 drivers/tee/optee/call.c | 86 +++++++++--------
23 drivers/tee/optee/core.c | 148 ++++++++++++++++++++----------
24 drivers/tee/optee/optee_private.h | 35 +++++--
25 drivers/tee/optee/rpc.c | 19 ++--
26 4 files changed, 182 insertions(+), 106 deletions(-)
27
28diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
Patrick Williams2194f502022-10-16 14:26:09 -050029index 103976df2062..ddedde45f1ee 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040030--- a/drivers/tee/optee/call.c
31+++ b/drivers/tee/optee/call.c
32@@ -1,6 +1,6 @@
33 // SPDX-License-Identifier: GPL-2.0-only
34 /*
35- * Copyright (c) 2015, Linaro Limited
36+ * Copyright (c) 2015-2021, Linaro Limited
37 */
38 #include <linux/arm-smccc.h>
39 #include <linux/device.h>
Patrick Williams2194f502022-10-16 14:26:09 -050040@@ -118,20 +118,25 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
Brad Bishopbec4ebc2022-08-03 09:55:16 -040041 /**
42 * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
43 * @ctx: calling context
44- * @parg: physical address of message to pass to secure world
45+ * @arg: shared memory holding the message to pass to secure world
46 *
47 * Does and SMC to OP-TEE in secure world and handles eventual resulting
48 * Remote Procedure Calls (RPC) from OP-TEE.
49 *
50 * Returns return code from secure world, 0 is OK
51 */
52-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
53+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg)
54 {
55 struct optee *optee = tee_get_drvdata(ctx->teedev);
56 struct optee_call_waiter w;
57 struct optee_rpc_param param = { };
58 struct optee_call_ctx call_ctx = { };
59- u32 ret;
60+ phys_addr_t parg;
61+ int rc;
62+
63+ rc = tee_shm_get_pa(arg, 0, &parg);
64+ if (rc)
65+ return rc;
66
67 param.a0 = OPTEE_SMC_CALL_WITH_ARG;
68 reg_pair_from_64(&param.a1, &param.a2, parg);
Patrick Williams2194f502022-10-16 14:26:09 -050069@@ -160,7 +165,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040070 param.a3 = res.a3;
71 optee_handle_rpc(ctx, &param, &call_ctx);
72 } else {
73- ret = res.a0;
74+ rc = res.a0;
75 break;
76 }
77 }
Patrick Williams2194f502022-10-16 14:26:09 -050078@@ -172,14 +177,12 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040079 */
80 optee_cq_wait_final(&optee->call_queue, &w);
81
82- return ret;
83+ return rc;
84 }
85
86 static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
87- struct optee_msg_arg **msg_arg,
88- phys_addr_t *msg_parg)
89+ struct optee_msg_arg **msg_arg)
90 {
91- int rc;
92 struct tee_shm *shm;
93 struct optee_msg_arg *ma;
94
Patrick Williams2194f502022-10-16 14:26:09 -050095@@ -190,22 +193,13 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
Brad Bishopbec4ebc2022-08-03 09:55:16 -040096
97 ma = tee_shm_get_va(shm, 0);
98 if (IS_ERR(ma)) {
99- rc = PTR_ERR(ma);
100- goto out;
101+ tee_shm_free(shm);
102+ return (void *)ma;
103 }
104
105- rc = tee_shm_get_pa(shm, 0, msg_parg);
106- if (rc)
107- goto out;
108-
109 memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
110 ma->num_params = num_params;
111 *msg_arg = ma;
112-out:
113- if (rc) {
114- tee_shm_free(shm);
115- return ERR_PTR(rc);
116- }
117
118 return shm;
119 }
Patrick Williams2194f502022-10-16 14:26:09 -0500120@@ -214,16 +208,16 @@ int optee_open_session(struct tee_context *ctx,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400121 struct tee_ioctl_open_session_arg *arg,
122 struct tee_param *param)
123 {
124+ struct optee *optee = tee_get_drvdata(ctx->teedev);
125 struct optee_context_data *ctxdata = ctx->data;
126 int rc;
127 struct tee_shm *shm;
128 struct optee_msg_arg *msg_arg;
129- phys_addr_t msg_parg;
130 struct optee_session *sess = NULL;
131 uuid_t client_uuid;
132
133 /* +2 for the meta parameters added below */
134- shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
135+ shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
136 if (IS_ERR(shm))
137 return PTR_ERR(shm);
138
Patrick Williams2194f502022-10-16 14:26:09 -0500139@@ -247,7 +241,8 @@ int optee_open_session(struct tee_context *ctx,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400140 goto out;
141 export_uuid(msg_arg->params[1].u.octets, &client_uuid);
142
143- rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
144+ rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
145+ arg->num_params, param);
146 if (rc)
147 goto out;
148
Patrick Williams2194f502022-10-16 14:26:09 -0500149@@ -257,7 +252,7 @@ int optee_open_session(struct tee_context *ctx,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400150 goto out;
151 }
152
153- if (optee_do_call_with_arg(ctx, msg_parg)) {
154+ if (optee->ops->do_call_with_arg(ctx, shm)) {
155 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
156 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
157 }
Patrick Williams2194f502022-10-16 14:26:09 -0500158@@ -272,7 +267,8 @@ int optee_open_session(struct tee_context *ctx,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400159 kfree(sess);
160 }
161
162- if (optee_from_msg_param(param, arg->num_params, msg_arg->params + 2)) {
163+ if (optee->ops->from_msg_param(optee, param, arg->num_params,
164+ msg_arg->params + 2)) {
165 arg->ret = TEEC_ERROR_COMMUNICATION;
166 arg->ret_origin = TEEC_ORIGIN_COMMS;
167 /* Close session again to avoid leakage */
Patrick Williams2194f502022-10-16 14:26:09 -0500168@@ -291,16 +287,16 @@ int optee_open_session(struct tee_context *ctx,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400169 int optee_close_session_helper(struct tee_context *ctx, u32 session)
170 {
171 struct tee_shm *shm;
172+ struct optee *optee = tee_get_drvdata(ctx->teedev);
173 struct optee_msg_arg *msg_arg;
174- phys_addr_t msg_parg;
175
176- shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
177+ shm = get_msg_arg(ctx, 0, &msg_arg);
178 if (IS_ERR(shm))
179 return PTR_ERR(shm);
180
181 msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
182 msg_arg->session = session;
183- optee_do_call_with_arg(ctx, msg_parg);
184+ optee->ops->do_call_with_arg(ctx, shm);
185
186 tee_shm_free(shm);
187
Patrick Williams2194f502022-10-16 14:26:09 -0500188@@ -328,10 +324,10 @@ int optee_close_session(struct tee_context *ctx, u32 session)
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400189 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
190 struct tee_param *param)
191 {
192+ struct optee *optee = tee_get_drvdata(ctx->teedev);
193 struct optee_context_data *ctxdata = ctx->data;
194 struct tee_shm *shm;
195 struct optee_msg_arg *msg_arg;
196- phys_addr_t msg_parg;
197 struct optee_session *sess;
198 int rc;
199
Patrick Williams2194f502022-10-16 14:26:09 -0500200@@ -342,7 +338,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400201 if (!sess)
202 return -EINVAL;
203
204- shm = get_msg_arg(ctx, arg->num_params, &msg_arg, &msg_parg);
205+ shm = get_msg_arg(ctx, arg->num_params, &msg_arg);
206 if (IS_ERR(shm))
207 return PTR_ERR(shm);
208 msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
Patrick Williams2194f502022-10-16 14:26:09 -0500209@@ -350,16 +346,18 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400210 msg_arg->session = arg->session;
211 msg_arg->cancel_id = arg->cancel_id;
212
213- rc = optee_to_msg_param(msg_arg->params, arg->num_params, param);
214+ rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
215+ param);
216 if (rc)
217 goto out;
218
219- if (optee_do_call_with_arg(ctx, msg_parg)) {
220+ if (optee->ops->do_call_with_arg(ctx, shm)) {
221 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
222 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
223 }
224
225- if (optee_from_msg_param(param, arg->num_params, msg_arg->params)) {
226+ if (optee->ops->from_msg_param(optee, param, arg->num_params,
227+ msg_arg->params)) {
228 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
229 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
230 }
Patrick Williams2194f502022-10-16 14:26:09 -0500231@@ -373,10 +371,10 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400232
233 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
234 {
235+ struct optee *optee = tee_get_drvdata(ctx->teedev);
236 struct optee_context_data *ctxdata = ctx->data;
237 struct tee_shm *shm;
238 struct optee_msg_arg *msg_arg;
239- phys_addr_t msg_parg;
240 struct optee_session *sess;
241
242 /* Check that the session is valid */
Patrick Williams2194f502022-10-16 14:26:09 -0500243@@ -386,14 +384,14 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400244 if (!sess)
245 return -EINVAL;
246
247- shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
248+ shm = get_msg_arg(ctx, 0, &msg_arg);
249 if (IS_ERR(shm))
250 return PTR_ERR(shm);
251
252 msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
253 msg_arg->session = session;
254 msg_arg->cancel_id = cancel_id;
255- optee_do_call_with_arg(ctx, msg_parg);
256+ optee->ops->do_call_with_arg(ctx, shm);
257
258 tee_shm_free(shm);
259 return 0;
Patrick Williams2194f502022-10-16 14:26:09 -0500260@@ -622,10 +620,10 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400261 struct page **pages, size_t num_pages,
262 unsigned long start)
263 {
264- struct tee_shm *shm_arg = NULL;
265+ struct optee *optee = tee_get_drvdata(ctx->teedev);
266 struct optee_msg_arg *msg_arg;
267+ struct tee_shm *shm_arg;
268 u64 *pages_list;
269- phys_addr_t msg_parg;
270 int rc;
271
272 if (!num_pages)
Patrick Williams2194f502022-10-16 14:26:09 -0500273@@ -639,7 +637,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400274 if (!pages_list)
275 return -ENOMEM;
276
277- shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
278+ shm_arg = get_msg_arg(ctx, 1, &msg_arg);
279 if (IS_ERR(shm_arg)) {
280 rc = PTR_ERR(shm_arg);
281 goto out;
Patrick Williams2194f502022-10-16 14:26:09 -0500282@@ -660,7 +658,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400283 msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
284 (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
285
286- if (optee_do_call_with_arg(ctx, msg_parg) ||
Patrick Williams2194f502022-10-16 14:26:09 -0500287+ if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400288 msg_arg->ret != TEEC_SUCCESS)
289 rc = -EINVAL;
290
Patrick Williams2194f502022-10-16 14:26:09 -0500291@@ -672,12 +670,12 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400292
293 int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
294 {
295- struct tee_shm *shm_arg;
296+ struct optee *optee = tee_get_drvdata(ctx->teedev);
297 struct optee_msg_arg *msg_arg;
298- phys_addr_t msg_parg;
299+ struct tee_shm *shm_arg;
300 int rc = 0;
301
302- shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
303+ shm_arg = get_msg_arg(ctx, 1, &msg_arg);
304 if (IS_ERR(shm_arg))
305 return PTR_ERR(shm_arg);
306
Patrick Williams2194f502022-10-16 14:26:09 -0500307@@ -686,7 +684,7 @@ int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400308 msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
309 msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
310
311- if (optee_do_call_with_arg(ctx, msg_parg) ||
Patrick Williams2194f502022-10-16 14:26:09 -0500312+ if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400313 msg_arg->ret != TEEC_SUCCESS)
314 rc = -EINVAL;
315 tee_shm_free(shm_arg);
316diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
Patrick Williams2194f502022-10-16 14:26:09 -0500317index 79f67a79e7b7..26492d3115f5 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400318--- a/drivers/tee/optee/core.c
319+++ b/drivers/tee/optee/core.c
320@@ -1,6 +1,6 @@
321 // SPDX-License-Identifier: GPL-2.0-only
322 /*
323- * Copyright (c) 2015, Linaro Limited
324+ * Copyright (c) 2015-2021, Linaro Limited
325 */
326
327 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Patrick Williams2194f502022-10-16 14:26:09 -0500328@@ -27,21 +27,87 @@
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400329
330 #define OPTEE_SHM_NUM_PRIV_PAGES CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
331
332+static void from_msg_param_value(struct tee_param *p, u32 attr,
333+ const struct optee_msg_param *mp)
334+{
335+ p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
336+ attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
337+ p->u.value.a = mp->u.value.a;
338+ p->u.value.b = mp->u.value.b;
339+ p->u.value.c = mp->u.value.c;
340+}
341+
342+static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
343+ const struct optee_msg_param *mp)
344+{
345+ struct tee_shm *shm;
346+ phys_addr_t pa;
347+ int rc;
348+
349+ p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
350+ attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
351+ p->u.memref.size = mp->u.tmem.size;
352+ shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
353+ if (!shm) {
354+ p->u.memref.shm_offs = 0;
355+ p->u.memref.shm = NULL;
356+ return 0;
357+ }
358+
359+ rc = tee_shm_get_pa(shm, 0, &pa);
360+ if (rc)
361+ return rc;
362+
363+ p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
364+ p->u.memref.shm = shm;
365+
366+ /* Check that the memref is covered by the shm object */
367+ if (p->u.memref.size) {
368+ size_t o = p->u.memref.shm_offs +
369+ p->u.memref.size - 1;
370+
371+ rc = tee_shm_get_pa(shm, o, NULL);
372+ if (rc)
373+ return rc;
374+ }
375+
376+ return 0;
377+}
378+
379+static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
380+ const struct optee_msg_param *mp)
381+{
382+ struct tee_shm *shm;
383+
384+ p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
385+ attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
386+ p->u.memref.size = mp->u.rmem.size;
387+ shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
388+
389+ if (shm) {
390+ p->u.memref.shm_offs = mp->u.rmem.offs;
391+ p->u.memref.shm = shm;
392+ } else {
393+ p->u.memref.shm_offs = 0;
394+ p->u.memref.shm = NULL;
395+ }
396+}
397+
398 /**
399 * optee_from_msg_param() - convert from OPTEE_MSG parameters to
400 * struct tee_param
401+ * @optee: main service struct
402 * @params: subsystem internal parameter representation
403 * @num_params: number of elements in the parameter arrays
404 * @msg_params: OPTEE_MSG parameters
405 * Returns 0 on success or <0 on failure
406 */
407-int optee_from_msg_param(struct tee_param *params, size_t num_params,
408- const struct optee_msg_param *msg_params)
409+static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
410+ size_t num_params,
411+ const struct optee_msg_param *msg_params)
412 {
413 int rc;
414 size_t n;
415- struct tee_shm *shm;
416- phys_addr_t pa;
417
418 for (n = 0; n < num_params; n++) {
419 struct tee_param *p = params + n;
Patrick Williams2194f502022-10-16 14:26:09 -0500420@@ -56,48 +122,19 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400421 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
422 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
423 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
424- p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
425- attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
426- p->u.value.a = mp->u.value.a;
427- p->u.value.b = mp->u.value.b;
428- p->u.value.c = mp->u.value.c;
429+ from_msg_param_value(p, attr, mp);
430 break;
431 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
432 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
433 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
434- p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
435- attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
436- p->u.memref.size = mp->u.tmem.size;
437- shm = (struct tee_shm *)(unsigned long)
438- mp->u.tmem.shm_ref;
439- if (!shm) {
440- p->u.memref.shm_offs = 0;
441- p->u.memref.shm = NULL;
442- break;
443- }
444- rc = tee_shm_get_pa(shm, 0, &pa);
445+ rc = from_msg_param_tmp_mem(p, attr, mp);
446 if (rc)
447 return rc;
448- p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
449- p->u.memref.shm = shm;
450 break;
451 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
452 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
453 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
454- p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
455- attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
456- p->u.memref.size = mp->u.rmem.size;
457- shm = (struct tee_shm *)(unsigned long)
458- mp->u.rmem.shm_ref;
459-
460- if (!shm) {
461- p->u.memref.shm_offs = 0;
462- p->u.memref.shm = NULL;
463- break;
464- }
465- p->u.memref.shm_offs = mp->u.rmem.offs;
466- p->u.memref.shm = shm;
467-
468+ from_msg_param_reg_mem(p, attr, mp);
469 break;
470
471 default:
Patrick Williams2194f502022-10-16 14:26:09 -0500472@@ -107,6 +144,16 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400473 return 0;
474 }
475
476+static void to_msg_param_value(struct optee_msg_param *mp,
477+ const struct tee_param *p)
478+{
479+ mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
480+ TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
481+ mp->u.value.a = p->u.value.a;
482+ mp->u.value.b = p->u.value.b;
483+ mp->u.value.c = p->u.value.c;
484+}
485+
486 static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
487 const struct tee_param *p)
488 {
Patrick Williams2194f502022-10-16 14:26:09 -0500489@@ -149,13 +196,15 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400490
491 /**
492 * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
493+ * @optee: main service struct
494 * @msg_params: OPTEE_MSG parameters
495 * @num_params: number of elements in the parameter arrays
496 * @params: subsystem itnernal parameter representation
497 * Returns 0 on success or <0 on failure
498 */
499-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
500- const struct tee_param *params)
501+static int optee_to_msg_param(struct optee *optee,
502+ struct optee_msg_param *msg_params,
503+ size_t num_params, const struct tee_param *params)
504 {
505 int rc;
506 size_t n;
Patrick Williams2194f502022-10-16 14:26:09 -0500507@@ -172,11 +221,7 @@ int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400508 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
509 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
510 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
511- mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
512- TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
513- mp->u.value.a = p->u.value.a;
514- mp->u.value.b = p->u.value.b;
515- mp->u.value.c = p->u.value.c;
516+ to_msg_param_value(mp, p);
517 break;
518 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
519 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
Patrick Williams2194f502022-10-16 14:26:09 -0500520@@ -302,7 +347,7 @@ static void optee_release_supp(struct tee_context *ctx)
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400521 optee_supp_release(&optee->supp);
522 }
523
524-static const struct tee_driver_ops optee_ops = {
525+static const struct tee_driver_ops optee_clnt_ops = {
526 .get_version = optee_get_version,
527 .open = optee_open,
528 .release = optee_release,
Patrick Williams2194f502022-10-16 14:26:09 -0500529@@ -314,9 +359,9 @@ static const struct tee_driver_ops optee_ops = {
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400530 .shm_unregister = optee_shm_unregister,
531 };
532
533-static const struct tee_desc optee_desc = {
534+static const struct tee_desc optee_clnt_desc = {
535 .name = DRIVER_NAME "-clnt",
536- .ops = &optee_ops,
537+ .ops = &optee_clnt_ops,
538 .owner = THIS_MODULE,
539 };
540
Patrick Williams2194f502022-10-16 14:26:09 -0500541@@ -337,6 +382,12 @@ static const struct tee_desc optee_supp_desc = {
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400542 .flags = TEE_DESC_PRIVILEGED,
543 };
544
545+static const struct optee_ops optee_ops = {
546+ .do_call_with_arg = optee_do_call_with_arg,
547+ .to_msg_param = optee_to_msg_param,
548+ .from_msg_param = optee_from_msg_param,
549+};
550+
551 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
552 {
553 struct arm_smccc_res res;
Patrick Williams2194f502022-10-16 14:26:09 -0500554@@ -670,10 +721,11 @@ static int optee_probe(struct platform_device *pdev)
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400555 goto err;
556 }
557
558+ optee->ops = &optee_ops;
559 optee->invoke_fn = invoke_fn;
560 optee->sec_caps = sec_caps;
561
562- teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
563+ teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
564 if (IS_ERR(teedev)) {
565 rc = PTR_ERR(teedev);
566 goto err;
567diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
Patrick Williams2194f502022-10-16 14:26:09 -0500568index a55793f9f6eb..beca97017996 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400569--- a/drivers/tee/optee/optee_private.h
570+++ b/drivers/tee/optee/optee_private.h
571@@ -1,6 +1,6 @@
572 /* SPDX-License-Identifier: GPL-2.0-only */
573 /*
574- * Copyright (c) 2015, Linaro Limited
575+ * Copyright (c) 2015-2021, Linaro Limited
576 */
577
578 #ifndef OPTEE_PRIVATE_H
579@@ -66,9 +66,34 @@ struct optee_supp {
580 struct completion reqs_c;
581 };
582
583+struct optee;
584+
585+/**
586+ * struct optee_ops - OP-TEE driver internal operations
587+ * @do_call_with_arg: enters OP-TEE in secure world
588+ * @to_msg_param: converts from struct tee_param to OPTEE_MSG parameters
589+ * @from_msg_param: converts from OPTEE_MSG parameters to struct tee_param
590+ *
591+ * These OPs are only supposed to be used internally in the OP-TEE driver
592+ * as a way of abstracting the different methogs of entering OP-TEE in
593+ * secure world.
594+ */
595+struct optee_ops {
596+ int (*do_call_with_arg)(struct tee_context *ctx,
597+ struct tee_shm *shm_arg);
598+ int (*to_msg_param)(struct optee *optee,
599+ struct optee_msg_param *msg_params,
600+ size_t num_params, const struct tee_param *params);
601+ int (*from_msg_param)(struct optee *optee, struct tee_param *params,
602+ size_t num_params,
603+ const struct optee_msg_param *msg_params);
604+};
605+
606 /**
607 * struct optee - main service struct
608 * @supp_teedev: supplicant device
609+ * @ops: internal callbacks for different ways to reach secure
610+ * world
611 * @teedev: client device
612 * @invoke_fn: function to issue smc or hvc
613 * @call_queue: queue of threads waiting to call @invoke_fn
614@@ -86,6 +111,7 @@ struct optee_supp {
615 struct optee {
616 struct tee_device *supp_teedev;
617 struct tee_device *teedev;
618+ const struct optee_ops *ops;
619 optee_invoke_fn *invoke_fn;
620 struct optee_call_queue call_queue;
621 struct optee_wait_queue wait_queue;
622@@ -148,7 +174,7 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
623 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
624 struct tee_param *param);
625
626-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
627+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg);
628 int optee_open_session(struct tee_context *ctx,
629 struct tee_ioctl_open_session_arg *arg,
630 struct tee_param *param);
Patrick Williams2194f502022-10-16 14:26:09 -0500631@@ -172,11 +198,6 @@ int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400632 unsigned long start);
633 int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
634
635-int optee_from_msg_param(struct tee_param *params, size_t num_params,
636- const struct optee_msg_param *msg_params);
637-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
638- const struct tee_param *params);
639-
640 u64 *optee_allocate_pages_list(size_t num_entries);
641 void optee_free_pages_list(void *array, size_t num_entries);
642 void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
643diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
Patrick Williams2194f502022-10-16 14:26:09 -0500644index efbaff7ad7e5..309258d47790 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400645--- a/drivers/tee/optee/rpc.c
646+++ b/drivers/tee/optee/rpc.c
647@@ -1,6 +1,6 @@
648 // SPDX-License-Identifier: GPL-2.0-only
649 /*
650- * Copyright (c) 2015-2016, Linaro Limited
651+ * Copyright (c) 2015-2021, Linaro Limited
652 */
653
654 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
655@@ -55,6 +55,7 @@ static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
656 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
657 struct optee_msg_arg *arg)
658 {
659+ struct optee *optee = tee_get_drvdata(ctx->teedev);
660 struct tee_param *params;
661 struct i2c_adapter *adapter;
662 struct i2c_msg msg = { };
663@@ -79,7 +80,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
664 return;
665 }
666
667- if (optee_from_msg_param(params, arg->num_params, arg->params))
668+ if (optee->ops->from_msg_param(optee, params, arg->num_params,
669+ arg->params))
670 goto bad;
671
672 for (i = 0; i < arg->num_params; i++) {
673@@ -122,7 +124,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
674 arg->ret = TEEC_ERROR_COMMUNICATION;
675 } else {
676 params[3].u.value.a = msg.len;
677- if (optee_to_msg_param(arg->params, arg->num_params, params))
678+ if (optee->ops->to_msg_param(optee, arg->params,
679+ arg->num_params, params))
680 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
681 else
682 arg->ret = TEEC_SUCCESS;
683@@ -234,7 +237,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
684 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
685 }
686
687-static void handle_rpc_supp_cmd(struct tee_context *ctx,
688+static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
689 struct optee_msg_arg *arg)
690 {
691 struct tee_param *params;
692@@ -248,14 +251,16 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx,
693 return;
694 }
695
696- if (optee_from_msg_param(params, arg->num_params, arg->params)) {
697+ if (optee->ops->from_msg_param(optee, params, arg->num_params,
698+ arg->params)) {
699 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
700 goto out;
701 }
702
703 arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
704
705- if (optee_to_msg_param(arg->params, arg->num_params, params))
706+ if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
707+ params))
708 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
709 out:
710 kfree(params);
711@@ -480,7 +485,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
712 handle_rpc_func_cmd_i2c_transfer(ctx, arg);
713 break;
714 default:
715- handle_rpc_supp_cmd(ctx, arg);
716+ handle_rpc_supp_cmd(ctx, optee, arg);
717 }
718 }
719
720--
Patrick Williams2194f502022-10-16 14:26:09 -05007212.34.1
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400722