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