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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox