mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
smcinvoke: implement retry and timeout for CB processing
CB requests are processed by HLOS userspace. It is possible that userspace never returns with a response. This could cause trusted environment that initiated CB request to reject processing anymore non-secure requests. This is not a desirable situation. Hence, adding timeout functionality along with retry mechanism to send error response back to trusted env after maximum number of retries are already done and continue processing requests from non-secure side. Change-Id: Idbd3048d0b9594c9927d55a24a8ca77e14214746 Signed-off-by: Anmolpreet Kaur <anmolpre@codeaurora.org>
This commit is contained in:
parent
aa860b5b17
commit
e55be43040
1 changed files with 42 additions and 14 deletions
|
|
@ -61,6 +61,7 @@
|
|||
*/
|
||||
#define SMCINVOKE_SERVER_STATE_DEFUNCT 1
|
||||
|
||||
#define CBOBJ_MAX_RETRIES 5
|
||||
#define FOR_ARGS(ndxvar, counts, section) \
|
||||
for (ndxvar = OBJECT_COUNTS_INDEX_##section(counts); \
|
||||
ndxvar < (OBJECT_COUNTS_INDEX_##section(counts) \
|
||||
|
|
@ -1002,6 +1003,8 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
|
|||
{
|
||||
/* ret is going to TZ. Provide values from OBJECT_ERROR_<> */
|
||||
int ret = OBJECT_ERROR_DEFUNCT;
|
||||
int cbobj_retries = 0;
|
||||
long timeout_jiff;
|
||||
struct smcinvoke_cb_txn *cb_txn = NULL;
|
||||
struct smcinvoke_tzcb_req *cb_req = NULL, *tmp_cb_req = NULL;
|
||||
struct smcinvoke_server_info *srvr_info = NULL;
|
||||
|
|
@ -1079,9 +1082,26 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
|
|||
* as this CBObj is served by this server, srvr_info will be valid.
|
||||
*/
|
||||
wake_up_interruptible_all(&srvr_info->req_wait_q);
|
||||
ret = wait_event_interruptible(srvr_info->rsp_wait_q,
|
||||
(cb_txn->state == SMCINVOKE_REQ_PROCESSED) ||
|
||||
(srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT));
|
||||
/* timeout before 1s otherwise tzbusy would come */
|
||||
timeout_jiff = msecs_to_jiffies(1000);
|
||||
|
||||
while (cbobj_retries < CBOBJ_MAX_RETRIES) {
|
||||
ret = wait_event_interruptible_timeout(srvr_info->rsp_wait_q,
|
||||
(cb_txn->state == SMCINVOKE_REQ_PROCESSED) ||
|
||||
(srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT),
|
||||
timeout_jiff);
|
||||
|
||||
if (ret == 0) {
|
||||
pr_err("CBobj timed out cb-tzhandle:%d, retry:%d, op:%d counts :%d\n",
|
||||
cb_req->hdr.tzhandle, cbobj_retries, cb_req->hdr.op, cb_req->hdr.counts);
|
||||
pr_err("CBobj %d timedout pid %x,tid %x, srvr state=%d, srvr id:%u\n",
|
||||
cb_req->hdr.tzhandle, current->pid, current->tgid, srvr_info->state,
|
||||
srvr_info->server_id);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
cbobj_retries++;
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
|
|
@ -1091,18 +1111,26 @@ out:
|
|||
*/
|
||||
mutex_lock(&g_smcinvoke_lock);
|
||||
hash_del(&cb_txn->hash);
|
||||
if (cb_txn->state == SMCINVOKE_REQ_PROCESSED) {
|
||||
/*
|
||||
* it is possible that server was killed immediately
|
||||
* after CB Req was processed but who cares now!
|
||||
*/
|
||||
} else if (!srvr_info ||
|
||||
srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) {
|
||||
cb_req->result = OBJECT_ERROR_DEFUNCT;
|
||||
pr_err("server invalid, res: %d\n", cb_req->result);
|
||||
} else {
|
||||
pr_debug("%s wait_event interrupted ret = %d\n", __func__, ret);
|
||||
if (ret == 0) {
|
||||
pr_err("CBObj timed out! No more retries\n");
|
||||
cb_req->result = OBJECT_ERROR_ABORT;
|
||||
} else if (ret < 0) {
|
||||
pr_err("wait event interruped, ret: %d\n", ret);
|
||||
cb_req->result = OBJECT_ERROR_ABORT;
|
||||
} else {
|
||||
if (cb_txn->state == SMCINVOKE_REQ_PROCESSED) {
|
||||
/*
|
||||
* it is possible that server was killed immediately
|
||||
* after CB Req was processed but who cares now!
|
||||
*/
|
||||
} else if (!srvr_info ||
|
||||
srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) {
|
||||
cb_req->result = OBJECT_ERROR_DEFUNCT;
|
||||
pr_err("server invalid, res: %d\n", cb_req->result);
|
||||
} else {
|
||||
pr_err("%s: unexpected event happened\n", __func__);
|
||||
cb_req->result = OBJECT_ERROR_ABORT;
|
||||
}
|
||||
}
|
||||
--cb_reqs_inflight;
|
||||
memcpy(buf, cb_req, buf_len);
|
||||
|
|
|
|||
Loading…
Reference in a new issue