xref: /openbmc/linux/drivers/tee/optee/rpc.c (revision 240e6d25)
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 
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 
27 void optee_wait_queue_exit(struct optee_wait_queue *priv)
28 {
29 	mutex_destroy(&priv->mu);
30 }
31 
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)
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
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 
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 
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 
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 
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 
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 
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 
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, &param);
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 
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, &param);
313 }
314 
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