From: sashiko-bot@kernel.org
To: "Benoît Monin" <benoit.monin@bootlin.com>
Cc: imx@lists.linux.dev, Frank.Li@kernel.org, vkoul@kernel.org,
dmaengine@vger.kernel.org
Subject: Re: [PATCH v10 1/2] dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec
Date: Fri, 11 Sep 2026 13:27:56 +0000 [thread overview]
Message-ID: <20260911132756.8B36F1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260911-fsl-edma-dyn-sg-v10-1-700eb72def57@bootlin.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [Critical] Kernel panic: Modulo by zero during unaligned DMA_DEV_TO_DEV burst calculation.
- [Critical] Arbitrary DMA Execution: 0-length vector triggers out-of-bounds read at tcd[0].
- [High] Data corruption: Missing multi-FIFO offset causes negative address drift.
- [Medium] Logic Error: Unreset burst size artificially breaches FIELD_MAX limit.
Pre-existing issues:
- [High] Kernel panic: DMA_NONE direction mapping triggers BUG_ON.
--
commit 084b4b0f402eb171d6adefd8fa18c7fa25e129fb
Author: Benoît Monin <benoit.monin@bootlin.com>
dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec
This commit adds the implementation of the .device_prep_peripheral_dma_vec()
callback to setup a scatter/gather DMA transfer from an array of dma_vec
structures. It also supports cyclic transfers if the DMA_PREP_REPEAT flag
is set.
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index bb7531c456dfa..c5f5951c988be 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -673,6 +673,122 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
> return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
> }
>
> +struct dma_async_tx_descriptor *
> +fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan, const struct dma_vec *vecs,
> + size_t nb, enum dma_transfer_direction direction,
> + unsigned long flags)
> +{
> + struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> + dma_addr_t src_addr, dst_addr, last_sg;
> + struct fsl_edma_desc *fsl_desc;
> + u16 soff, doff, iter;
> + u32 nbytes;
> + int i;
> +
> + if (!is_slave_direction(direction))
> + return NULL;
> +
> + if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
> + return NULL;
[Severity: High]
This is a pre-existing issue, but does passing DMA_DEV_TO_DEV to
fsl_edma_prep_slave_dma() cause a kernel panic?
If a driver requests a DMA_DEV_TO_DEV transfer, fsl_edma_prep_slave_dma()
handles it by mapping the resource with dma_dir = DMA_NONE. The core DMA
mapping API (dma_map_phys via dma_map_resource) asserts
BUG_ON(!valid_dma_direction(dir)), which leads to an intentional kernel
crash.
> +
> + fsl_desc = fsl_edma_alloc_desc(fsl_chan, nb);
> + if (!fsl_desc)
> + return NULL;
[Severity: Critical]
Is it possible for a caller to pass nb == 0 here?
If nb is 0, fsl_edma_alloc_desc() allocates an empty descriptor with
n_tcds = 0. When the transfer is subsequently submitted via
fsl_edma_xfer_desc(), the engine unconditionally dereferences
fsl_chan->edesc->tcd[0].vtcd. Since tcd[0] is out-of-bounds, this will
result in a heap out-of-bounds read, potentially leading to arbitrary
DMA programming or a crash.
[ ... ]
> + for (i = 0; i < nb; i++) {
> + if (direction == DMA_MEM_TO_DEV) {
> + src_addr = vecs[i].addr;
> + dst_addr = fsl_chan->dma_dev_addr;
> + soff = fsl_chan->cfg.dst_addr_width;
> + doff = 0;
[Severity: High]
Can this hardcoded offset cause memory corruption for multi-FIFO endpoints?
When fsl_chan->is_multi_fifo is true, fsl_edma_fill_tcd() automatically
applies a negative Minor Loop Offset (MLOFF) equal to -burst. Because doff
is set to 0 here, the destination address does not advance during the minor
loop, but is still incorrectly pulled backwards by -burst at the end of
each minor loop. This causes the destination address to drift negatively.
[ ... ]
> + } else {
> + /* DMA_DEV_TO_DEV */
> + src_addr = fsl_chan->cfg.src_addr;
> + dst_addr = fsl_chan->cfg.dst_addr;
> + soff = 0;
> + doff = 0;
> + }
> +
> + /*
> + * Choose the suitable burst length if dma_vec length is not
> + * multiple of burst length so that the whole transfer length is
> + * multiple of minor loop(burst length).
> + */
> + if (nbytes && vecs[i].len % nbytes) {
> + u32 width = (direction == DMA_DEV_TO_MEM) ? doff : soff;
> + u32 burst = (direction == DMA_DEV_TO_MEM) ?
> + fsl_chan->cfg.src_maxburst :
> + fsl_chan->cfg.dst_maxburst;
> + int j;
> +
> + for (j = burst; j > 1; j--) {
> + if (!(vecs[i].len % (j * width))) {
[Severity: Critical]
Could this result in a modulo by zero for DMA_DEV_TO_DEV transfers?
For DMA_DEV_TO_DEV, both soff and doff are 0, which means width evaluates
to 0. If the vector length is unaligned, the modulo operator will evaluate
vecs[i].len % 0, causing an immediate kernel panic via division by zero.
> + nbytes = j * width;
> + break;
> + }
> + }
> + /* Set burst size as 1 if there's no suitable one */
> + if (j == 1)
> + nbytes = width;
> + }
> +
> + if (!nbytes || vecs[i].len / nbytes > FIELD_MAX(EDMA_TCD_ITER_MASK))
> + goto err_free_desc;
[Severity: Medium]
Will this erroneously reject valid transfers if nbytes is shrunk during an
earlier loop iteration?
When a vector length isn't a multiple of nbytes, nbytes is reduced to a
suitable factor. However, nbytes is never restored to its optimal value at
the start of the loop for the next vector. If a later vector in the array
is large, it will be divided by this artificially reduced nbytes, causing
the calculation to exceed FIELD_MAX(EDMA_TCD_ITER_MASK) and falsely aborting
the transfer setup.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260911-fsl-edma-dyn-sg-v10-0-700eb72def57@bootlin.com?part=1
next prev parent reply other threads:[~2026-09-11 13:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 13:11 [PATCH v10 0/2] dmaengine: fsl-edma: Scatter/gather improvements Benoît Monin
2026-09-11 13:11 ` [PATCH v10 1/2] dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec Benoît Monin
2026-09-11 13:27 ` sashiko-bot [this message]
2026-09-11 13:11 ` [PATCH v10 2/2] dmaengine: fsl-edma: Support dynamic scatter/gather chaining Benoît Monin
2026-09-11 13:23 ` sashiko-bot
2026-09-11 14:14 ` Frank Li
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=20260911132756.8B36F1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=benoit.monin@bootlin.com \
--cc=dmaengine@vger.kernel.org \
--cc=imx@lists.linux.dev \
--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.