From nobody Sat Jul 25 19:30:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCC283932EA; Tue, 14 Jul 2026 12:08:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030938; cv=none; b=moQe7otc2H7O65jluY1N3do4M2v2OUxcyxReQvIYh9njA13+iHLbGHXY/8/gksMN1L8/Ou2ahGOkv7NWiAOAhZIl51z/RHv8P7JsdPt7GzKNIkeHjXplQ9BlakScIKLNBNGbbZ6XfrY4vGOR9HaxDu52bMS4znnkTNdkJyldG4Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030938; c=relaxed/simple; bh=gXZ0kfWQwe20nG1CyMHlfe7DegLPDEYaIMsWcXHUCCA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TFgqCR4FLMnIl71VvBuzUdoIby484lo4SrNS7wR9zAYJoevfyBr2piilznpDnDTju3wiKfEO/fRMqk1xK9TWCGSCN5Ti4czlSpGsDLy9jF7Ciqrmtngrnc7e4k929+W2aOZngbjtwhnspZBH/kedzIcMgA52Bv6OJmkp+57hHHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 108BE1F00A3A; Tue, 14 Jul 2026 12:08:52 +0000 (UTC) From: Manivannan Sadhasivam Date: Tue, 14 Jul 2026 14:08:32 +0200 Subject: [PATCH v2 1/3] dmaengine: dw-edma: Implement device_synchronize() callback Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260714-mhi-ep-flush-v2-1-b6a9db011e85@oss.qualcomm.com> References: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> In-Reply-To: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> To: Manivannan Sadhasivam , Vinod Koul , Frank Li , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Kishon Vijay Abraham I , Bjorn Helgaas Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2128; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=gXZ0kfWQwe20nG1CyMHlfe7DegLPDEYaIMsWcXHUCCA=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBqVibPBpXj3VkynQpUy6PTp0/uEgS3iefzI+E4d x62q/7AWguJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCalYmzwAKCRBVnxHm/pHO 9QQiCACjXyf+XO2z4Fc9k5RWTLCDxaeOgk4G2fvKMPu/BNLT/2UqYH+r+2kt4A5+h57xna8XUkZ 6XooahzqatkOFcvjOeBIwOD7LNA1oStZP03kNlIadMutRYehD6mwf94Jsj89B7aLo7IRkVTairO 3Y5yGCVYu9C9DDHc0vnrew76+SeHUeQ21/8y8NkTj6p1gUUCjITqytm+eL6p4WXdFT1ERiPYOEz 3cAdVF6MKOK2pfLQOhKQa2bWMxDIq7DkAuW4eM5zNPshR5jHftS2p7cRikkXUMx9ckmKiB/lOaB lFw5n/S3Sc3QAXPOG8VETxuKMaPd7+QSOGOlpJJNwYuzXzEU X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 device_synchronize() callback is required by the client drivers to ensure all the DMA operations are completed so that they can free the memory associated with the complete callbacks. So implement this callback by first making sure that all the in-flight DMA operations are completed and then call vchan_synchronize() to drain the DMA tasklet. Signed-off-by: Manivannan Sadhasivam --- drivers/dma/dw-edma/dw-edma-core.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-ed= ma-core.c index c2feb3adc79f..df0d1a946ed0 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -331,6 +332,20 @@ static int dw_edma_device_terminate_all(struct dma_cha= n *dchan) return err; } =20 +static void dw_edma_device_synchronize(struct dma_chan *dchan) +{ + struct dw_edma_chan *chan =3D dchan2dw_edma_chan(dchan); + + /* + * Make sure all the in-flight DMA operations are completed before + * draining the tasklet using vchan_synchronize(). + */ + read_poll_timeout(READ_ONCE, chan->status, chan->status !=3D EDMA_ST_BUSY, + 10, 0, false, chan->status); + + vchan_synchronize(&chan->vc); +} + static void dw_edma_device_issue_pending(struct dma_chan *dchan) { struct dw_edma_chan *chan =3D dchan2dw_edma_chan(dchan); @@ -968,6 +983,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u3= 2 wr_alloc, u32 rd_alloc) dma->device_pause =3D dw_edma_device_pause; dma->device_resume =3D dw_edma_device_resume; dma->device_terminate_all =3D dw_edma_device_terminate_all; + dma->device_synchronize =3D dw_edma_device_synchronize; dma->device_issue_pending =3D dw_edma_device_issue_pending; dma->device_tx_status =3D dw_edma_device_tx_status; dma->device_prep_slave_sg =3D dw_edma_device_prep_slave_sg; --=20 2.43.0 From nobody Sat Jul 25 19:30:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 26027390C9A; Tue, 14 Jul 2026 12:09:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030942; cv=none; b=M+xblS500C4c5nYCTWq9a7WOatMmBEabsRQpnGHYNhiplmFLGDAfl2Qr1IJh7kdoMYHTxfMLgEmACfJSJnOgnJYuUrRdrOcWGgooU0KM3GHNcqFBqaCqUk0Mui7o+7Q0wK+ZJGgTvrZBlqk47QTlKxxaKvKTC+rqsO5n2ji0YZw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030942; c=relaxed/simple; bh=DoH7hPNg0fHxC+lCNJKTY0zrXTBD6EGE6jTVdxWvpPg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XFwaKw+rTsSP0KAQRDO6hyyJToCKfWKAokIAIq9rQxmbdbkcpiXHLnJ10DY1d7IxthexNUsLFGgFPJ2y2HZLzcOySYAVAMQpus+FxpxKcJxW9FJPHMTXFPAov4O68GwIXJSCFvaKuQUdGUgFqWTdV9zaR5uiBG0IKFqqWA0xLcw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1859D1F000E9; Tue, 14 Jul 2026 12:08:56 +0000 (UTC) From: Manivannan Sadhasivam Date: Tue, 14 Jul 2026 14:08:33 +0200 Subject: [PATCH v2 2/3] bus: mhi: ep: Add mhi_cntrl->flush_async() callback to flush the async read/write Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260714-mhi-ep-flush-v2-2-b6a9db011e85@oss.qualcomm.com> References: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> In-Reply-To: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> To: Manivannan Sadhasivam , Vinod Koul , Frank Li , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Kishon Vijay Abraham I , Bjorn Helgaas Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, Manivannan Sadhasivam , stable+noautosel@kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3321; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=DoH7hPNg0fHxC+lCNJKTY0zrXTBD6EGE6jTVdxWvpPg=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBqVibPwrOb4UYlQc3nLzYN/rTvy06oXd6q/uuUU lv9p3g4Vl2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCalYmzwAKCRBVnxHm/pHO 9bGWB/9ajfMPV4GSG3rHDRUogdaSu/zlpYJSOm0A49KP4UbNIa9y44rUsHZfNjrgRLYF25D3HmJ 1nwF+maOh8NajFu+JH8MC/y4kdbB0wTR6WUunVdB+0yqLPDQ9xc+AxdxKI4/9rDA/r0ssN2/DSZ q56Vqt97yfDZ58f6fXVeLRG0yFKfUU93I84oxNYf6vtsMCMSKi+nHCbNUdtrABs+UEyL6+IaG0h /CvNAd30guZewPV1JvS+v3HPsfpf4ZjJFiKfcLhLeXnLPCeqkvx7DwsgAeHKUTFsgioKIWX9SVA 5+SJINYyDaZvkdjbTA9zAUp8VcyNE7SencCIF4N/VXDTUPBX X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 MHI EP stack makes use of the MHI controller drivers like MHI EPF to do read/write to the host memory. And that driver is free to use mechanisms like DMA to offload the read/write operations. So if DMA is used for offload, then there is no guarantee that those DMA operations would be completed by the time mhi_ep_remove() gets called. This can lead to UAF (Use-After-Free) issues as the DMA callback can trigger xfer_cb() even after mhi_ep_remove() has returned. So to fix this issue, introduce the mhi_cntrl->flush_async() callback and call it in mhi_ep_remove() before setting xfer_cb to NULL. Note that flush_async() blocks until all the in-flight async transfers are completed, so calling it with the chan->lock held would needlessly stall the transfer paths on that channel for the whole duration of the drain. So drop chan->lock around the flush and clear xfer_cb() only afterwards, once all the pending completions are drained. Cc: # Needs dmaengine driver fix as well Fixes: 2547beb00ddb ("bus: mhi: ep: Add support for async DMA read operatio= n") Fixes: ee08acb58fe4 ("bus: mhi: ep: Add support for async DMA write operati= on") Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 7 +++++++ include/linux/mhi_ep.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 0277e1ab1198..329a4855d397 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1612,6 +1612,7 @@ static void mhi_ep_remove(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); struct mhi_ep_driver *mhi_drv =3D to_mhi_ep_driver(dev->driver); + struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; struct mhi_result result =3D {}; struct mhi_ep_chan *mhi_chan; int dir; @@ -1636,6 +1637,12 @@ static void mhi_ep_remove(struct device *dev) } =20 mhi_chan->state =3D MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + + if (mhi_cntrl->flush_async) + mhi_cntrl->flush_async(mhi_cntrl); + + mutex_lock(&mhi_chan->lock); mhi_chan->xfer_cb =3D NULL; mutex_unlock(&mhi_chan->lock); } diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 7b40fc8cbe77..f6383a57a872 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -107,6 +107,7 @@ struct mhi_ep_buf_info { * @write_sync: CB function for writing to host memory synchronously * @read_async: CB function for reading from host memory asynchronously * @write_async: CB function for writing to host memory asynchronously + * @flush_async: CB function for flushing asynchronous read/writes * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by the endpoint controller * @mru: MRU (Maximum Receive Unit) value of the endpoint controller @@ -164,6 +165,7 @@ struct mhi_ep_cntrl { int (*write_sync)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info = *buf_info); int (*read_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info = *buf_info); int (*write_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info= *buf_info); + void (*flush_async)(struct mhi_ep_cntrl *mhi_cntrl); =20 enum mhi_state mhi_state; =20 --=20 2.43.0 From nobody Sat Jul 25 19:30:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFB0339B94A; Tue, 14 Jul 2026 12:09:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030947; cv=none; b=fkTuEeHB/uAIZMZnEXneQqFVZIqsN3nm3NesEQNNIb4CZE4I5pI8h9JNz/6RuzrNoTrWM+5c+KnBsO8CAi128LUnkX40PWY9C5z+2ZcsvenqwNUMevXPK3MEY/ge6iNPkLGNSGjDsrVj5RfNtXOz7CfSUjmiwgxW5aZuwpCb+Iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784030947; c=relaxed/simple; bh=qLqfbvmjnz3X26mpqAuThVFaSvP9MX15HVPTE+SgzCA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D/h95vM2+IENwcqoyltaV9ORI6e5bBkWbgArqEUhqUHgpucElJZAR0hfVscreuvnPpKSbANIOiLPwuh7pnshVBiHUo6l2WnMg8Zn4ap/vNSQSHud0g0GA19o90lgGKBqG/RrbAEw7yMbGJjHHsygcYtJzeAOFVZmtip7jrMY4wk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3C591F00A3D; Tue, 14 Jul 2026 12:09:01 +0000 (UTC) From: Manivannan Sadhasivam Date: Tue, 14 Jul 2026 14:08:34 +0200 Subject: [PATCH v2 3/3] PCI: epf-mhi: Implement mhi_cntrl->flush_async() to flush DMA read/write Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260714-mhi-ep-flush-v2-3-b6a9db011e85@oss.qualcomm.com> References: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> In-Reply-To: <20260714-mhi-ep-flush-v2-0-b6a9db011e85@oss.qualcomm.com> To: Manivannan Sadhasivam , Vinod Koul , Frank Li , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Kishon Vijay Abraham I , Bjorn Helgaas Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1534; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=qLqfbvmjnz3X26mpqAuThVFaSvP9MX15HVPTE+SgzCA=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBqVibQ2+h95kLAUBf3P96wpgqFqfpDTkUbjFhHE VtyFhIMHseJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCalYm0AAKCRBVnxHm/pHO 9UnGCACadmnTY70mIwm6+exLoH0fGJYpDVbVCCp7NakpdS92kPSOsLqqaEzBwUfko/ThMdMYGOG H9gR0WkTaMQI5au0WodS8dRH2+OdbGgSQC2PBTDOQjOO40tDVi8myEQB2xdJ+P42WFGWSBxR8iB HeSbDPPh1dSjvB/DgOQ5EBqHwX8zvzCaJHbaXt7ceA+fXPhHXjQ1ikb72syU0dL53FUJv0VRS0p PiMJ08NR9PGufghFwUie17+KZhSJQfGBQCGG69++sA7b2QRwY7KTXuSE+33WNtgzSy93Z+DS5o9 QumRNRBEfMdIRDWyMbXtE7bbRSuCbhyAZijVCuKBnO8OJqSv X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 The MHI core needs to make sure that all the current DMA transactions are completed before removing the channels. So implement the mhi_cntrl->flush_async() callback by first making sure all the in-flight DMA operations are completed and then flushing the DMA workqueue. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/endpoint/functions/pci-epf-mhi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/end= point/functions/pci-epf-mhi.c index 7f5326925ed5..8d2d9d01cfd2 100644 --- a/drivers/pci/endpoint/functions/pci-epf-mhi.c +++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c @@ -644,6 +644,15 @@ static int pci_epf_mhi_edma_write_async(struct mhi_ep_= cntrl *mhi_cntrl, return ret; } =20 +static void pci_epf_mhi_edma_flush_async(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct pci_epf_mhi *epf_mhi =3D to_epf_mhi(mhi_cntrl); + + dmaengine_synchronize(epf_mhi->dma_chan_rx); + dmaengine_synchronize(epf_mhi->dma_chan_tx); + flush_workqueue(epf_mhi->dma_wq); +} + struct epf_dma_filter { struct device *dev; u32 dma_mask; @@ -812,6 +821,7 @@ static int pci_epf_mhi_link_up(struct pci_epf *epf) mhi_cntrl->write_sync =3D pci_epf_mhi_edma_write; mhi_cntrl->read_async =3D pci_epf_mhi_edma_read_async; mhi_cntrl->write_async =3D pci_epf_mhi_edma_write_async; + mhi_cntrl->flush_async =3D pci_epf_mhi_edma_flush_async; } =20 /* Register the MHI EP controller */ --=20 2.43.0