xref: /linux/drivers/tee/qcomtee/call.c (revision d6e290837e50f73f88f31f19bd8a7213d92e6e46)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4  */
5 
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7 
8 #include <linux/slab.h>
9 #include <linux/tee.h>
10 #include <linux/platform_device.h>
11 #include <linux/xarray.h>
12 
13 #include "qcomtee.h"
14 
15 static int find_qtee_object(struct qcomtee_object **object, unsigned long id,
16 			    struct qcomtee_context_data *ctxdata)
17 {
18 	int err = 0;
19 
20 	guard(rcu)();
21 	/* Object release is RCU protected. */
22 	*object = idr_find(&ctxdata->qtee_objects_idr, id);
23 	if (!qcomtee_object_get(*object))
24 		err = -EINVAL;
25 
26 	return err;
27 }
28 
29 static void del_qtee_object(unsigned long id,
30 			    struct qcomtee_context_data *ctxdata)
31 {
32 	struct qcomtee_object *object;
33 
34 	scoped_guard(mutex, &ctxdata->qtee_lock)
35 		object = idr_remove(&ctxdata->qtee_objects_idr, id);
36 
37 	qcomtee_object_put(object);
38 }
39 
40 /**
41  * qcomtee_context_add_qtee_object() - Add a QTEE object to the context.
42  * @param: TEE parameter representing @object.
43  * @object: QTEE object.
44  * @ctx: context to add the object.
45  *
46  * It assumes @object is %QCOMTEE_OBJECT_TYPE_TEE and the caller has already
47  * issued qcomtee_object_get() for @object.
48  *
49  * Return: On success, returns 0; on failure, returns < 0.
50  */
51 int qcomtee_context_add_qtee_object(struct tee_param *param,
52 				    struct qcomtee_object *object,
53 				    struct tee_context *ctx)
54 {
55 	int ret;
56 	struct qcomtee_context_data *ctxdata = ctx->data;
57 
58 	scoped_guard(mutex, &ctxdata->qtee_lock)
59 		ret = idr_alloc(&ctxdata->qtee_objects_idr, object, 0, 0,
60 				GFP_KERNEL);
61 	if (ret < 0)
62 		return ret;
63 
64 	param->u.objref.id = ret;
65 	/* QTEE Object: QCOMTEE_OBJREF_FLAG_TEE set. */
66 	param->u.objref.flags = QCOMTEE_OBJREF_FLAG_TEE;
67 
68 	return 0;
69 }
70 
71 /* Retrieve the QTEE object added with qcomtee_context_add_qtee_object(). */
72 int qcomtee_context_find_qtee_object(struct qcomtee_object **object,
73 				     struct tee_param *param,
74 				     struct tee_context *ctx)
75 {
76 	struct qcomtee_context_data *ctxdata = ctx->data;
77 
78 	return find_qtee_object(object, param->u.objref.id, ctxdata);
79 }
80 
81 /**
82  * qcomtee_context_del_qtee_object() - Delete a QTEE object from the context.
83  * @param: TEE parameter representing @object.
84  * @ctx: context for deleting the object.
85  *
86  * The @param has been initialized by qcomtee_context_add_qtee_object().
87  */
88 void qcomtee_context_del_qtee_object(struct tee_param *param,
89 				     struct tee_context *ctx)
90 {
91 	struct qcomtee_context_data *ctxdata = ctx->data;
92 	/* 'qtee_objects_idr' stores QTEE objects only. */
93 	if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_TEE)
94 		del_qtee_object(param->u.objref.id, ctxdata);
95 }
96 
97 /**
98  * qcomtee_objref_to_arg() - Convert OBJREF parameter to QTEE argument.
99  * @arg: QTEE argument.
100  * @param: TEE parameter.
101  * @ctx: context in which the conversion should happen.
102  *
103  * It assumes @param is an OBJREF.
104  * It does not set @arg.type; the caller should initialize it to a correct
105  * &enum qcomtee_arg_type value. It gets the object's refcount in @arg;
106  * the caller should manage to put it afterward.
107  *
108  * Return: On success, returns 0; on failure, returns < 0.
109  */
110 int qcomtee_objref_to_arg(struct qcomtee_arg *arg, struct tee_param *param,
111 			  struct tee_context *ctx)
112 {
113 	int err = -EINVAL;
114 
115 	arg->o = NULL_QCOMTEE_OBJECT;
116 	/* param is a NULL object: */
117 	if (param->u.objref.id == TEE_OBJREF_NULL)
118 		return 0;
119 
120 	/* param is a callback object: */
121 	if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_USER)
122 		err =  qcomtee_user_param_to_object(&arg->o, param, ctx);
123 	/* param is a QTEE object: */
124 	else if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_TEE)
125 		err =  qcomtee_context_find_qtee_object(&arg->o, param, ctx);
126 
127 	/*
128 	 * For callback objects, call qcomtee_object_get() to keep a temporary
129 	 * copy for the driver, as these objects are released asynchronously
130 	 * and may disappear even before returning from QTEE.
131 	 *
132 	 *  - For direct object invocations, the matching put is called in
133 	 *    qcomtee_object_invoke() when parsing the QTEE response.
134 	 *  - For callback responses, put is called in qcomtee_user_object_notify()
135 	 *    after QTEE has received its copies.
136 	 */
137 
138 	if (!err && (typeof_qcomtee_object(arg->o) == QCOMTEE_OBJECT_TYPE_CB))
139 		qcomtee_object_get(arg->o);
140 
141 	return err;
142 }
143 
144 /**
145  * qcomtee_objref_from_arg() - Convert QTEE argument to OBJREF param.
146  * @param: TEE parameter.
147  * @arg: QTEE argument.
148  * @ctx: context in which the conversion should happen.
149  *
150  * It assumes @arg is of %QCOMTEE_ARG_TYPE_IO or %QCOMTEE_ARG_TYPE_OO.
151  * It does not set @param.attr; the caller should initialize it to a
152  * correct type.
153  *
154  * Return: On success, returns 0; on failure, returns < 0.
155  */
156 int qcomtee_objref_from_arg(struct tee_param *param, struct qcomtee_arg *arg,
157 			    struct tee_context *ctx)
158 {
159 	struct qcomtee_object *object = arg->o;
160 
161 	switch (typeof_qcomtee_object(object)) {
162 	case QCOMTEE_OBJECT_TYPE_NULL:
163 		param->u.objref.id = TEE_OBJREF_NULL;
164 
165 		return 0;
166 	case QCOMTEE_OBJECT_TYPE_CB:
167 		/* object is a callback object: */
168 		if (is_qcomtee_user_object(object))
169 			return qcomtee_user_param_from_object(param, object,
170 							      ctx);
171 
172 		break;
173 	case QCOMTEE_OBJECT_TYPE_TEE:
174 		return qcomtee_context_add_qtee_object(param, object, ctx);
175 
176 	case QCOMTEE_OBJECT_TYPE_ROOT:
177 	default:
178 		break;
179 	}
180 
181 	return -EINVAL;
182 }
183 
184 /**
185  * qcomtee_params_to_args() - Convert TEE parameters to QTEE arguments.
186  * @u: QTEE arguments.
187  * @params: TEE parameters.
188  * @num_params: number of elements in the parameter array.
189  * @ctx: context in which the conversion should happen.
190  *
191  * It assumes @u has at least @num_params + 1 entries and has been initialized
192  * with %QCOMTEE_ARG_TYPE_INV as &struct qcomtee_arg.type.
193  *
194  * Return: On success, returns 0; on failure, returns < 0.
195  */
196 static int qcomtee_params_to_args(struct qcomtee_arg *u,
197 				  struct tee_param *params, int num_params,
198 				  struct tee_context *ctx)
199 {
200 	int i;
201 
202 	for (i = 0; i < num_params; i++) {
203 		switch (params[i].attr) {
204 		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
205 		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
206 			u[i].flags = QCOMTEE_ARG_FLAGS_UADDR;
207 			u[i].b.uaddr = params[i].u.ubuf.uaddr;
208 			u[i].b.size = params[i].u.ubuf.size;
209 
210 			if (params[i].attr ==
211 			    TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT)
212 				u[i].type = QCOMTEE_ARG_TYPE_IB;
213 			else /* TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT */
214 				u[i].type = QCOMTEE_ARG_TYPE_OB;
215 
216 			break;
217 		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
218 			u[i].type = QCOMTEE_ARG_TYPE_IO;
219 			if (qcomtee_objref_to_arg(&u[i], &params[i], ctx))
220 				goto out_failed;
221 
222 			break;
223 		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
224 			u[i].type = QCOMTEE_ARG_TYPE_OO;
225 			u[i].o = NULL_QCOMTEE_OBJECT;
226 			break;
227 		default:
228 			goto out_failed;
229 		}
230 	}
231 
232 	return 0;
233 
234 out_failed:
235 	/* Undo qcomtee_objref_to_arg(). */
236 	for (i--; i >= 0; i--) {
237 		if (u[i].type != QCOMTEE_ARG_TYPE_IO)
238 			continue;
239 
240 		qcomtee_user_object_set_notify(u[i].o, false);
241 		/* See docs for qcomtee_objref_to_arg() for double put. */
242 		if (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB)
243 			qcomtee_object_put(u[i].o);
244 
245 		qcomtee_object_put(u[i].o);
246 	}
247 
248 	return -EINVAL;
249 }
250 
251 /**
252  * qcomtee_params_from_args() - Convert QTEE arguments to TEE parameters.
253  * @params: TEE parameters.
254  * @u: QTEE arguments.
255  * @num_params: number of elements in the parameter array.
256  * @ctx: context in which the conversion should happen.
257  *
258  * @u should have already been initialized by qcomtee_params_to_args().
259  * This also represents the end of a QTEE invocation that started with
260  * qcomtee_params_to_args() by releasing %QCOMTEE_ARG_TYPE_IO objects.
261  *
262  * Return: On success, returns 0; on failure, returns < 0.
263  */
264 static int qcomtee_params_from_args(struct tee_param *params,
265 				    struct qcomtee_arg *u, int num_params,
266 				    struct tee_context *ctx)
267 {
268 	int i, np;
269 
270 	qcomtee_arg_for_each(np, u) {
271 		switch (u[np].type) {
272 		case QCOMTEE_ARG_TYPE_OB:
273 			/* TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT */
274 			params[np].u.ubuf.size = u[np].b.size;
275 
276 			break;
277 		case QCOMTEE_ARG_TYPE_IO:
278 			/* IEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT */
279 			qcomtee_object_put(u[np].o);
280 
281 			break;
282 		case QCOMTEE_ARG_TYPE_OO:
283 			/* TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT */
284 			if (qcomtee_objref_from_arg(&params[np], &u[np], ctx))
285 				goto out_failed;
286 
287 			break;
288 		case QCOMTEE_ARG_TYPE_IB:
289 		default:
290 			break;
291 		}
292 	}
293 
294 	return 0;
295 
296 out_failed:
297 	/* Undo qcomtee_objref_from_arg(). */
298 	for (i = 0; i < np; i++) {
299 		if (params[i].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT)
300 			qcomtee_context_del_qtee_object(&params[i], ctx);
301 	}
302 
303 	/* Release any IO and OO objects not processed. */
304 	for (; u[i].type && i < num_params; i++) {
305 		if (u[i].type == QCOMTEE_ARG_TYPE_OO ||
306 		    u[i].type == QCOMTEE_ARG_TYPE_IO)
307 			qcomtee_object_put(u[i].o);
308 	}
309 
310 	return -EINVAL;
311 }
312 
313 /* TEE Device Ops. */
314 
315 static int qcomtee_params_check(struct tee_param *params, int num_params)
316 {
317 	int io = 0, oo = 0, ib = 0, ob = 0;
318 	int i;
319 
320 	/* QTEE can accept 64 arguments. */
321 	if (num_params > QCOMTEE_ARGS_MAX)
322 		return -EINVAL;
323 
324 	/* Supported parameter types. */
325 	for (i = 0; i < num_params; i++) {
326 		switch (params[i].attr) {
327 		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
328 			ib++;
329 			break;
330 		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
331 			ob++;
332 			break;
333 		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
334 			io++;
335 			break;
336 		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
337 			oo++;
338 			break;
339 		default:
340 			return -EINVAL;
341 		}
342 	}
343 
344 	/*  QTEE can accept 16 arguments of each supported types. */
345 	if (io > QCOMTEE_ARGS_PER_TYPE || oo > QCOMTEE_ARGS_PER_TYPE ||
346 	    ib > QCOMTEE_ARGS_PER_TYPE || ob > QCOMTEE_ARGS_PER_TYPE)
347 		return -EINVAL;
348 
349 	return 0;
350 }
351 
352 /* Check if an operation on ROOT_QCOMTEE_OBJECT from userspace is permitted. */
353 static int qcomtee_root_object_check(u32 op, struct tee_param *params,
354 				     int num_params)
355 {
356 	/* Some privileged operations recognized by QTEE. */
357 	if (op == QCOMTEE_ROOT_OP_NOTIFY_DOMAIN_CHANGE ||
358 	    op == QCOMTEE_ROOT_OP_ADCI_ACCEPT ||
359 	    op == QCOMTEE_ROOT_OP_ADCI_SHUTDOWN)
360 		return -EINVAL;
361 
362 	/*
363 	 * QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS is to register with QTEE
364 	 * by passing a credential object as input OBJREF. TEE_OBJREF_NULL as a
365 	 * credential object represents a privileged client for QTEE and
366 	 * is used by the kernel only.
367 	 */
368 	if (op == QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS && num_params == 2) {
369 		if (params[0].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT &&
370 		    params[1].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT) {
371 			if (params[0].u.objref.id == TEE_OBJREF_NULL)
372 				return -EINVAL;
373 		}
374 	}
375 
376 	return 0;
377 }
378 
379 /**
380  * qcomtee_object_invoke() - Invoke a QTEE object.
381  * @ctx: TEE context.
382  * @arg: ioctl arguments.
383  * @params: parameters for the object.
384  *
385  * Return: On success, returns 0; on failure, returns < 0.
386  */
387 static int qcomtee_object_invoke(struct tee_context *ctx,
388 				 struct tee_ioctl_object_invoke_arg *arg,
389 				 struct tee_param *params)
390 {
391 	struct qcomtee_object_invoke_ctx *oic __free(kfree) = NULL;
392 	struct qcomtee_context_data *ctxdata = ctx->data;
393 	struct qcomtee_arg *u __free(kfree) = NULL;
394 	struct qcomtee_object *object;
395 	int i, ret, result;
396 
397 	if (qcomtee_params_check(params, arg->num_params))
398 		return -EINVAL;
399 
400 	/* First, handle reserved operations: */
401 	if (arg->op == QCOMTEE_MSG_OBJECT_OP_RELEASE) {
402 		del_qtee_object(arg->id, ctxdata);
403 
404 		return 0;
405 	}
406 
407 	/* Otherwise, invoke a QTEE object: */
408 	oic = qcomtee_object_invoke_ctx_alloc(ctx);
409 	if (!oic)
410 		return -ENOMEM;
411 
412 	/* +1 for ending QCOMTEE_ARG_TYPE_INV. */
413 	u = kcalloc(arg->num_params + 1, sizeof(*u), GFP_KERNEL);
414 	if (!u)
415 		return -ENOMEM;
416 
417 	/* Get an object to invoke. */
418 	if (arg->id == TEE_OBJREF_NULL) {
419 		/* Use ROOT if TEE_OBJREF_NULL is invoked. */
420 		if (qcomtee_root_object_check(arg->op, params, arg->num_params))
421 			return -EINVAL;
422 
423 		object = ROOT_QCOMTEE_OBJECT;
424 	} else if (find_qtee_object(&object, arg->id, ctxdata)) {
425 		return -EINVAL;
426 	}
427 
428 	ret = qcomtee_params_to_args(u, params, arg->num_params, ctx);
429 	if (ret)
430 		goto out;
431 
432 	ret = qcomtee_object_do_invoke(oic, object, arg->op, u, &result);
433 	if (ret) {
434 		qcomtee_arg_for_each_input_object(i, u) {
435 			qcomtee_user_object_set_notify(u[i].o, false);
436 			qcomtee_object_put(u[i].o);
437 		}
438 
439 		goto out;
440 	}
441 
442 	/* Prase QTEE response and put driver's object copies: */
443 
444 	if (!result) {
445 		/* Assume service is UNAVAIL if unable to process the result. */
446 		if (qcomtee_params_from_args(params, u, arg->num_params, ctx))
447 			result = QCOMTEE_MSG_ERROR_UNAVAIL;
448 	} else {
449 		/*
450 		 * qcomtee_params_to_args() gets a copy of IO for the driver to
451 		 * make sure they do not get released while in the middle of
452 		 * invocation. On success (!result), qcomtee_params_from_args()
453 		 * puts them; Otherwise, put them here.
454 		 */
455 		qcomtee_arg_for_each_input_object(i, u)
456 			qcomtee_object_put(u[i].o);
457 	}
458 
459 	arg->ret = result;
460 out:
461 	qcomtee_object_put(object);
462 
463 	return ret;
464 }
465 
466 /**
467  * qcomtee_supp_recv() - Wait for a request for the supplicant.
468  * @ctx: TEE context.
469  * @op: requested operation on the object.
470  * @num_params: number of elements in the parameter array.
471  * @params: parameters for @op.
472  *
473  * The first parameter is a meta %TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT.
474  * On input, it provides a user buffer. This buffer is used for parameters of
475  * type %TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT in qcomtee_cb_params_from_args().
476  * On output, the object ID and request ID are stored in the meta parameter.
477  *
478  * @num_params is updated to the number of parameters that actually exist
479  * in @params on return.
480  *
481  * Return: On success, returns 0; on failure, returns < 0.
482  */
483 static int qcomtee_supp_recv(struct tee_context *ctx, u32 *op, u32 *num_params,
484 			     struct tee_param *params)
485 {
486 	struct qcomtee_user_object_request_data data;
487 	void __user *uaddr;
488 	size_t ubuf_size;
489 	int i, ret;
490 
491 	if (!*num_params)
492 		return -EINVAL;
493 
494 	/* First parameter should be an INOUT + meta parameter. */
495 	if (params->attr !=
496 	    (TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT | TEE_IOCTL_PARAM_ATTR_META))
497 		return -EINVAL;
498 
499 	/* Other parameters are none. */
500 	for (i = 1; i < *num_params; i++)
501 		if (params[i].attr)
502 			return -EINVAL;
503 
504 	if (!IS_ALIGNED(params->u.value.a, 8))
505 		return -EINVAL;
506 
507 	/* User buffer and size from meta parameter. */
508 	uaddr = u64_to_user_ptr(params->u.value.a);
509 	ubuf_size = params->u.value.b;
510 	/* Process TEE parameters. +/-1 to ignore the meta parameter. */
511 	ret = qcomtee_user_object_select(ctx, params + 1, *num_params - 1,
512 					 uaddr, ubuf_size, &data);
513 	if (ret)
514 		return ret;
515 
516 	params->u.value.a = data.object_id;
517 	params->u.value.b = data.id;
518 	params->u.value.c = 0;
519 	*op = data.op;
520 	*num_params = data.np + 1;
521 
522 	return 0;
523 }
524 
525 /**
526  * qcomtee_supp_send() - Submit a response for a request.
527  * @ctx: TEE context.
528  * @errno: return value for the request.
529  * @num_params: number of elements in the parameter array.
530  * @params: returned parameters.
531  *
532  * The first parameter is a meta %TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT.
533  * It specifies the request ID this response belongs to.
534  *
535  * Return: On success, returns 0; on failure, returns < 0.
536  */
537 static int qcomtee_supp_send(struct tee_context *ctx, u32 errno, u32 num_params,
538 			     struct tee_param *params)
539 {
540 	int req_id;
541 
542 	if (!num_params)
543 		return -EINVAL;
544 
545 	/* First parameter should be an OUTPUT + meta parameter. */
546 	if (params->attr != (TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT |
547 			     TEE_IOCTL_PARAM_ATTR_META))
548 		return -EINVAL;
549 
550 	req_id = params->u.value.a;
551 	/* Process TEE parameters. +/-1 to ignore the meta parameter. */
552 	return qcomtee_user_object_submit(ctx, params + 1, num_params - 1,
553 					  req_id, errno);
554 }
555 
556 static int qcomtee_open(struct tee_context *ctx)
557 {
558 	struct qcomtee_context_data *ctxdata __free(kfree) = NULL;
559 
560 	ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
561 	if (!ctxdata)
562 		return -ENOMEM;
563 
564 	/*
565 	 * In the QTEE driver, the same context is used to refcount resources
566 	 * shared by QTEE. For example, teedev_ctx_get() is called for any
567 	 * instance of callback objects (see qcomtee_user_param_to_object()).
568 	 *
569 	 * Maintain a copy of teedev for QTEE as it serves as a direct user of
570 	 * this context. The teedev will be released in the context's release().
571 	 *
572 	 * tee_device_unregister() will remain blocked until all contexts
573 	 * are released. This includes contexts owned by the user, which are
574 	 * closed by teedev_close_context(), as well as those owned by QTEE
575 	 * closed by teedev_ctx_put() in object's release().
576 	 */
577 	if (!tee_device_get(ctx->teedev))
578 		return -EINVAL;
579 
580 	idr_init(&ctxdata->qtee_objects_idr);
581 	mutex_init(&ctxdata->qtee_lock);
582 	idr_init(&ctxdata->reqs_idr);
583 	INIT_LIST_HEAD(&ctxdata->reqs_list);
584 	mutex_init(&ctxdata->reqs_lock);
585 	init_completion(&ctxdata->req_c);
586 
587 	ctx->data = no_free_ptr(ctxdata);
588 
589 	return 0;
590 }
591 
592 /* Gets called when the user closes the device */
593 static void qcomtee_close_context(struct tee_context *ctx)
594 {
595 	struct qcomtee_context_data *ctxdata = ctx->data;
596 	struct qcomtee_object *object;
597 	int id;
598 
599 	/* Process QUEUED or PROCESSING requests. */
600 	qcomtee_requests_destroy(ctxdata);
601 	/* Release QTEE objects. */
602 	idr_for_each_entry(&ctxdata->qtee_objects_idr, object, id)
603 		qcomtee_object_put(object);
604 }
605 
606 /* Gets called when the final reference to the context goes away. */
607 static void qcomtee_release(struct tee_context *ctx)
608 {
609 	struct qcomtee_context_data *ctxdata = ctx->data;
610 
611 	idr_destroy(&ctxdata->qtee_objects_idr);
612 	idr_destroy(&ctxdata->reqs_idr);
613 	kfree(ctxdata);
614 
615 	/* There is nothing shared in this context with QTEE. */
616 	tee_device_put(ctx->teedev);
617 }
618 
619 static void qcomtee_get_version(struct tee_device *teedev,
620 				struct tee_ioctl_version_data *vers)
621 {
622 	struct tee_ioctl_version_data v = {
623 		.impl_id = TEE_IMPL_ID_QTEE,
624 		.gen_caps = TEE_GEN_CAP_OBJREF,
625 	};
626 
627 	*vers = v;
628 }
629 
630 /**
631  * qcomtee_get_qtee_feature_list() - Query QTEE features versions.
632  * @ctx: TEE context.
633  * @id: ID of the feature to query.
634  * @version: version of the feature.
635  *
636  * Used to query the verion of features supported by QTEE.
637  */
638 static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
639 					  u32 *version)
640 {
641 	struct qcomtee_object_invoke_ctx *oic __free(kfree);
642 	struct qcomtee_object *client_env, *service;
643 	struct qcomtee_arg u[3] = { 0 };
644 	int result;
645 
646 	oic = qcomtee_object_invoke_ctx_alloc(ctx);
647 	if (!oic)
648 		return;
649 
650 	client_env = qcomtee_object_get_client_env(oic);
651 	if (client_env == NULL_QCOMTEE_OBJECT)
652 		return;
653 
654 	/* Get ''FeatureVersions Service'' object. */
655 	service = qcomtee_object_get_service(oic, client_env,
656 					     QCOMTEE_FEATURE_VER_UID);
657 	if (service == NULL_QCOMTEE_OBJECT)
658 		goto out_failed;
659 
660 	/* IB: Feature to query. */
661 	u[0].b.addr = &id;
662 	u[0].b.size = sizeof(id);
663 	u[0].type = QCOMTEE_ARG_TYPE_IB;
664 
665 	/* OB: Version returned. */
666 	u[1].b.addr = version;
667 	u[1].b.size = sizeof(*version);
668 	u[1].type = QCOMTEE_ARG_TYPE_OB;
669 
670 	qcomtee_object_do_invoke(oic, service, QCOMTEE_FEATURE_VER_OP_GET, u,
671 				 &result);
672 
673 out_failed:
674 	qcomtee_object_put(service);
675 	qcomtee_object_put(client_env);
676 }
677 
678 static const struct tee_driver_ops qcomtee_ops = {
679 	.get_version = qcomtee_get_version,
680 	.open = qcomtee_open,
681 	.close_context = qcomtee_close_context,
682 	.release = qcomtee_release,
683 	.object_invoke_func = qcomtee_object_invoke,
684 	.supp_recv = qcomtee_supp_recv,
685 	.supp_send = qcomtee_supp_send,
686 };
687 
688 static const struct tee_desc qcomtee_desc = {
689 	.name = "qcomtee",
690 	.ops = &qcomtee_ops,
691 	.owner = THIS_MODULE,
692 };
693 
694 static int qcomtee_probe(struct platform_device *pdev)
695 {
696 	struct workqueue_struct *async_wq;
697 	struct tee_device *teedev;
698 	struct tee_shm_pool *pool;
699 	struct tee_context *ctx;
700 	struct qcomtee *qcomtee;
701 	int err;
702 
703 	qcomtee = kzalloc(sizeof(*qcomtee), GFP_KERNEL);
704 	if (!qcomtee)
705 		return -ENOMEM;
706 
707 	pool = qcomtee_shm_pool_alloc();
708 	if (IS_ERR(pool)) {
709 		err = PTR_ERR(pool);
710 
711 		goto err_free_qcomtee;
712 	}
713 
714 	teedev = tee_device_alloc(&qcomtee_desc, NULL, pool, qcomtee);
715 	if (IS_ERR(teedev)) {
716 		err = PTR_ERR(teedev);
717 
718 		goto err_pool_destroy;
719 	}
720 
721 	qcomtee->teedev = teedev;
722 	qcomtee->pool = pool;
723 	err = tee_device_register(qcomtee->teedev);
724 	if (err)
725 		goto err_unreg_teedev;
726 
727 	platform_set_drvdata(pdev, qcomtee);
728 	/* Start async wq. */
729 	async_wq = alloc_ordered_workqueue("qcomtee_wq", 0);
730 	if (!async_wq) {
731 		err = -ENOMEM;
732 
733 		goto err_unreg_teedev;
734 	}
735 
736 	qcomtee->wq = async_wq;
737 	/* Driver context used for async operations of teedev. */
738 	ctx = teedev_open(qcomtee->teedev);
739 	if (IS_ERR(ctx)) {
740 		err = PTR_ERR(ctx);
741 
742 		goto err_dest_wq;
743 	}
744 
745 	qcomtee->ctx = ctx;
746 	/* Init Object table. */
747 	qcomtee->xa_last_id = 0;
748 	xa_init_flags(&qcomtee->xa_local_objects, XA_FLAGS_ALLOC);
749 	/* Get QTEE verion. */
750 	qcomtee_get_qtee_feature_list(qcomtee->ctx,
751 				      QCOMTEE_FEATURE_VER_OP_GET_QTEE_ID,
752 				      &qcomtee->qtee_version);
753 
754 	pr_info("QTEE version %u.%u.%u\n",
755 		QTEE_VERSION_GET_MAJOR(qcomtee->qtee_version),
756 		QTEE_VERSION_GET_MINOR(qcomtee->qtee_version),
757 		QTEE_VERSION_GET_PATCH(qcomtee->qtee_version));
758 
759 	return 0;
760 
761 err_dest_wq:
762 	destroy_workqueue(qcomtee->wq);
763 err_unreg_teedev:
764 	tee_device_unregister(qcomtee->teedev);
765 err_pool_destroy:
766 	tee_shm_pool_free(pool);
767 err_free_qcomtee:
768 	kfree(qcomtee);
769 
770 	return err;
771 }
772 
773 /**
774  * qcomtee_remove() - Device Removal Routine.
775  * @pdev: platform device information struct.
776  *
777  * It is called by the platform subsystem to alert the driver that it should
778  * release the device.
779  *
780  * QTEE does not provide an API to inform it about a callback object going away.
781  * However, when releasing QTEE objects, any callback object sent to QTEE
782  * previously would be released by QTEE as part of the object release.
783  */
784 static void qcomtee_remove(struct platform_device *pdev)
785 {
786 	struct qcomtee *qcomtee = platform_get_drvdata(pdev);
787 
788 	teedev_close_context(qcomtee->ctx);
789 	/* Wait for RELEASE operations to be processed for QTEE objects. */
790 	tee_device_unregister(qcomtee->teedev);
791 	destroy_workqueue(qcomtee->wq);
792 	tee_shm_pool_free(qcomtee->pool);
793 	kfree(qcomtee);
794 }
795 
796 static const struct platform_device_id qcomtee_ids[] = { { "qcomtee", 0 }, {} };
797 MODULE_DEVICE_TABLE(platform, qcomtee_ids);
798 
799 static struct platform_driver qcomtee_platform_driver = {
800 	.probe = qcomtee_probe,
801 	.remove = qcomtee_remove,
802 	.driver = {
803 		.name = "qcomtee",
804 	},
805 	.id_table = qcomtee_ids,
806 };
807 
808 module_platform_driver(qcomtee_platform_driver);
809 
810 MODULE_AUTHOR("Qualcomm");
811 MODULE_DESCRIPTION("QTEE driver");
812 MODULE_VERSION("1.0");
813 MODULE_LICENSE("GPL");
814