Skip to content

Commit 68a838b

Browse files
fidomaxdavem330
authored andcommitted
net: qrtr: start MHI channel after endpoit creation
MHI channel may generates event/interrupt right after enabling. It may leads to 2 race conditions issues. 1) Such event may be dropped by qcom_mhi_qrtr_dl_callback() at check: if (!qdev || mhi_res->transaction_status) return; Because dev_set_drvdata(&mhi_dev->dev, qdev) may be not performed at this moment. In this situation qrtr-ns will be unable to enumerate services in device. --------------------------------------------------------------- 2) Such event may come at the moment after dev_set_drvdata() and before qrtr_endpoint_register(). In this case kernel will panic with accessing wrong pointer at qcom_mhi_qrtr_dl_callback(): rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, mhi_res->bytes_xferd); Because endpoint is not created yet. -------------------------------------------------------------- So move mhi_prepare_for_transfer_autoqueue after endpoint creation to fix it. Fixes: a2e2cc0 ("net: qrtr: Start MHI channels during init") Signed-off-by: Maxim Kochetkov <[email protected]> Reviewed-by: Hemant Kumar <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Loic Poulain <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7778856 commit 68a838b

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

net/qrtr/mhi.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,6 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
7878
struct qrtr_mhi_dev *qdev;
7979
int rc;
8080

81-
/* start channels */
82-
rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
83-
if (rc)
84-
return rc;
85-
8681
qdev = devm_kzalloc(&mhi_dev->dev, sizeof(*qdev), GFP_KERNEL);
8782
if (!qdev)
8883
return -ENOMEM;
@@ -96,6 +91,13 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
9691
if (rc)
9792
return rc;
9893

94+
/* start channels */
95+
rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
96+
if (rc) {
97+
qrtr_endpoint_unregister(&qdev->ep);
98+
return rc;
99+
}
100+
99101
dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");
100102

101103
return 0;

0 commit comments

Comments
 (0)