From: sashiko-bot@kernel.org
To: "Logan Gunthorpe" <logang@deltatee.com>
Cc: Frank.Li@kernel.org, dmaengine@vger.kernel.org, vkoul@kernel.org,
linux-pci@vger.kernel.org
Subject: Re: [PATCH v5 07/12] dmaengine: switchtec-dma: fix chan_status_irq cleanup on create() error
Date: Mon, 31 Aug 2026 22:35:11 +0000 [thread overview]
Message-ID: <20260831223512.26BB71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260831191403.207631-8-logang@deltatee.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
Pre-existing issues:
- [High] Unchecked return value of ioremap() can lead to a NULL pointer dereference.
- [High] Interrupt handler is registered before the DMA channels list is initialized, risking a NULL pointer dereference.
- [High] DMA device is unregistered after channels and IRQs are torn down.
- [High] Holding a spinlock while busy-waiting for up to 100 milliseconds disables preemption for an unacceptable duration, potentially causing RCU stalls or soft lockups.
- [Medium] The return value of dma_set_mask_and_coherent() is ignored.
- [Medium] Missing put_device() causes reference count leak on the device structure in the error path of switchtec_dma_create().
--
commit 789f2f9ebf1e9dd9f52e2557e403d93f922154be
Author: Logan Gunthorpe <logang@deltatee.com>
Subject: dmaengine: switchtec-dma: fix chan_status_irq cleanup on create() error
This commit ensures that chan_status_irq is properly cleaned up on error by
using pci_free_irq() instead of free_irq(). It also initializes the IRQ vector
index to -1 so that a valid index of 0 is no longer skipped during cleanup.
Link: https://lore.kernel.org/dmaengine/20260717223431.625EE1F000E9@smtp.kernel.org
> diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
> index c30530ba78caf..3068d9de4e6d3 100644
> --- a/drivers/dma/switchtec_dma.c
> +++ b/drivers/dma/switchtec_dma.c
> @@ -1262,6 +1262,8 @@ static int switchtec_dma_create(struct pci_dev *pdev)
> if (!swdma_dev)
> return -ENOMEM;
>
> + swdma_dev->chan_status_irq = -1;
> +
> swdma_dev->bar = ioremap(pci_resource_start(pdev, 0),
> pci_resource_len(pdev, 0));
[Severity: High]
This is a pre-existing issue, but shouldn't we check the return value of
ioremap() here?
If ioremap() fails, swdma_dev->bar will be NULL. The code immediately proceeds
to dereference it via readw(swdma_dev->bar + SWITCHTEC_REG_CHAN_STS_VEC). Can
this lead to a NULL pointer dereference and kernel panic during device probe?
[ ... ]
> err_exit:
> - if (swdma_dev->chan_status_irq)
> - free_irq(swdma_dev->chan_status_irq, swdma_dev);
> + if (swdma_dev->chan_status_irq >= 0)
> + pci_free_irq(pdev, swdma_dev->chan_status_irq, swdma_dev);
>
> iounmap(swdma_dev->bar);
> kfree(swdma_dev);
> return rc;
[Severity: Medium]
This is a pre-existing issue, but does this error path leak the device
reference?
Earlier in switchtec_dma_create(), a reference is acquired:
dma->dev = get_device(&pdev->dev);
If dma_async_device_register() fails, the code jumps to
err_chans_release_exit and eventually falls through to err_exit, but
put_device(dma->dev) is never called. Since the device wasn't successfully
registered, switchtec_dma_release() won't be called to drop this reference.
In drivers/dma/switchtec_dma.c:switchtec_dma_probe():
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
rc = pci_request_mem_regions(pdev, KBUILD_MODNAME);
[Severity: Medium]
This is a pre-existing issue, but is the return value of
dma_set_mask_and_coherent() intentionally ignored here?
If the platform or IOMMU rejects the 64-bit mask, this function can fail.
Should the driver check the return value and gracefully fallback to 32-bit
DMA or fail the probe to prevent silent data corruption or IOMMU faults?
In drivers/dma/switchtec_dma.c:switchtec_dma_create():
rc = pci_request_irq(pdev, irq, NULL, switchtec_dma_chan_status_isr,
swdma_dev, KBUILD_MODNAME);
if (rc)
goto err_exit;
[Severity: High]
This is a pre-existing issue, but does registering the interrupt handler here
risk a NULL pointer dereference?
Later in switchtec_dma_create(), switchtec_dma_chans_enumerate() is called,
which initializes the dma->channels list:
INIT_LIST_HEAD(&dma->channels);
At the time of IRQ registration, swdma_dev was allocated with kzalloc_obj(),
meaning dma_dev->channels.next is NULL. If an interrupt fires immediately
after registration, switchtec_dma_chan_status_isr() will execute:
list_for_each_entry(chan, &dma_dev->channels, device_node) {
Since the list head is zeroed, this loop could underflow and dereference an
invalid pointer, leading to a kernel oops.
In drivers/dma/switchtec_dma.c:switchtec_dma_remove():
switchtec_dma_chans_release(pdev, swdma_dev);
rcu_assign_pointer(swdma_dev->pdev, NULL);
synchronize_rcu();
pci_free_irq(pdev, swdma_dev->chan_status_irq, swdma_dev);
pci_free_irq_vectors(pdev);
dma_async_device_unregister(&swdma_dev->dma_dev);
[Severity: High]
This is a pre-existing issue, but is the DMA device unregistered too late in
the teardown process?
The driver initiates hardware teardown by stopping channels and freeing IRQs
before calling dma_async_device_unregister(). Tearing down hardware and IRQs
while the device is still exposed to the DMA engine subsystem can lead to
use-after-free, hanging clients, or hardware access races if a client
actively uses the DMA device during removal. Should the subsystem be
unregistered first?
In drivers/dma/switchtec_dma.c:wait_for_chan_status():
return readl_poll_timeout_atomic(&chan_hw->status, status,
(set && (status & mask)) ||
(!set && !(status & mask)),
10, 100 * USEC_PER_MSEC);
[Severity: High]
This is a pre-existing issue, but could this atomic poll loop cause soft
lockups or RCU stalls?
This function is called from halt_channel() while holding a spinlock:
spin_lock(&swdma_chan->hw_ctrl_lock);
writeb(SWITCHTEC_CHAN_CTRL_HALT, &chan_hw->ctrl);
ret = wait_for_chan_status(chan_hw, SWITCHTEC_CHAN_STS_HALTED, true);
spin_unlock(&swdma_chan->hw_ctrl_lock);
Since holding a spinlock disables preemption, blocking the CPU for up to 100
milliseconds without preemption could severely degrade system latency.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260831191403.207631-1-logang@deltatee.com?part=7
next prev parent reply other threads:[~2026-08-31 22:35 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 19:13 [PATCH v5 00/12] dmaengine: miscellaneous fixes for ioat, switchtec_dma and plx_dma Logan Gunthorpe
2026-08-31 19:13 ` [PATCH v5 01/12] dmaengine: switchtec-dma: fix double-free in switchtec_dma_free_desc() Logan Gunthorpe
2026-08-31 21:28 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 02/12] dmaengine: switchtec-dma: fix resource leak in alloc_chan_resources Logan Gunthorpe
2026-08-31 21:38 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 03/12] dmaengine: switchtec-dma: always clear DMA base registers on chan_stop() Logan Gunthorpe
2026-08-31 21:51 ` sashiko-bot
2026-08-31 22:43 ` Logan Gunthorpe
2026-08-31 19:13 ` [PATCH v5 04/12] dmaengine: switchtec-dma: halt channel on alloc_chan_resources error Logan Gunthorpe
2026-08-31 22:04 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 05/12] dmaengine: switchtec-dma: fix channel leak on registration failure Logan Gunthorpe
2026-08-31 22:18 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 06/12] dmaengine: switchtec-dma: make switchtec_dma_chans_release() void Logan Gunthorpe
2026-08-31 22:24 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 07/12] dmaengine: switchtec-dma: fix chan_status_irq cleanup on create() error Logan Gunthorpe
2026-08-31 22:35 ` sashiko-bot [this message]
2026-08-31 19:13 ` [PATCH v5 08/12] dmaengine: switchtec-dma: disable channels before freeing on registration failure Logan Gunthorpe
2026-08-31 22:50 ` sashiko-bot
2026-08-31 19:13 ` [PATCH v5 09/12] dmaengine: switchtec-dma: fix use-after-free of swdma_dev in remove() Logan Gunthorpe
2026-08-31 23:04 ` sashiko-bot
2026-08-31 19:14 ` [PATCH v5 10/12] dmaengine: ioat: disable relaxed ordering before registering the device Logan Gunthorpe
2026-08-31 23:13 ` sashiko-bot
2026-08-31 19:14 ` [PATCH v5 11/12] dmaengine: ioat: use sysfs_emit() in per-channel sysfs show() Logan Gunthorpe
2026-08-31 23:19 ` sashiko-bot
2026-08-31 19:14 ` [PATCH v5 12/12] dmaengine: plx_dma: fix NULL pointer deref in plx_dma_isr() Logan Gunthorpe
2026-08-31 23:30 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831223512.26BB71F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=logang@deltatee.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox