Re: [PATCH v2 34/64] dmaengine: mtk-cqdma: kill vchan BH on teardown
[email protected] Mon, 27 Jul 2026 21:09:13 +0000
| Newsgroups | org.kernel.vger.dmaengine |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: Pre-existing issues: - [High] Incorrect teardown order in mtk_cqdma_remove() allows physical channel tasklets to reschedule virtual channel bottom halves after they have been killed, leading to a use-after-free. - [High] Manual removal of channels from the DMA device channel list via list_del() before unregistration bypasses dmaengine cleanup, leaking memory and IDA indexes. - [High] The DMA device is registered before physical channel tasklets and hardware are initialized, allowing early interrupts to schedule uninitialized tasklets. -- --- Patch [34]: [PATCH v2 34/64] dmaengine: mtk-cqdma: kill vchan BH on teardown --- commit 94dd78bb3e2fc0bc1ffe5fdde7322901f8e3ea2c Author: Allen Pais <[email protected]> dmaengine: mtk-cqdma: kill vchan BH on teardown This patch updates the virt-dma channel cleanup in the MediaTek CQDMA driver to use the standard dma_chan_kill_bh() helper rather than directly calling tasklet_kill(). > diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c > index 80791e30aec24..3b0f1d8fa2055 100644 > --- a/drivers/dma/mediatek/mtk-cqdma.c > +++ b/drivers/dma/mediatek/mtk-cqdma.c > @@ -895,7 +895,7 @@ static void mtk_cqdma_remove(struct platform_device *pdev) > vc = &cqdma->vc[i]; > > list_del(&vc->vc.chan.device_node); [Severity: High] This isn't a bug introduced by this patch, but does calling list_del() here cause a memory and IDA index leak? By manually removing the channel from the dmaengine device list before calling dma_async_device_unregister(), the core subsystem's unregistration loop will see an empty list. This causes __dma_async_device_channel_unregister() to be skipped, which means free_percpu(), sysfs cleanup, and ida_free() are never executed. > - tasklet_kill(&vc->vc.task); > + dma_chan_kill_bh(&vc->vc.chan); [Severity: High] This is a pre-existing issue, but does this teardown order leave a window for a use-after-free? If a physical channel interrupt fires after dma_chan_kill_bh() is called but before the hardware interrupts are disabled and tasklets are killed below, the interrupt handler will schedule the physical channel tasklet. This tasklet processes completions and calls vchan_cookie_complete(), which re-queues the virtual channel bottom-half work. After mtk_cqdma_remove() returns, devres frees the cqdma device, leaving the re-queued work item referencing freed memory. Would it be safer to disable physical interrupts and kill tasklets before killing the virtual channel bottom halves? > } > > /* disable interrupt */ [ ... ] While reviewing this file, another pre-existing issue was noticed in mtk_cqdma_probe(): [Severity: High] This is a pre-existing issue, but is the DMA device registered before the physical channel tasklets and hardware are fully initialized? drivers/dma/mediatek/mtk-cqdma.c:mtk_cqdma_probe() { ... err = dma_async_device_register(dd); ... err = mtk_cqdma_hw_init(cqdma); ... for (i = 0; i < cqdma->dma_channels; ++i) tasklet_setup(&cqdma->pc[i]->tasklet, mtk_cqdma_tasklet_cb); ... } Once dma_async_device_register() is called, the controller is globally visible. If a client probes asynchronously and immediately requests a channel, it could trigger an early interrupt before tasklet_setup() completes, potentially dereferencing a NULL pointer for the uninitialized tasklet callback. -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=34