summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhen Kong <zkong@codeaurora.org>2017-11-13 15:13:31 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-12-02 08:25:16 -0800
commit69fb586ddb1fe33b3570eef5e74e9d4a970937d2 (patch)
tree83b3c89159ed2316f390ee09a175a51d5afb9c5d
parent55cbbe687356eeb53256e8f8dc7f7daddae68272 (diff)
qseecom: fix a race condition when TA is blocked
When the thread processing blocked TA wakes up when listener becames available, the listener may be unavailable again before this thread grabs the global mutex, so make change to add a while loop to check if listener available after wake up and hold mutex. Change-Id: Ib386faca7a44325142da1dc54e19a99f3173ec86 Signed-off-by: Zhen Kong <zkong@codeaurora.org>
-rw-r--r--drivers/misc/qseecom.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8c48a5c05bbe..fab9a07955dd 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1898,20 +1898,22 @@ static int __qseecom_process_blocked_on_listener_legacy(
ptr_app->blocked_on_listener_id = resp->data;
/* sleep until listener is available */
- qseecom.app_block_ref_cnt++;
- ptr_app->app_blocked = true;
- mutex_unlock(&app_access_lock);
- if (wait_event_freezable(
+ do {
+ qseecom.app_block_ref_cnt++;
+ ptr_app->app_blocked = true;
+ mutex_unlock(&app_access_lock);
+ if (wait_event_freezable(
list_ptr->listener_block_app_wq,
!list_ptr->listener_in_use)) {
- pr_err("Interrupted: listener_id %d, app_id %d\n",
+ pr_err("Interrupted: listener_id %d, app_id %d\n",
resp->data, ptr_app->app_id);
- ret = -ERESTARTSYS;
- goto exit;
- }
- mutex_lock(&app_access_lock);
- ptr_app->app_blocked = false;
- qseecom.app_block_ref_cnt--;
+ ret = -ERESTARTSYS;
+ goto exit;
+ }
+ mutex_lock(&app_access_lock);
+ ptr_app->app_blocked = false;
+ qseecom.app_block_ref_cnt--;
+ } while (list_ptr->listener_in_use);
ptr_app->blocked_on_listener_id = 0;
/* notify the blocked app that listener is available */
@@ -1962,18 +1964,20 @@ static int __qseecom_process_blocked_on_listener_smcinvoke(
pr_debug("lsntr %d in_use = %d\n",
resp->data, list_ptr->listener_in_use);
/* sleep until listener is available */
- qseecom.app_block_ref_cnt++;
- mutex_unlock(&app_access_lock);
- if (wait_event_freezable(
+ do {
+ qseecom.app_block_ref_cnt++;
+ mutex_unlock(&app_access_lock);
+ if (wait_event_freezable(
list_ptr->listener_block_app_wq,
!list_ptr->listener_in_use)) {
- pr_err("Interrupted: listener_id %d, session_id %d\n",
+ pr_err("Interrupted: listener_id %d, session_id %d\n",
resp->data, session_id);
- ret = -ERESTARTSYS;
- goto exit;
- }
- mutex_lock(&app_access_lock);
- qseecom.app_block_ref_cnt--;
+ ret = -ERESTARTSYS;
+ goto exit;
+ }
+ mutex_lock(&app_access_lock);
+ qseecom.app_block_ref_cnt--;
+ } while (list_ptr->listener_in_use);
/* notify TZ that listener is available */
pr_warn("Lsntr %d is available, unblock session(%d) in TZ\n",