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/slab.h>
11 #include <linux/tee_drv.h>
12 #include "optee_private.h"
13 #include "optee_rpc_cmd.h"
14
15 struct wq_entry {
16 struct list_head link;
17 struct completion c;
18 u32 key;
19 };
20
optee_wait_queue_init(struct optee_wait_queue * priv)21 void optee_wait_queue_init(struct optee_wait_queue *priv)
22 {
23 mutex_init(&priv->mu);
24 INIT_LIST_HEAD(&priv->db);
25 }
26
optee_wait_queue_exit(struct optee_wait_queue * priv)27 void optee_wait_queue_exit(struct optee_wait_queue *priv)
28 {
29 mutex_destroy(&priv->mu);
30 }
31
handle_rpc_func_cmd_get_time(struct optee_msg_arg * arg)32 static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
33 {
34 struct timespec64 ts;
35
36 if (arg->num_params != 1)
37 goto bad;
38 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
39 OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT)
40 goto bad;
41
42 ktime_get_real_ts64(&ts);
43 arg->params[0].u.value.a = ts.tv_sec;
44 arg->params[0].u.value.b = ts.tv_nsec;
45
46 arg->ret = TEEC_SUCCESS;
47 return;
48 bad:
49 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
50 }
51
52 #if IS_REACHABLE(CONFIG_I2C)
handle_rpc_func_cmd_i2c_transfer(struct tee_context * ctx,struct optee_msg_arg * arg)53 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
54 struct optee_msg_arg *arg)
55 {
56 struct optee *optee = tee_get_drvdata(ctx->teedev);
57 struct tee_param *params;
58 struct i2c_adapter *adapter;
59 struct i2c_msg msg = { };
60 size_t i;
61 int ret = -EOPNOTSUPP;
62 u8 attr[] = {
63 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
64 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
65 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
66 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT,
67 };
68
69 if (arg->num_params != ARRAY_SIZE(attr)) {
70 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
71 return;
72 }
73
74 params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
75 GFP_KERNEL);
76 if (!params) {
77 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
78 return;
79 }
80
81 if (optee->ops->from_msg_param(optee, params, arg->num_params,
82 arg->params))
83 goto bad;
84
85 for (i = 0; i < arg->num_params; i++) {
86 if (params[i].attr != attr[i])
87 goto bad;
88 }
89
90 adapter = i2c_get_adapter(params[0].u.value.b);
91 if (!adapter)
92 goto bad;
93
94 if (params[1].u.value.a & OPTEE_RPC_I2C_FLAGS_TEN_BIT) {
95 if (!i2c_check_functionality(adapter,
96 I2C_FUNC_10BIT_ADDR)) {
97 i2c_put_adapter(adapter);
98 goto bad;
99 }
100
101 msg.flags = I2C_M_TEN;
102 }
103
104 msg.addr = params[0].u.value.c;
105 msg.buf = params[2].u.memref.shm->kaddr;
106 msg.len = params[2].u.memref.size;
107
108 switch (params[0].u.value.a) {
109 case OPTEE_RPC_I2C_TRANSFER_RD:
110 msg.flags |= I2C_M_RD;
111 break;
112 case OPTEE_RPC_I2C_TRANSFER_WR:
113 break;
114 default:
115 i2c_put_adapter(adapter);
116 goto bad;
117 }
118
119 ret = i2c_transfer(adapter, &msg, 1);
120
121 if (ret < 0) {
122 arg->ret = TEEC_ERROR_COMMUNICATION;
123 } else {
124 params[3].u.value.a = msg.len;
125 if (optee->ops->to_msg_param(optee, arg->params,
126 arg->num_params, params))
127 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
128 else
129 arg->ret = TEEC_SUCCESS;
130 }
131
132 i2c_put_adapter(adapter);
133 kfree(params);
134 return;
135 bad:
136 kfree(params);
137 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
138 }
139 #else
handle_rpc_func_cmd_i2c_transfer(struct tee_context * ctx,struct optee_msg_arg * arg)140 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
141 struct optee_msg_arg *arg)
142 {
143 arg->ret = TEEC_ERROR_NOT_SUPPORTED;
144 }
145 #endif
146
wq_entry_get(struct optee_wait_queue * wq,u32 key)147 static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
148 {
149 struct wq_entry *w;
150
151 mutex_lock(&wq->mu);
152
153 list_for_each_entry(w, &wq->db, link)
154 if (w->key == key)
155 goto out;
156
157 w = kmalloc(sizeof(*w), GFP_KERNEL);
158 if (w) {
159 init_completion(&w->c);
160 w->key = key;
161 list_add_tail(&w->link, &wq->db);
162 }
163 out:
164 mutex_unlock(&wq->mu);
165 return w;
166 }
167
wq_sleep(struct optee_wait_queue * wq,u32 key)168 static void wq_sleep(struct optee_wait_queue *wq, u32 key)
169 {
170 struct wq_entry *w = wq_entry_get(wq, key);
171
172 if (w) {
173 wait_for_completion(&w->c);
174 mutex_lock(&wq->mu);
175 list_del(&w->link);
176 mutex_unlock(&wq->mu);
177 kfree(w);
178 }
179 }
180
wq_wakeup(struct optee_wait_queue * wq,u32 key)181 static void wq_wakeup(struct optee_wait_queue *wq, u32 key)
182 {
183 struct wq_entry *w = wq_entry_get(wq, key);
184
185 if (w)
186 complete(&w->c);
187 }
188
handle_rpc_func_cmd_wq(struct optee * optee,struct optee_msg_arg * arg)189 static void handle_rpc_func_cmd_wq(struct optee *optee,
190 struct optee_msg_arg *arg)
191 {
192 if (arg->num_params != 1)
193 goto bad;
194
195 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
196 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
197 goto bad;
198
199 switch (arg->params[0].u.value.a) {
200 case OPTEE_RPC_WAIT_QUEUE_SLEEP:
201 wq_sleep(&optee->wait_queue, arg->params[0].u.value.b);
202 break;
203 case OPTEE_RPC_WAIT_QUEUE_WAKEUP:
204 wq_wakeup(&optee->wait_queue, arg->params[0].u.value.b);
205 break;
206 default:
207 goto bad;
208 }
209
210 arg->ret = TEEC_SUCCESS;
211 return;
212 bad:
213 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
214 }
215
handle_rpc_func_cmd_wait(struct optee_msg_arg * arg)216 static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
217 {
218 u32 msec_to_wait;
219
220 if (arg->num_params != 1)
221 goto bad;
222
223 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
224 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
225 goto bad;
226
227 msec_to_wait = arg->params[0].u.value.a;
228
229 /* Go to interruptible sleep */
230 msleep_interruptible(msec_to_wait);
231
232 arg->ret = TEEC_SUCCESS;
233 return;
234 bad:
235 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
236 }
237
handle_rpc_supp_cmd(struct tee_context * ctx,struct optee * optee,struct optee_msg_arg * arg)238 static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
239 struct optee_msg_arg *arg)
240 {
241 struct tee_param *params;
242
243 arg->ret_origin = TEEC_ORIGIN_COMMS;
244
245 params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
246 GFP_KERNEL);
247 if (!params) {
248 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
249 return;
250 }
251
252 if (optee->ops->from_msg_param(optee, params, arg->num_params,
253 arg->params)) {
254 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
255 goto out;
256 }
257
258 arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
259
260 if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
261 params))
262 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
263 out:
264 kfree(params);
265 }
266
optee_rpc_cmd_alloc_suppl(struct tee_context * ctx,size_t sz)267 struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
268 {
269 u32 ret;
270 struct tee_param param;
271 struct optee *optee = tee_get_drvdata(ctx->teedev);
272 struct tee_shm *shm;
273
274 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
275 param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
276 param.u.value.b = sz;
277 param.u.value.c = 0;
278
279 ret = optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_ALLOC, 1, ¶m);
280 if (ret)
281 return ERR_PTR(-ENOMEM);
282
283 mutex_lock(&optee->supp.mutex);
284 /* Increases count as secure world doesn't have a reference */
285 shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
286 mutex_unlock(&optee->supp.mutex);
287 return shm;
288 }
289
optee_rpc_cmd_free_suppl(struct tee_context * ctx,struct tee_shm * shm)290 void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
291 {
292 struct tee_param param;
293
294 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
295 param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
296 param.u.value.b = tee_shm_get_id(shm);
297 param.u.value.c = 0;
298
299 /*
300 * Match the tee_shm_get_from_id() in cmd_alloc_suppl() as secure
301 * world has released its reference.
302 *
303 * It's better to do this before sending the request to supplicant
304 * as we'd like to let the process doing the initial allocation to
305 * do release the last reference too in order to avoid stacking
306 * many pending fput() on the client process. This could otherwise
307 * happen if secure world does many allocate and free in a single
308 * invoke.
309 */
310 tee_shm_put(shm);
311
312 optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, ¶m);
313 }
314
optee_rpc_cmd(struct tee_context * ctx,struct optee * optee,struct optee_msg_arg * arg)315 void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
316 struct optee_msg_arg *arg)
317 {
318 switch (arg->cmd) {
319 case OPTEE_RPC_CMD_GET_TIME:
320 handle_rpc_func_cmd_get_time(arg);
321 break;
322 case OPTEE_RPC_CMD_WAIT_QUEUE:
323 handle_rpc_func_cmd_wq(optee, arg);
324 break;
325 case OPTEE_RPC_CMD_SUSPEND:
326 handle_rpc_func_cmd_wait(arg);
327 break;
328 case OPTEE_RPC_CMD_I2C_TRANSFER:
329 handle_rpc_func_cmd_i2c_transfer(ctx, arg);
330 break;
331 default:
332 handle_rpc_supp_cmd(ctx, optee, arg);
333 }
334 }
335
336
337