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:
Zhen Kong 2017-11-13 15:13:31 -08:00 committed by Gerrit - the friendly Code Review server
parent 55cbbe6873
commit 69fb586ddb

View file

@ -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",