From e6c7ea7d4da7e43ca05bb2634165e7c143a108ba Mon Sep 17 00:00:00 2001 From: Hisping Lin Date: Tue, 28 Feb 2023 10:17:52 +0800 Subject: [PATCH] tee: optee: interrupt an RPC when supplicant has been killed check supplicant is dead or alive when get signal, run normal program if supplicant is alive, interrupting an RPC if supplicant is dead, Otherwise, the current thread will be stuck in the optee driver. The error is printed as follows: INFO: task gatekeeper@1.0-:461 blocked for more than 20 seconds. Not tainted 5.10.66 #2 task:gatekeeper@1.0- state:D stack: 0 pid: 461 ppid: 1 flags:0x0400002d Call trace: switch_to+0x180/0x230 __schedule+0x49c/0x704 schedule+0xa0/0xe8 schedule_timeout+0x38/0x124 wait_for_common+0xa4/0x134 wait_for_completion+0x1c/0x2c optee_handle_rpc+0x1a4/0x6ec optee_do_call_with_arg+0x1a4/0x298 optee_release+0x134/0x1bc tee_release+0xa4/0x100 Change-Id: I2f82338ecccc1bc97bb5a6c25767eca4542cbcdf Signed-off-by: Hisping Lin --- drivers/tee/optee/supp.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c index 322a543b8c27..2d556b79a67e 100644 --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -82,6 +82,9 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, struct optee_supp_req *req; bool interruptable; u32 ret; + unsigned long timeleft; + int id; + struct optee_supp_req *get_req; /* * Return in case there is no supplicant available and @@ -114,8 +117,17 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, * exclusive access again. */ while (wait_for_completion_interruptible(&req->c)) { + pr_err("Warning, Interrupting an RPC to supplicant!\n"); + timeleft = wait_for_completion_timeout(&req->c, msecs_to_jiffies(2000)); + if (timeleft) { + /* get completion, it means tee-supplicant is alive. */ + break; + } else { + /* timeout, it means tee-supplicant is dead, interrupting an RPC. */ + interruptable = true; + } + mutex_lock(&supp->mutex); - interruptable = !supp->ctx; if (interruptable) { /* * There's no supplicant available and since the @@ -134,6 +146,14 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, list_del(&req->link); req->in_queue = false; } + + idr_for_each_entry(&supp->idr, get_req, id) { + if (get_req == req) { + idr_remove(&supp->idr, id); + supp->req_id = -1; + break; + } + } } mutex_unlock(&supp->mutex);