summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorAndrei Danaila <adanaila@codeaurora.org>2014-12-03 10:27:26 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:11:04 -0700
commitb4fae7723729aae13fe3753c8b5892db2f65cfba (patch)
tree475b0da9fa963c647dff6ee3c66b0e8158d93f27 /drivers/platform
parentfd631cba6d2ecc2cd39b3de4665e580451822e71 (diff)
mhi: uci: Fix race conditon in mhi_poll_inbound
A race condition exists in MHI_UCI whereby a client could receive a buffer, inconsistent with the return code from MHI. Change-Id: I4a932ea608ce967c1588f092c60d03747bad2064 Signed-off-by: Andrei Danaila <adanaila@codeaurora.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/mhi/mhi_main.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/platform/msm/mhi/mhi_main.c b/drivers/platform/msm/mhi/mhi_main.c
index d772b6e12f4a..f8e59b2c8d3e 100644
--- a/drivers/platform/msm/mhi/mhi_main.c
+++ b/drivers/platform/msm/mhi/mhi_main.c
@@ -1302,20 +1302,22 @@ int mhi_poll_inbound(struct mhi_client_handle *client_handle,
(union mhi_xfer_pkt *)pending_trb);
result->flags = pending_trb->info;
result->transaction_status = MHI_STATUS_SUCCESS;
+ ret_val = delete_element(local_chan_ctxt,
+ &local_chan_ctxt->ack_rp,
+ &local_chan_ctxt->rp, NULL);
+ if (ret_val != MHI_STATUS_SUCCESS) {
+ mhi_log(MHI_MSG_ERROR,
+ "Internal Failure, inconsistent ring state, ret %d chan %d\n",
+ ret_val, chan);
+ result->payload_buf = 0;
+ result->bytes_xferd = 0;
+ result->transaction_status = MHI_STATUS_ERROR;
+ }
} else {
result->payload_buf = 0;
result->bytes_xferd = 0;
result->transaction_status = MHI_STATUS_SUCCESS;
- }
- ret_val = delete_element(local_chan_ctxt, &local_chan_ctxt->ack_rp,
- &local_chan_ctxt->rp, NULL);
- if (ret_val != MHI_STATUS_SUCCESS) {
- mhi_log(MHI_MSG_ERROR,
- "Failed to remove from inbound ring ret %d chan %d\n",
- ret_val, chan);
- result->payload_buf = 0;
- result->bytes_xferd = 0;
- result->transaction_status = MHI_STATUS_SUCCESS;
+ ret_val = MHI_STATUS_RING_EMPTY;
}
mutex_unlock(chan_mutex);
return ret_val;