]> Git Repo - linux.git/blob - drivers/tee/optee/rpc.c
Linux 6.14-rc3
[linux.git] / drivers / tee / optee / rpc.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015-2021, Linaro Limited
4  */
5
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7
8 #include <linux/delay.h>
9 #include <linux/i2c.h>
10 #include <linux/rpmb.h>
11 #include <linux/slab.h>
12 #include <linux/tee_core.h>
13 #include "optee_private.h"
14 #include "optee_rpc_cmd.h"
15
16 static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
17 {
18         struct timespec64 ts;
19
20         if (arg->num_params != 1)
21                 goto bad;
22         if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
23                         OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT)
24                 goto bad;
25
26         ktime_get_real_ts64(&ts);
27         arg->params[0].u.value.a = ts.tv_sec;
28         arg->params[0].u.value.b = ts.tv_nsec;
29
30         arg->ret = TEEC_SUCCESS;
31         return;
32 bad:
33         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
34 }
35
36 #if IS_REACHABLE(CONFIG_I2C)
37 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
38                                              struct optee_msg_arg *arg)
39 {
40         struct optee *optee = tee_get_drvdata(ctx->teedev);
41         struct tee_param *params;
42         struct i2c_adapter *adapter;
43         struct i2c_msg msg = { };
44         size_t i;
45         int ret = -EOPNOTSUPP;
46         u8 attr[] = {
47                 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
48                 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
49                 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
50                 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT,
51         };
52
53         if (arg->num_params != ARRAY_SIZE(attr)) {
54                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
55                 return;
56         }
57
58         params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
59                                GFP_KERNEL);
60         if (!params) {
61                 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
62                 return;
63         }
64
65         if (optee->ops->from_msg_param(optee, params, arg->num_params,
66                                        arg->params))
67                 goto bad;
68
69         for (i = 0; i < arg->num_params; i++) {
70                 if (params[i].attr != attr[i])
71                         goto bad;
72         }
73
74         adapter = i2c_get_adapter(params[0].u.value.b);
75         if (!adapter)
76                 goto bad;
77
78         if (params[1].u.value.a & OPTEE_RPC_I2C_FLAGS_TEN_BIT) {
79                 if (!i2c_check_functionality(adapter,
80                                              I2C_FUNC_10BIT_ADDR)) {
81                         i2c_put_adapter(adapter);
82                         goto bad;
83                 }
84
85                 msg.flags = I2C_M_TEN;
86         }
87
88         msg.addr = params[0].u.value.c;
89         msg.buf  = params[2].u.memref.shm->kaddr;
90         msg.len  = params[2].u.memref.size;
91
92         switch (params[0].u.value.a) {
93         case OPTEE_RPC_I2C_TRANSFER_RD:
94                 msg.flags |= I2C_M_RD;
95                 break;
96         case OPTEE_RPC_I2C_TRANSFER_WR:
97                 break;
98         default:
99                 i2c_put_adapter(adapter);
100                 goto bad;
101         }
102
103         ret = i2c_transfer(adapter, &msg, 1);
104
105         if (ret < 0) {
106                 arg->ret = TEEC_ERROR_COMMUNICATION;
107         } else {
108                 params[3].u.value.a = msg.len;
109                 if (optee->ops->to_msg_param(optee, arg->params,
110                                              arg->num_params, params))
111                         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
112                 else
113                         arg->ret = TEEC_SUCCESS;
114         }
115
116         i2c_put_adapter(adapter);
117         kfree(params);
118         return;
119 bad:
120         kfree(params);
121         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
122 }
123 #else
124 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
125                                              struct optee_msg_arg *arg)
126 {
127         arg->ret = TEEC_ERROR_NOT_SUPPORTED;
128 }
129 #endif
130
131 static void handle_rpc_func_cmd_wq(struct optee *optee,
132                                    struct optee_msg_arg *arg)
133 {
134         int rc = 0;
135
136         if (arg->num_params != 1)
137                 goto bad;
138
139         if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
140                         OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
141                 goto bad;
142
143         switch (arg->params[0].u.value.a) {
144         case OPTEE_RPC_NOTIFICATION_WAIT:
145                 rc = optee_notif_wait(optee, arg->params[0].u.value.b, arg->params[0].u.value.c);
146                 if (rc)
147                         goto bad;
148                 break;
149         case OPTEE_RPC_NOTIFICATION_SEND:
150                 if (optee_notif_send(optee, arg->params[0].u.value.b))
151                         goto bad;
152                 break;
153         default:
154                 goto bad;
155         }
156
157         arg->ret = TEEC_SUCCESS;
158         return;
159 bad:
160         if (rc == -ETIMEDOUT)
161                 arg->ret = TEE_ERROR_TIMEOUT;
162         else
163                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
164 }
165
166 static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
167 {
168         u32 msec_to_wait;
169
170         if (arg->num_params != 1)
171                 goto bad;
172
173         if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
174                         OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
175                 goto bad;
176
177         msec_to_wait = arg->params[0].u.value.a;
178
179         /* Go to interruptible sleep */
180         msleep_interruptible(msec_to_wait);
181
182         arg->ret = TEEC_SUCCESS;
183         return;
184 bad:
185         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
186 }
187
188 static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
189                                 struct optee_msg_arg *arg)
190 {
191         struct tee_param *params;
192
193         arg->ret_origin = TEEC_ORIGIN_COMMS;
194
195         params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
196                                GFP_KERNEL);
197         if (!params) {
198                 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
199                 return;
200         }
201
202         if (optee->ops->from_msg_param(optee, params, arg->num_params,
203                                        arg->params)) {
204                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
205                 goto out;
206         }
207
208         arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
209
210         if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
211                                      params))
212                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
213 out:
214         kfree(params);
215 }
216
217 struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
218 {
219         u32 ret;
220         struct tee_param param;
221         struct optee *optee = tee_get_drvdata(ctx->teedev);
222         struct tee_shm *shm;
223
224         param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
225         param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
226         param.u.value.b = sz;
227         param.u.value.c = 0;
228
229         ret = optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_ALLOC, 1, &param);
230         if (ret)
231                 return ERR_PTR(-ENOMEM);
232
233         mutex_lock(&optee->supp.mutex);
234         /* Increases count as secure world doesn't have a reference */
235         shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
236         mutex_unlock(&optee->supp.mutex);
237         return shm;
238 }
239
240 void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
241 {
242         struct tee_param param;
243
244         param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
245         param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
246         param.u.value.b = tee_shm_get_id(shm);
247         param.u.value.c = 0;
248
249         /*
250          * Match the tee_shm_get_from_id() in cmd_alloc_suppl() as secure
251          * world has released its reference.
252          *
253          * It's better to do this before sending the request to supplicant
254          * as we'd like to let the process doing the initial allocation to
255          * do release the last reference too in order to avoid stacking
256          * many pending fput() on the client process. This could otherwise
257          * happen if secure world does many allocate and free in a single
258          * invoke.
259          */
260         tee_shm_put(shm);
261
262         optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, &param);
263 }
264
265 static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
266                                              struct optee *optee,
267                                              struct optee_msg_arg *arg)
268 {
269         struct tee_param params[1];
270
271         if (arg->num_params != ARRAY_SIZE(params) ||
272             optee->ops->from_msg_param(optee, params, arg->num_params,
273                                        arg->params) ||
274             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
275                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
276                 return;
277         }
278
279         params[0].u.value.a = OPTEE_RPC_SHM_TYPE_KERNEL;
280         params[0].u.value.b = 0;
281         params[0].u.value.c = 0;
282         if (optee->ops->to_msg_param(optee, arg->params,
283                                      arg->num_params, params)) {
284                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
285                 return;
286         }
287
288         mutex_lock(&optee->rpmb_dev_mutex);
289         rpmb_dev_put(optee->rpmb_dev);
290         optee->rpmb_dev = NULL;
291         mutex_unlock(&optee->rpmb_dev_mutex);
292
293         arg->ret = TEEC_SUCCESS;
294 }
295
296 static int rpmb_type_to_rpc_type(enum rpmb_type rtype)
297 {
298         switch (rtype) {
299         case RPMB_TYPE_EMMC:
300                 return OPTEE_RPC_RPMB_EMMC;
301         case RPMB_TYPE_UFS:
302                 return OPTEE_RPC_RPMB_UFS;
303         case RPMB_TYPE_NVME:
304                 return OPTEE_RPC_RPMB_NVME;
305         default:
306                 return -1;
307         }
308 }
309
310 static int rpc_rpmb_match(struct device *dev, const void *data)
311 {
312         struct rpmb_dev *rdev = to_rpmb_dev(dev);
313
314         return rpmb_type_to_rpc_type(rdev->descr.type) >= 0;
315 }
316
317 static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
318                                             struct optee *optee,
319                                             struct optee_msg_arg *arg)
320 {
321         struct rpmb_dev *rdev;
322         struct tee_param params[2];
323         void *buf;
324
325         if (arg->num_params != ARRAY_SIZE(params) ||
326             optee->ops->from_msg_param(optee, params, arg->num_params,
327                                        arg->params) ||
328             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
329             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
330                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
331                 return;
332         }
333         buf = tee_shm_get_va(params[1].u.memref.shm,
334                              params[1].u.memref.shm_offs);
335         if (IS_ERR(buf)) {
336                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
337                 return;
338         }
339
340         mutex_lock(&optee->rpmb_dev_mutex);
341         rdev = rpmb_dev_find_device(NULL, optee->rpmb_dev, rpc_rpmb_match);
342         rpmb_dev_put(optee->rpmb_dev);
343         optee->rpmb_dev = rdev;
344         mutex_unlock(&optee->rpmb_dev_mutex);
345
346         if (!rdev) {
347                 arg->ret = TEEC_ERROR_ITEM_NOT_FOUND;
348                 return;
349         }
350
351         if (params[1].u.memref.size < rdev->descr.dev_id_len) {
352                 arg->ret = TEEC_ERROR_SHORT_BUFFER;
353                 return;
354         }
355         memcpy(buf, rdev->descr.dev_id, rdev->descr.dev_id_len);
356         params[1].u.memref.size = rdev->descr.dev_id_len;
357         params[0].u.value.a = rpmb_type_to_rpc_type(rdev->descr.type);
358         params[0].u.value.b = rdev->descr.capacity;
359         params[0].u.value.c = rdev->descr.reliable_wr_count;
360         if (optee->ops->to_msg_param(optee, arg->params,
361                                      arg->num_params, params)) {
362                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
363                 return;
364         }
365
366         arg->ret = TEEC_SUCCESS;
367 }
368
369 static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
370                                         struct optee *optee,
371                                         struct optee_msg_arg *arg)
372 {
373         struct tee_param params[2];
374         struct rpmb_dev *rdev;
375         void *p0, *p1;
376
377         mutex_lock(&optee->rpmb_dev_mutex);
378         rdev = rpmb_dev_get(optee->rpmb_dev);
379         mutex_unlock(&optee->rpmb_dev_mutex);
380         if (!rdev) {
381                 arg->ret = TEEC_ERROR_ITEM_NOT_FOUND;
382                 return;
383         }
384
385         if (arg->num_params != ARRAY_SIZE(params) ||
386             optee->ops->from_msg_param(optee, params, arg->num_params,
387                                        arg->params) ||
388             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
389             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
390                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
391                 goto out;
392         }
393
394         p0 = tee_shm_get_va(params[0].u.memref.shm,
395                             params[0].u.memref.shm_offs);
396         p1 = tee_shm_get_va(params[1].u.memref.shm,
397                             params[1].u.memref.shm_offs);
398         if (rpmb_route_frames(rdev, p0, params[0].u.memref.size, p1,
399                               params[1].u.memref.size)) {
400                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
401                 goto out;
402         }
403         if (optee->ops->to_msg_param(optee, arg->params,
404                                      arg->num_params, params)) {
405                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
406                 goto out;
407         }
408         arg->ret = TEEC_SUCCESS;
409 out:
410         rpmb_dev_put(rdev);
411 }
412
413 void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
414                    struct optee_msg_arg *arg)
415 {
416         switch (arg->cmd) {
417         case OPTEE_RPC_CMD_GET_TIME:
418                 handle_rpc_func_cmd_get_time(arg);
419                 break;
420         case OPTEE_RPC_CMD_NOTIFICATION:
421                 handle_rpc_func_cmd_wq(optee, arg);
422                 break;
423         case OPTEE_RPC_CMD_SUSPEND:
424                 handle_rpc_func_cmd_wait(arg);
425                 break;
426         case OPTEE_RPC_CMD_I2C_TRANSFER:
427                 handle_rpc_func_cmd_i2c_transfer(ctx, arg);
428                 break;
429         /*
430          * optee->in_kernel_rpmb_routing true means that OP-TEE supports
431          * in-kernel RPMB routing _and_ that the RPMB subsystem is
432          * reachable. This is reported to user space with
433          * rpmb_routing_model=kernel in sysfs.
434          *
435          * rpmb_routing_model=kernel is also a promise to user space that
436          * RPMB access will not require supplicant support, hence the
437          * checks below.
438          */
439         case OPTEE_RPC_CMD_RPMB_PROBE_RESET:
440                 if (optee->in_kernel_rpmb_routing)
441                         handle_rpc_func_rpmb_probe_reset(ctx, optee, arg);
442                 else
443                         handle_rpc_supp_cmd(ctx, optee, arg);
444                 break;
445         case OPTEE_RPC_CMD_RPMB_PROBE_NEXT:
446                 if (optee->in_kernel_rpmb_routing)
447                         handle_rpc_func_rpmb_probe_next(ctx, optee, arg);
448                 else
449                         handle_rpc_supp_cmd(ctx, optee, arg);
450                 break;
451         case OPTEE_RPC_CMD_RPMB_FRAMES:
452                 if (optee->in_kernel_rpmb_routing)
453                         handle_rpc_func_rpmb_frames(ctx, optee, arg);
454                 else
455                         handle_rpc_supp_cmd(ctx, optee, arg);
456                 break;
457         default:
458                 handle_rpc_supp_cmd(ctx, optee, arg);
459         }
460 }
461
462
This page took 0.055739 seconds and 4 git commands to generate.