From: sashiko-bot@kernel.org
To: "Rosen Penev" <rosenp@gmail.com>
Cc: Frank.Li@kernel.org, dmaengine@vger.kernel.org, vkoul@kernel.org
Subject: Re: [PATCHv3 5/8] dmaengine: ti: omap-dma: disable IRQs on probe failure
Date: Wed, 03 Jun 2026 03:21:38 +0000 [thread overview]
Message-ID: <20260603032138.A4E3C1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260603030754.288757-6-rosenp@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing `return rc;` in the `of_dma_controller_register` error path causes probe to fall through and register a CPU PM notifier using memory that will subsequently be freed.
- [High] Missing `cpu_pm_unregister_notifier` on module removal for configurations with `needs_busy_check`, leading to a dangling PM notifier.
- [High] Wrong interrupt enable register (`IRQENABLE_L0`) is cleared during `omap_dma_remove`, risking an unhandled IRQ storm.
- [High] Division by zero in SG transfer preparation if `maxburst` is configured to 0.
--
commit 2fb0d3495f0f7caa9bb739f8dcae6f87cb0dcd07
Author: Rosen Penev <rosenp@gmail.com>
Subject: dmaengine: ti: omap-dma: disable IRQs on probe failure
The probe failure paths after IRQ setup free channel state while hardware
interrupts can still be enabled. A concurrent interrupt can then walk
lch_map[] and access channel memory that teardown is releasing. Disable
IRQENABLE_L1 and clear irq_enable_mask under irq_lock before teardown,
then read IRQENABLE_L1 back to flush the posted write.
> diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
> index 55ece7fd0d99a..a5dc07bcbeb87 100644
> --- a/drivers/dma/ti/omap-dma.c
> +++ b/drivers/dma/ti/omap-dma.c
[ ... ]
> @@ -1825,6 +1832,13 @@ static int omap_dma_probe(struct platform_device *pdev)
> if (rc) {
> pr_warn("OMAP-DMA: failed to register DMA controller\n");
> dma_async_device_unregister(&od->ddev);
> + if (!omap_dma_legacy(od)) {
> + spin_lock_irq(&od->irq_lock);
> + od->irq_enable_mask = 0;
> + omap_dma_glbl_write(od, IRQENABLE_L1, 0);
> + spin_unlock_irq(&od->irq_lock);
> + omap_dma_glbl_read(od, IRQENABLE_L1);
> + }
> if (od->ll123_supported)
> dma_pool_destroy(od->desc_pool);
> omap_dma_free(od);
> }
[Severity: High]
This is a pre-existing issue, but shouldn't this error path in
omap_dma_probe() return the error code?
If of_dma_controller_register() fails, the code frees the resources and
cleans up, but execution falls through instead of returning. It then proceeds
to register a CPU PM notifier on the newly freed memory:
drivers/dma/ti/omap-dma.c:omap_dma_probe() {
...
if (od->cfg->needs_busy_check) {
od->nb.notifier_call = omap_dma_busy_notifier;
cpu_pm_register_notifier(&od->nb);
...
}
When devres releases the od structure, od->nb will become a dangling
pointer, which could cause a use-after-free on the next CPU power transition.
[ ... ]
[Severity: High]
This isn't a bug introduced by this patch, but does omap_dma_remove()
correctly unregister the CPU PM notifier in all configurations?
In omap_dma_probe(), the notifier is conditionally registered like this:
drivers/dma/ti/omap-dma.c:omap_dma_probe() {
...
if (od->cfg->needs_busy_check) {
od->nb.notifier_call = omap_dma_busy_notifier;
cpu_pm_register_notifier(&od->nb);
} else if (od->cfg->may_lose_context) {
od->nb.notifier_call = omap_dma_context_notifier;
cpu_pm_register_notifier(&od->nb);
}
...
}
But in omap_dma_remove(), it only unregisters if may_lose_context is true:
drivers/dma/ti/omap-dma.c:omap_dma_remove() {
...
if (od->cfg->may_lose_context)
cpu_pm_unregister_notifier(&od->nb);
...
}
If needs_busy_check is true and may_lose_context is false, the notifier is
never unregistered, leaving a dangling pointer when the module is removed.
[ ... ]
[Severity: High]
This is a pre-existing issue, but does omap_dma_remove() disable the correct
interrupt enable register?
During omap_dma_remove(), the code attempts to disable interrupts:
drivers/dma/ti/omap-dma.c:omap_dma_remove() {
...
if (!omap_dma_legacy(od)) {
/* Disable all interrupts */
omap_dma_glbl_write(od, IRQENABLE_L0, 0);
}
...
}
The driver configures interrupts on IRQENABLE_L1 during probe and channel
allocation. By clearing IRQENABLE_L0 instead, active channels remain enabled in
IRQENABLE_L1. After the IRQ handler is unregistered, any pending hardware
interrupt could cause an unhandled IRQ storm.
[ ... ]
[Severity: High]
This isn't a bug introduced by this patch, but could a client passing 0 for
maxburst cause a division by zero in omap_dma_prep_slave_sg()?
In omap_dma_prep_slave_sg(), the burst variable is initialized directly from
the client's configuration:
drivers/dma/ti/omap-dma.c:omap_dma_prep_slave_sg() {
...
if (dir == DMA_DEV_TO_MEM) {
...
burst = c->cfg.src_maxburst;
...
en = burst;
frame_bytes = es_bytes[es] * en;
...
}
Later in the scatterlist loop, frame_bytes is used in a division:
drivers/dma/ti/omap-dma.c:omap_dma_prep_slave_sg() {
...
for_each_sg(sgl, sgent, sglen, i) {
struct omap_sg *osg = &d->sg[i];
...
osg->fn = sg_dma_len(sgent) / frame_bytes;
...
}
If a client passes 0 for maxburst, frame_bytes will be 0, leading to an
unhandled division by zero.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260603030754.288757-6-rosenp@gmail.com?part=1
next prev parent reply other threads:[~2026-06-03 3:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 3:07 [PATCH v3 0/8] dmaengine: ti: omap-dma: probe/remove bug fixes and cleanup Rosen Penev
2026-06-03 3:07 ` [PATCHv3 1/8] dmaengine: ti: omap-dma: fix missing return in probe error path Rosen Penev
2026-06-03 3:18 ` sashiko-bot
2026-06-03 3:07 ` [PATCHv3 2/8] dmaengine: ti: omap-dma: synchronize CPU PM notifier removal Rosen Penev
2026-06-03 3:18 ` sashiko-bot
2026-06-03 3:07 ` [PATCHv3 3/8] dmaengine: ti: omap-dma: fix CPU PM notifier leak Rosen Penev
2026-06-03 3:07 ` [PATCHv3 4/8] dmaengine: ti: omap-dma: stop channels during teardown Rosen Penev
2026-06-03 3:25 ` sashiko-bot
2026-06-03 3:07 ` [PATCHv3 5/8] dmaengine: ti: omap-dma: disable IRQs on probe failure Rosen Penev
2026-06-03 3:21 ` sashiko-bot [this message]
2026-06-03 3:07 ` [PATCHv3 6/8] dmaengine: ti: omap-dma: destroy descriptor pool last Rosen Penev
2026-06-03 3:07 ` [PATCHv3 7/8] dmaengine: ti: omap-dma: fix interrupt handling in remove Rosen Penev
2026-06-03 3:07 ` [PATCHv3 8/8] dmaengine: ti: omap-dma: turn lch_map into a flexible array Rosen Penev
2026-06-03 3:23 ` 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=20260603032138.A4E3C1F00893@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=rosenp@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.