summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengguang Zhu <pengguang.zhu@amlogic.com>2019-05-16 14:07:13 +0800
committerPengguang Zhu <pengguang.zhu@amlogic.com>2019-05-16 15:51:12 +0800
commit45da928ae2c55c6626a480cfbc72e8deaeac04c7 (patch)
tree56479748620916dc891bd4ceb8e01bfde11a44d5
parent31f0ae9cecde555eaba749a4de2fe24eb944cc95 (diff)
downloadoptee_linuxdriver-45da928ae2c55c6626a480cfbc72e8deaeac04c7.tar.gz
linuxdriver: check supplicant status before send message [1/1]
PD#TV-5392 Problem: when playing netflix movies, press power button, TV can not power down and console hang. previous commit will check supplicant status, but there is gap that thread will scheduled and meanwhile the supplicant status may change. Solution: move the status check before wait_for_completion Verify: TXLX + Android P Change-Id: I445619192a1c6cf047a3fe51f3660dad7aa39601 Signed-off-by: Pengguang Zhu <pengguang.zhu@amlogic.com>
-rwxr-xr-xoptee/supp.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/optee/supp.c b/optee/supp.c
index d4f4a34..de1b5f9 100755
--- a/optee/supp.c
+++ b/optee/supp.c
@@ -88,14 +88,12 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_supp *supp = &optee->supp;
- struct optee_supp_req *req = NULL;
+ struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL);
bool interruptable;
u32 ret;
+ int id;
+ struct optee_supp_req *req_tmp;
- if (!supp->ctx)
- return TEEC_ERROR_COMMUNICATION;
-
- req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return TEEC_ERROR_OUT_OF_MEMORY;
@@ -113,6 +111,23 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
/* Tell an eventual waiter there's a new request */
complete(&supp->reqs_c);
+ if (!supp->ctx) {
+ mutex_lock(&supp->mutex);
+ if (req->in_queue) {
+ list_del(&req->link);
+ } else {
+ idr_for_each_entry(&supp->idr, req_tmp, id) {
+ if (req == req_tmp)
+ idr_remove(&supp->idr, id);
+ }
+ }
+ mutex_unlock(&supp->mutex);
+
+ kfree(req);
+
+ return TEEC_ERROR_COMMUNICATION;
+ }
+
/*
* Wait for supplicant to process and return result, once we've
* returned from wait_for_completion(&req->c) successfully we have