Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: a2e2cc0dbb11 ("net: qrtr: Start MHI channels during init")
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
Reviewed-by: Hemant Kumar <quic_hemantk@quicinc.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Maxim Kochetkov and committed by
David S. Miller
68a838b8 77788567

+7 -5
+7 -5
net/qrtr/mhi.c
··· 78 78 struct qrtr_mhi_dev *qdev; 79 79 int rc; 80 80 81 - /* start channels */ 82 - rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); 83 - if (rc) 84 - return rc; 85 - 86 81 qdev = devm_kzalloc(&mhi_dev->dev, sizeof(*qdev), GFP_KERNEL); 87 82 if (!qdev) 88 83 return -ENOMEM; ··· 90 95 rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); 91 96 if (rc) 92 97 return rc; 98 + 99 + /* start channels */ 100 + rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); 101 + if (rc) { 102 + qrtr_endpoint_unregister(&qdev->ep); 103 + return rc; 104 + } 93 105 94 106 dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); 95 107