diff options
author | Zhen Kong <zkong@codeaurora.org> | 2017-11-13 15:13:31 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-12-02 08:25:16 -0800 |
commit | 69fb586ddb1fe33b3570eef5e74e9d4a970937d2 (patch) | |
tree | 83b3c89159ed2316f390ee09a175a51d5afb9c5d | |
parent | 55cbbe687356eeb53256e8f8dc7f7daddae68272 (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.c | 44 |
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", |