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/uaccess.h> 10 11 #include "qcomtee.h" 12 13 /** 14 * DOC: User Objects aka Supplicants 15 * 16 * Any userspace process with access to the TEE device file can behave as a 17 * supplicant by creating a user object. Any TEE parameter of type OBJREF with 18 * %QCOMTEE_OBJREF_FLAG_USER flag set is considered a user object. 19 * 20 * A supplicant uses qcomtee_user_object_select() (i.e. TEE_IOC_SUPPL_RECV) to 21 * receive a QTEE user object request and qcomtee_user_object_submit() 22 * (i.e. TEE_IOC_SUPPL_SEND) to submit a response. QTEE expects to receive the 23 * response, including OB and OO in a specific order in the message; parameters 24 * submitted with qcomtee_user_object_submit() should maintain this order. 25 */ 26 27 /** 28 * struct qcomtee_user_object - User object. 29 * @object: &struct qcomtee_object representing the user object. 30 * @ctx: context for which the user object is defined. 31 * @object_id: object ID in @ctx. 32 * @notify: notify on release. 33 * 34 * Any object managed in userspace is represented by this struct. 35 * If @notify is set, a notification message is sent back to userspace 36 * upon release. 37 */ 38 struct qcomtee_user_object { 39 struct qcomtee_object object; 40 struct tee_context *ctx; 41 u64 object_id; 42 bool notify; 43 }; 44 45 #define to_qcomtee_user_object(o) \ 46 container_of((o), struct qcomtee_user_object, object) 47 48 static struct qcomtee_object_operations qcomtee_user_object_ops; 49 50 /* Is it a user object? */ 51 int is_qcomtee_user_object(struct qcomtee_object *object) 52 { 53 return object != NULL_QCOMTEE_OBJECT && 54 typeof_qcomtee_object(object) == QCOMTEE_OBJECT_TYPE_CB && 55 object->ops == &qcomtee_user_object_ops; 56 } 57 58 /* Set the user object's 'notify on release' flag. */ 59 void qcomtee_user_object_set_notify(struct qcomtee_object *object, bool notify) 60 { 61 if (is_qcomtee_user_object(object)) 62 to_qcomtee_user_object(object)->notify = notify; 63 } 64 65 /* Supplicant Requests: */ 66 67 /** 68 * enum qcomtee_req_state - Current state of request. 69 * @QCOMTEE_REQ_QUEUED: Request is waiting for supplicant. 70 * @QCOMTEE_REQ_PROCESSING: Request has been picked by the supplicant. 71 * @QCOMTEE_REQ_PROCESSED: Response has been submitted for the request. 72 */ 73 enum qcomtee_req_state { 74 QCOMTEE_REQ_QUEUED = 1, 75 QCOMTEE_REQ_PROCESSING, 76 QCOMTEE_REQ_PROCESSED, 77 }; 78 79 /* User requests sent to supplicants. */ 80 struct qcomtee_ureq { 81 enum qcomtee_req_state state; 82 83 /* User Request: */ 84 int req_id; 85 u64 object_id; 86 u32 op; 87 struct qcomtee_arg *args; 88 int errno; 89 90 struct list_head node; 91 struct completion c; /* Completion for whoever wait. */ 92 }; 93 94 /* 95 * Placeholder for a PROCESSING request in qcomtee_context.reqs_idr. 96 * 97 * If the thread that calls qcomtee_object_invoke() dies and the supplicant 98 * is processing the request, replace the entry in qcomtee_context.reqs_idr 99 * with empty_ureq. This ensures that (1) the req_id remains busy and is not 100 * reused, and (2) the supplicant fails to submit the response and performs 101 * the necessary rollback. 102 */ 103 static struct qcomtee_ureq empty_ureq = { .state = QCOMTEE_REQ_PROCESSING }; 104 105 /* Enqueue a user request for a context and assign a request ID. */ 106 static int ureq_enqueue(struct qcomtee_context_data *ctxdata, 107 struct qcomtee_ureq *ureq) 108 { 109 int ret; 110 111 guard(mutex)(&ctxdata->reqs_lock); 112 /* Supplicant is dying. */ 113 if (ctxdata->released) 114 return -ENODEV; 115 116 /* Allocate an ID and queue the request. */ 117 ret = idr_alloc(&ctxdata->reqs_idr, ureq, 0, 0, GFP_KERNEL); 118 if (ret < 0) 119 return ret; 120 121 ureq->req_id = ret; 122 ureq->state = QCOMTEE_REQ_QUEUED; 123 list_add_tail(&ureq->node, &ctxdata->reqs_list); 124 125 return 0; 126 } 127 128 /** 129 * ureq_dequeue() - Dequeue a user request from a context. 130 * @ctxdata: context data for a context to dequeue the request. 131 * @req_id: ID of the request to be dequeued. 132 * 133 * It dequeues a user request and releases its request ID. 134 * 135 * Context: The caller should hold &qcomtee_context_data->reqs_lock. 136 * Return: Returns the user request associated with this ID; otherwise, NULL. 137 */ 138 static struct qcomtee_ureq *ureq_dequeue(struct qcomtee_context_data *ctxdata, 139 int req_id) 140 { 141 struct qcomtee_ureq *ureq; 142 143 ureq = idr_remove(&ctxdata->reqs_idr, req_id); 144 if (ureq == &empty_ureq || !ureq) 145 return NULL; 146 147 list_del(&ureq->node); 148 149 return ureq; 150 } 151 152 /** 153 * ureq_select() - Select the next request in a context. 154 * @ctxdata: context data for a context to pop a request. 155 * @ubuf_size: size of the available buffer for UBUF parameters. 156 * @num_params: number of entries for the TEE parameter array. 157 * 158 * It checks if @num_params is large enough to fit the next request arguments. 159 * It checks if @ubuf_size is large enough to fit IB buffer arguments. 160 * 161 * Context: The caller should hold &qcomtee_context_data->reqs_lock. 162 * Return: On success, returns a request; 163 * on failure, returns NULL and ERR_PTR. 164 */ 165 static struct qcomtee_ureq *ureq_select(struct qcomtee_context_data *ctxdata, 166 size_t ubuf_size, int num_params) 167 { 168 struct qcomtee_ureq *req, *ureq = NULL; 169 struct qcomtee_arg *u; 170 int i; 171 172 /* Find the a queued request. */ 173 list_for_each_entry(req, &ctxdata->reqs_list, node) { 174 if (req->state == QCOMTEE_REQ_QUEUED) { 175 ureq = req; 176 break; 177 } 178 } 179 180 if (!ureq) 181 return NULL; 182 183 u = ureq->args; 184 /* (1) Is there enough TEE parameters? */ 185 if (num_params < qcomtee_args_len(u)) 186 return ERR_PTR(-EINVAL); 187 /* (2) Is there enough space to pass input buffers? */ 188 qcomtee_arg_for_each_input_buffer(i, u) { 189 ubuf_size = size_sub(ubuf_size, u[i].b.size); 190 if (ubuf_size == SIZE_MAX) 191 return ERR_PTR(-EINVAL); 192 193 ubuf_size = round_down(ubuf_size, 8); 194 } 195 196 return ureq; 197 } 198 199 /* Gets called when the user closes the device. */ 200 void qcomtee_requests_destroy(struct qcomtee_context_data *ctxdata) 201 { 202 struct qcomtee_ureq *req, *ureq; 203 204 guard(mutex)(&ctxdata->reqs_lock); 205 /* So ureq_enqueue() refuses new requests from QTEE. */ 206 ctxdata->released = true; 207 /* ureqs in reqs_list are in QUEUED or PROCESSING (!= empty_ureq) state. */ 208 list_for_each_entry_safe(ureq, req, &ctxdata->reqs_list, node) { 209 ureq_dequeue(ctxdata, ureq->req_id); 210 211 if (ureq->op != QCOMTEE_MSG_OBJECT_OP_RELEASE) { 212 ureq->state = QCOMTEE_REQ_PROCESSED; 213 ureq->errno = -ENODEV; 214 215 complete(&ureq->c); 216 } else { 217 kfree(ureq); 218 } 219 } 220 } 221 222 /* User Object API. */ 223 224 /* User object dispatcher. */ 225 static int qcomtee_user_object_dispatch(struct qcomtee_object_invoke_ctx *oic, 226 struct qcomtee_object *object, u32 op, 227 struct qcomtee_arg *args) 228 { 229 struct qcomtee_user_object *uo = to_qcomtee_user_object(object); 230 struct qcomtee_context_data *ctxdata = uo->ctx->data; 231 int errno; 232 233 struct qcomtee_ureq *ureq __free(kfree) = kzalloc_obj(*ureq); 234 if (!ureq) 235 return -ENOMEM; 236 237 init_completion(&ureq->c); 238 ureq->object_id = uo->object_id; 239 ureq->op = op; 240 ureq->args = args; 241 242 /* Queue the request. */ 243 if (ureq_enqueue(ctxdata, ureq)) 244 return -ENODEV; 245 /* Wakeup supplicant to process it. */ 246 complete(&ctxdata->req_c); 247 248 /* 249 * Wait for the supplicant to process the request. Wait as KILLABLE 250 * in case the supplicant and invoke thread are both running from the 251 * same process, the supplicant crashes, or the shutdown sequence 252 * starts with supplicant dies first; otherwise, it stuck indefinitely. 253 * 254 * If the supplicant processes long-running requests, also use 255 * TASK_FREEZABLE to allow the device to safely suspend if needed. 256 */ 257 if (!wait_for_completion_state(&ureq->c, 258 TASK_KILLABLE | TASK_FREEZABLE)) { 259 errno = ureq->errno; 260 if (!errno) 261 oic->data = no_free_ptr(ureq); 262 } else { 263 enum qcomtee_req_state prev_state; 264 265 errno = -ENODEV; 266 267 scoped_guard(mutex, &ctxdata->reqs_lock) { 268 prev_state = ureq->state; 269 /* Replace with empty_ureq to keep req_id reserved. */ 270 if (prev_state == QCOMTEE_REQ_PROCESSING) { 271 list_del(&ureq->node); 272 idr_replace(&ctxdata->reqs_idr, 273 &empty_ureq, ureq->req_id); 274 275 /* Remove as supplicant has never seen this request. */ 276 } else if (prev_state == QCOMTEE_REQ_QUEUED) { 277 ureq_dequeue(ctxdata, ureq->req_id); 278 } 279 } 280 281 /* Supplicant did some work, do not discard it. */ 282 if (prev_state == QCOMTEE_REQ_PROCESSED) { 283 errno = ureq->errno; 284 if (!errno) 285 oic->data = no_free_ptr(ureq); 286 } 287 } 288 289 return errno; 290 } 291 292 /* Gets called after submitting the dispatcher response. */ 293 static void qcomtee_user_object_notify(struct qcomtee_object_invoke_ctx *oic, 294 struct qcomtee_object *unused_object, 295 int err) 296 { 297 struct qcomtee_ureq *ureq = oic->data; 298 struct qcomtee_arg *u = ureq->args; 299 int i; 300 301 /* 302 * If err, there was a transport issue, and QTEE did not receive the 303 * response for the dispatcher. Release the callback object created for 304 * QTEE, in addition to the copies of objects kept for the drivers. 305 */ 306 qcomtee_arg_for_each_output_object(i, u) { 307 if (err && 308 (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB)) 309 qcomtee_object_put(u[i].o); 310 qcomtee_object_put(u[i].o); 311 } 312 313 kfree(ureq); 314 } 315 316 static void qcomtee_user_object_release(struct qcomtee_object *object) 317 { 318 struct qcomtee_user_object *uo = to_qcomtee_user_object(object); 319 struct qcomtee_context_data *ctxdata = uo->ctx->data; 320 struct qcomtee_ureq *ureq; 321 322 /* RELEASE does not require any argument. */ 323 static struct qcomtee_arg args[] = { { .type = QCOMTEE_ARG_TYPE_INV } }; 324 325 if (!uo->notify) 326 goto out_no_notify; 327 328 ureq = kzalloc_obj(*ureq); 329 if (!ureq) 330 goto out_no_notify; 331 332 /* QUEUE a release request: */ 333 ureq->object_id = uo->object_id; 334 ureq->op = QCOMTEE_MSG_OBJECT_OP_RELEASE; 335 ureq->args = args; 336 if (ureq_enqueue(ctxdata, ureq)) { 337 kfree(ureq); 338 /* Ignore the notification if it cannot be queued. */ 339 goto out_no_notify; 340 } 341 342 complete(&ctxdata->req_c); 343 344 out_no_notify: 345 teedev_ctx_put(uo->ctx); 346 kfree(uo); 347 } 348 349 static struct qcomtee_object_operations qcomtee_user_object_ops = { 350 .release = qcomtee_user_object_release, 351 .notify = qcomtee_user_object_notify, 352 .dispatch = qcomtee_user_object_dispatch, 353 }; 354 355 /** 356 * qcomtee_user_param_to_object() - OBJREF parameter to &struct qcomtee_object. 357 * @object: object returned. 358 * @param: TEE parameter. 359 * @ctx: context in which the conversion should happen. 360 * 361 * @param is an OBJREF with %QCOMTEE_OBJREF_FLAG_USER flags. 362 * 363 * Return: On success, returns 0; on failure, returns < 0. 364 */ 365 int qcomtee_user_param_to_object(struct qcomtee_object **object, 366 struct tee_param *param, 367 struct tee_context *ctx) 368 { 369 int err; 370 371 struct qcomtee_user_object *user_object __free(kfree) = 372 kzalloc_obj(*user_object); 373 if (!user_object) 374 return -ENOMEM; 375 376 user_object->ctx = ctx; 377 user_object->object_id = param->u.objref.id; 378 /* By default, always notify userspace upon release. */ 379 user_object->notify = true; 380 err = qcomtee_object_user_init(&user_object->object, 381 QCOMTEE_OBJECT_TYPE_CB, 382 &qcomtee_user_object_ops, "uo-%llu", 383 param->u.objref.id); 384 if (err) 385 return err; 386 /* Matching teedev_ctx_put() is in qcomtee_user_object_release(). */ 387 teedev_ctx_get(ctx); 388 389 *object = &no_free_ptr(user_object)->object; 390 391 return 0; 392 } 393 394 /* Reverse what qcomtee_user_param_to_object() does. */ 395 int qcomtee_user_param_from_object(struct tee_param *param, 396 struct qcomtee_object *object, 397 struct tee_context *ctx) 398 { 399 struct qcomtee_user_object *uo; 400 401 uo = to_qcomtee_user_object(object); 402 /* Ensure the object is in the same context as the caller. */ 403 if (uo->ctx != ctx) 404 return -EINVAL; 405 406 param->u.objref.id = uo->object_id; 407 param->u.objref.flags = QCOMTEE_OBJREF_FLAG_USER; 408 409 /* User objects are valid in userspace; do not keep a copy. */ 410 qcomtee_object_put(object); 411 412 return 0; 413 } 414 415 /** 416 * qcomtee_cb_params_from_args() - Convert QTEE arguments to TEE parameters. 417 * @params: TEE parameters. 418 * @u: QTEE arguments. 419 * @num_params: number of elements in the parameter array. 420 * @ubuf_addr: user buffer for arguments of type %QCOMTEE_ARG_TYPE_IB. 421 * @ubuf_size: size of the user buffer. 422 * @ctx: context in which the conversion should happen. 423 * 424 * It expects @params to have enough entries for @u. Entries in @params are of 425 * %TEE_IOCTL_PARAM_ATTR_TYPE_NONE. 426 * 427 * Return: On success, returns the number of input parameters; 428 * on failure, returns < 0. 429 */ 430 static int qcomtee_cb_params_from_args(struct tee_param *params, 431 struct qcomtee_arg *u, int num_params, 432 void __user *ubuf_addr, size_t ubuf_size, 433 struct tee_context *ctx) 434 { 435 int i, np; 436 void __user *uaddr; 437 438 qcomtee_arg_for_each(i, u) { 439 switch (u[i].type) { 440 case QCOMTEE_ARG_TYPE_IB: 441 params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT; 442 443 /* Underflow already checked in ureq_select(). */ 444 ubuf_size = round_down(ubuf_size - u[i].b.size, 8); 445 uaddr = (void __user *)(ubuf_addr + ubuf_size); 446 447 params[i].u.ubuf.uaddr = uaddr; 448 params[i].u.ubuf.size = u[i].b.size; 449 if (copy_to_user(params[i].u.ubuf.uaddr, u[i].b.addr, 450 u[i].b.size)) 451 goto out_failed; 452 453 break; 454 case QCOMTEE_ARG_TYPE_OB: 455 params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT; 456 /* Let the user knows the maximum size QTEE expects. */ 457 params[i].u.ubuf.size = u[i].b.size; 458 459 break; 460 case QCOMTEE_ARG_TYPE_IO: 461 params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT; 462 if (qcomtee_objref_from_arg(¶ms[i], &u[i], ctx)) 463 goto out_failed; 464 465 break; 466 case QCOMTEE_ARG_TYPE_OO: 467 params[i].attr = 468 TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT; 469 470 break; 471 default: /* Never get here! */ 472 goto out_failed; 473 } 474 } 475 476 return i; 477 478 out_failed: 479 /* Undo qcomtee_objref_from_arg(). */ 480 for (np = i; np >= 0; np--) { 481 if (params[np].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT) 482 qcomtee_context_del_qtee_object(¶ms[np], ctx); 483 } 484 485 /* Release any IO objects not processed. */ 486 for (; u[i].type; i++) { 487 if (u[i].type == QCOMTEE_ARG_TYPE_IO) 488 qcomtee_object_put(u[i].o); 489 } 490 491 return -EINVAL; 492 } 493 494 /** 495 * qcomtee_cb_params_to_args() - Convert TEE parameters to QTEE arguments. 496 * @u: QTEE arguments. 497 * @params: TEE parameters. 498 * @num_params: number of elements in the parameter array. 499 * @ctx: context in which the conversion should happen. 500 * 501 * Return: On success, returns 0; on failure, returns < 0. 502 */ 503 static int qcomtee_cb_params_to_args(struct qcomtee_arg *u, 504 struct tee_param *params, int num_params, 505 struct tee_context *ctx) 506 { 507 int i; 508 509 qcomtee_arg_for_each(i, u) { 510 switch (u[i].type) { 511 case QCOMTEE_ARG_TYPE_IB: 512 if (params[i].attr != 513 TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT) 514 goto out_failed; 515 516 break; 517 case QCOMTEE_ARG_TYPE_OB: 518 if (params[i].attr != 519 TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT) 520 goto out_failed; 521 522 /* Client can not send more data than requested. */ 523 if (params[i].u.ubuf.size > u[i].b.size) 524 goto out_failed; 525 526 if (copy_from_user(u[i].b.addr, params[i].u.ubuf.uaddr, 527 params[i].u.ubuf.size)) 528 goto out_failed; 529 530 u[i].b.size = params[i].u.ubuf.size; 531 532 break; 533 case QCOMTEE_ARG_TYPE_IO: 534 if (params[i].attr != 535 TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT) 536 goto out_failed; 537 538 break; 539 case QCOMTEE_ARG_TYPE_OO: 540 if (params[i].attr != 541 TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT) 542 goto out_failed; 543 544 if (qcomtee_objref_to_arg(&u[i], ¶ms[i], ctx)) 545 goto out_failed; 546 547 break; 548 default: /* Never get here! */ 549 goto out_failed; 550 } 551 } 552 553 return 0; 554 555 out_failed: 556 /* Undo qcomtee_objref_to_arg(). */ 557 for (i--; i >= 0; i--) { 558 if (u[i].type != QCOMTEE_ARG_TYPE_OO) 559 continue; 560 561 qcomtee_user_object_set_notify(u[i].o, false); 562 if (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB) 563 qcomtee_object_put(u[i].o); 564 565 qcomtee_object_put(u[i].o); 566 } 567 568 return -EINVAL; 569 } 570 571 /** 572 * qcomtee_user_object_select() - Select a request for a user object. 573 * @ctx: context to look for a user object. 574 * @params: parameters for @op. 575 * @num_params: number of elements in the parameter array. 576 * @uaddr: user buffer for output UBUF parameters. 577 * @size: size of user buffer @uaddr. 578 * @data: information for the selected request. 579 * 580 * @params is filled along with @data for the selected request. 581 * 582 * Return: On success, returns 0; on failure, returns < 0. 583 */ 584 int qcomtee_user_object_select(struct tee_context *ctx, 585 struct tee_param *params, int num_params, 586 void __user *uaddr, size_t size, 587 struct qcomtee_user_object_request_data *data) 588 { 589 struct qcomtee_context_data *ctxdata = ctx->data; 590 struct qcomtee_ureq *ureq; 591 int ret; 592 593 /* 594 * Hold the reqs_lock not only for ureq_select() and updating the ureq 595 * state to PROCESSING but for the entire duration of ureq access. 596 * This prevents qcomtee_user_object_dispatch() from freeing 597 * ureq while it is still in use, if client dies. 598 */ 599 600 while (1) { 601 scoped_guard(mutex, &ctxdata->reqs_lock) { 602 ureq = ureq_select(ctxdata, size, num_params); 603 if (!ureq) 604 goto wait_for_request; 605 606 if (IS_ERR(ureq)) 607 return PTR_ERR(ureq); 608 609 /* Processing the request 'QUEUED -> PROCESSING'. */ 610 ureq->state = QCOMTEE_REQ_PROCESSING; 611 /* ''Prepare user request:'' */ 612 data->id = ureq->req_id; 613 data->object_id = ureq->object_id; 614 data->op = ureq->op; 615 ret = qcomtee_cb_params_from_args(params, ureq->args, 616 num_params, uaddr, 617 size, ctx); 618 if (ret >= 0) 619 goto done_request; 620 621 /* Something is wrong with the request: */ 622 ureq_dequeue(ctxdata, data->id); 623 /* Send error to QTEE. */ 624 ureq->state = QCOMTEE_REQ_PROCESSED; 625 ureq->errno = ret; 626 627 complete(&ureq->c); 628 } 629 630 continue; 631 wait_for_request: 632 /* Wait for a new QUEUED request. */ 633 if (wait_for_completion_interruptible(&ctxdata->req_c)) 634 return -ERESTARTSYS; 635 } 636 637 done_request: 638 /* No one is waiting for the response. */ 639 if (data->op == QCOMTEE_MSG_OBJECT_OP_RELEASE) { 640 scoped_guard(mutex, &ctxdata->reqs_lock) 641 ureq_dequeue(ctxdata, data->id); 642 kfree(ureq); 643 } 644 645 data->np = ret; 646 647 return 0; 648 } 649 650 /** 651 * qcomtee_user_object_submit() - Submit a response for a user object. 652 * @ctx: context to look for a user object. 653 * @params: returned parameters. 654 * @num_params: number of elements in the parameter array. 655 * @req_id: request ID for the response. 656 * @errno: result of user object invocation. 657 * 658 * Return: On success, returns 0; on failure, returns < 0. 659 */ 660 int qcomtee_user_object_submit(struct tee_context *ctx, 661 struct tee_param *params, int num_params, 662 int req_id, int errno) 663 { 664 struct qcomtee_context_data *ctxdata = ctx->data; 665 struct qcomtee_ureq *ureq; 666 667 /* See comments for reqs_lock in qcomtee_user_object_select(). */ 668 guard(mutex)(&ctxdata->reqs_lock); 669 670 ureq = ureq_dequeue(ctxdata, req_id); 671 if (!ureq) 672 return -EINVAL; 673 674 ureq->state = QCOMTEE_REQ_PROCESSED; 675 676 if (!errno) 677 ureq->errno = qcomtee_cb_params_to_args(ureq->args, params, 678 num_params, ctx); 679 else 680 ureq->errno = errno; 681 /* Return errno if qcomtee_cb_params_to_args() failed; otherwise 0. */ 682 if (!errno && ureq->errno) 683 errno = ureq->errno; 684 else 685 errno = 0; 686 687 /* Send result to QTEE. */ 688 complete(&ureq->c); 689 690 return errno; 691 } 692