Re: [PATCH v2 49/64] dmaengine: hisi: kill vchan BH on teardown
[email protected] Mon, 27 Jul 2026 21:20:33 +0000
| Newsgroups | org.kernel.vger.dmaengine |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] Race condition during device teardown can lead to a use-after-free because the bottom-half work is killed before IRQs are synchronized, allowing a concurrent IRQ handler to reschedule the bottom-half work on freed memory. - [High] The driver requests shared IRQs before fully initializing virtual channel structures, risking an uninitialized spinlock access and null pointer dereference if a shared or spurious interrupt occurs early. -- --- Patch [49]: [PATCH v2 49/64] dmaengine: hisi: kill vchan BH on teardown --- commit f8a5265e01e8ff281f13c0af8c64babbb3148800 Author: Allen Pais <[email protected]> dmaengine: hisi: kill vchan BH on teardown This commit replaces tasklet_kill() with dma_chan_kill_bh() for virt-dma cleanup during device teardown. > diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c > index 28bf818f9aa63..39bc88c465138 100644 > --- a/drivers/dma/hisi_dma.c > +++ b/drivers/dma/hisi_dma.c > @@ -720,7 +720,7 @@ static void hisi_dma_disable_qps(struct hisi_dma_dev *hdma_dev) > > for (i = 0; i < hdma_dev->chan_num; i++) { > hisi_dma_disable_qp(hdma_dev, i); > - tasklet_kill(&hdma_dev->chan[i].vc.task); > + dma_chan_kill_bh(&hdma_dev->chan[i].vc.chan); [Severity: High] This is a pre-existing issue, but does this teardown sequence leave us open to a use-after-free regression? During device unbind, devres executes hisi_dma_disable_hw_channels() which calls hisi_dma_disable_qps(). However, devm_free_irq() hasn't been called yet. If hisi_dma_irq() is concurrently executing on another CPU, it can call vchan_cookie_complete(): drivers/dma/hisi_dma.c:hisi_dma_irq() { ... vchan_cookie_complete(&desc->vd); ... } This can schedule the bottom half after dma_chan_kill_bh() has already flushed it. When devres subsequently frees the device memory, could the scheduled bottom half execute on the freed channel structure? > } > } [Severity: High] This isn't a bug introduced by this patch, but is it possible for a shared interrupt to fire before the channel structures are fully initialized? In hisi_dma_enable_hw_channels(), the driver requests shared IRQs before calling hisi_dma_enable_qps(), which initializes the channels: drivers/dma/hisi_dma.c:hisi_dma_enable_hw_channels() { ... ret = hisi_dma_request_qps_irq(hdma_dev); ... } If a shared or spurious interrupt fires immediately, hisi_dma_irq() would execute and dereference an uninitialized pointer and lock: drivers/dma/hisi_dma.c:hisi_dma_irq() { ... struct hisi_dma_dev *hdma_dev = chan->hdma_dev; ... spin_lock(&chan->vc.lock); ... } Could this lead to a NULL pointer dereference or uninitialized lock access? -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=49