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>
This commit is contained in:
parent
55cbbe6873
commit
69fb586ddb
1 changed files with 24 additions and 20 deletions
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue