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