diff options
author | Zhen Kong <zkong@codeaurora.org> | 2018-10-11 17:22:05 -0700 |
---|---|---|
committer | Sravanthi Palakonda <c_srapal@qti.qualcomm.com> | 2018-10-27 18:27:29 +0530 |
commit | 3eff2be91caf3ee4f0685072bd39694d6d697672 (patch) | |
tree | a8c1e4f4987ab3ad3674c89103ca106bcfa08755 | |
parent | c09eb0e1a68c512781389ac0534e0b3cdcd2c20e (diff) |
qseecom: do not wake up listener to receive request if it is not readyLA.UM.6.3.r4-05800-sdm845.0
Listener should not process the old pending listener request that
was received when listener is not ready, as shared buffer may be
locked at this time
Change-Id: Ib954143aa19c61b6a1a24206182cd8a8469546d2
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
-rw-r--r-- | drivers/misc/qseecom.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index d7bafd9fc392..d5bf7093ca1e 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -182,6 +182,7 @@ struct qseecom_registered_listener_list { size_t sb_length; struct ion_handle *ihandle; /* Retrieve phy addr */ wait_queue_head_t rcv_req_wq; + /* rcv_req_flag: -1: not ready; 0: ready and empty; 1: received req */ int rcv_req_flag; int send_resp_flag; bool listener_in_use; @@ -1202,7 +1203,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, if (!new_entry) return -ENOMEM; memcpy(&new_entry->svc, &rcvd_lstnr, sizeof(rcvd_lstnr)); - new_entry->rcv_req_flag = 0; + new_entry->rcv_req_flag = -1; new_entry->svc.listener_id = rcvd_lstnr.listener_id; new_entry->sb_length = rcvd_lstnr.sb_size; @@ -1638,21 +1639,20 @@ static void __qseecom_clean_listener_sglistinfo( } } -/* wake up listener receive request wq retry delay (ms) and max attemp count */ -#define QSEECOM_WAKE_LISTENER_RCVWQ_DELAY 10 -#define QSEECOM_WAKE_LISTENER_RCVWQ_MAX_ATTEMP 3 +/* wait listener retry delay (ms) and max attemp count */ +#define QSEECOM_WAIT_LISTENER_DELAY 10 +#define QSEECOM_WAIT_LISTENER_MAX_ATTEMP 3 -static int __qseecom_retry_wake_up_listener_rcv_wq( +static int __is_listener_rcv_wq_not_ready( struct qseecom_registered_listener_list *ptr_svc) { int retry = 0; - while (ptr_svc->rcv_req_flag == 1 && - retry++ < QSEECOM_WAKE_LISTENER_RCVWQ_MAX_ATTEMP) { - wake_up_interruptible(&ptr_svc->rcv_req_wq); - msleep(QSEECOM_WAKE_LISTENER_RCVWQ_DELAY); + while (ptr_svc->rcv_req_flag == -1 && + retry++ < QSEECOM_WAIT_LISTENER_MAX_ATTEMP) { + msleep(QSEECOM_WAIT_LISTENER_DELAY); } - return ptr_svc->rcv_req_flag == 1; + return ptr_svc->rcv_req_flag == -1; } static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, @@ -1683,6 +1683,8 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head, list) { if (ptr_svc->svc.listener_id == lstnr) { + if (__is_listener_rcv_wq_not_ready(ptr_svc)) + break; ptr_svc->listener_in_use = true; ptr_svc->rcv_req_flag = 1; wake_up_interruptible(&ptr_svc->rcv_req_wq); @@ -1723,14 +1725,15 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, goto err_resp; } - if (ptr_svc->rcv_req_flag == 1 && - __qseecom_retry_wake_up_listener_rcv_wq(ptr_svc)) { + if (ptr_svc->rcv_req_flag == -1) { pr_err("Service %d is not ready to receive request\n", lstnr); rc = -ENOENT; status = QSEOS_RESULT_FAILURE; goto err_resp; + } + pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); /* initialize the new signal mask with all signals*/ @@ -2003,6 +2006,8 @@ static int __qseecom_reentrancy_process_incomplete_cmd( list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head, list) { if (ptr_svc->svc.listener_id == lstnr) { + if (__is_listener_rcv_wq_not_ready(ptr_svc)) + break; ptr_svc->listener_in_use = true; ptr_svc->rcv_req_flag = 1; wake_up_interruptible(&ptr_svc->rcv_req_wq); @@ -2043,14 +2048,15 @@ static int __qseecom_reentrancy_process_incomplete_cmd( goto err_resp; } - if (ptr_svc->rcv_req_flag == 1 && - __qseecom_retry_wake_up_listener_rcv_wq(ptr_svc)) { + if (ptr_svc->rcv_req_flag == -1) { pr_err("Service %d is not ready to receive request\n", lstnr); rc = -ENOENT; status = QSEOS_RESULT_FAILURE; goto err_resp; + } + pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); /* initialize the new signal mask with all signals*/ @@ -3854,7 +3860,7 @@ static int __qseecom_listener_has_rcvd_req(struct qseecom_dev_handle *data, { int ret; - ret = (svc->rcv_req_flag != 0); + ret = (svc->rcv_req_flag == 1); return ret || data->abort || svc->abort; } @@ -3868,6 +3874,7 @@ static int qseecom_receive_req(struct qseecom_dev_handle *data) pr_err("Invalid listener ID\n"); return -ENODATA; } + this_lstnr->rcv_req_flag = 0; while (1) { if (wait_event_freezable(this_lstnr->rcv_req_wq, |