From: sashiko-bot@kernel.org
To: "Claudiu Beznea" <claudiu.beznea@kernel.org>
Cc: Frank.Li@kernel.org, vkoul@kernel.org, dmaengine@vger.kernel.org,
wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v6 06/18] dmaengine: sh: rz-dmac: Save the start LM descriptor
Date: Tue, 26 May 2026 09:41:41 +0000 [thread overview]
Message-ID: <20260526094142.42FAF1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260526084710.3491480-7-claudiu.beznea@kernel.org>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] The newly introduced `start_lmdesc` field can be dereferenced while `NULL` in `rz_dmac_calculate_residue_bytes_in_vd()`.
Pre-existing issues:
- [High] Multiple MEMCPY transfers overwrite each other's hardware descriptors causing data corruption.
- [High] Missing `dma_wmb()` memory barrier before setting the Link Valid (`HEADER_LV`) bit in DMA descriptors.
- [High] Silent ring buffer overflow when preparing slave SG descriptors if the scatterlist exceeds 64 entries.
--
commit 1282aed7089327e34eb2eeee4b69973599e70406
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
dmaengine: sh: rz-dmac: Save the start LM descriptor
This commit saves the start LM descriptor in the channel's descriptor
structure to avoid unnecessary iterations from the beginning of the list
when calculating residue bytes.
> diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> index c48858b68dee6..d3926ecd63ac1 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
[ ... ]
> @@ -343,6 +344,8 @@ static void rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan *channel)
> struct rz_dmac_desc *d = channel->desc;
> u32 chcfg = CHCFG_MEM_COPY;
>
> + d->start_lmdesc = lmdesc;
> +
> /* prepare descriptor */
> lmdesc->sa = d->src;
> lmdesc->da = d->dest;
[Severity: High]
This isn't a bug introduced by this patch, but does
rz_dmac_prepare_desc_for_memcpy() overwrite hardware descriptors of an
already active memcpy transfer?
The transfer is configured at channel->lmdesc.tail, but the tail pointer is
never advanced (unlike in the slave_sg path). If rz_dmac_issue_pending()
is called while a memcpy transfer is already active, the new transfer is
prepared into the exact same channel->lmdesc.tail slot currently being read
by the active DMA hardware.
Can this cause memory corruption and unpredictable hardware behavior?
I note this is fixed later in the series in commit d09437d0a9b5a
("dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor
processing"), which adds a !channel->desc check.
[ ... ]
> @@ -377,6 +380,7 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channel)
> }
>
> lmdesc = channel->lmdesc.tail;
> + d->start_lmdesc = lmdesc;
>
> for (i = 0, sg = sgl; i < sg_len; i++, sg = sg_next(sg)) {
> if (d->direction == DMA_DEV_TO_MEM) {
[Severity: High]
This isn't a bug introduced by this patch, but does this loop lack a
bounds check for sg_len?
The driver iterates over sg_len without checking if it exceeds the hardware
ring buffer size (DMAC_NR_LMDESC, which is 64).
If a client submits a scatterlist with more than 64 entries, the loop will
wrap around and overwrite the beginning of the very same transfer it is
currently preparing.
Could this result in a corrupted DMA ring buffer and an infinite hardware
loop?
[Severity: High]
This is a pre-existing issue, but does setting the Link Valid (HEADER_LV)
bit require a dma_wmb() barrier?
The DMA descriptors (lmdesc) are allocated in coherent memory. The driver
writes the payload (sa, da, tb, chcfg) and then sets the HEADER_LV bit to
indicate to the hardware that the descriptor is ready:
rz_dmac_prepare_descs_for_slave_sg() {
...
lmdesc->tb = sg_dma_len(sg);
lmdesc->chitvl = 0;
lmdesc->chext = 0;
if (i == (sg_len - 1)) {
lmdesc->chcfg = (channel->chcfg & ~CHCFG_DEM);
lmdesc->header = HEADER_LV;
...
}
Because writes to Normal Non-Cacheable memory can be reordered by the CPU
write buffer, is a dma_wmb() barrier strictly required before setting
lmdesc->header = HEADER_LV?
Without it, if the hardware is executing the chain and polling for the
next descriptor, it might see the HEADER_LV bit set before the payload
writes have completed.
[ ... ]
> @@ -693,9 +697,10 @@ rz_dmac_get_next_lmdesc(struct rz_lmdesc *base, struct rz_lmdesc *lmdesc)
> return next;
> }
>
> -static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel, u32 crla)
> +static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel,
> + struct rz_dmac_desc *desc, u32 crla)
> {
> - struct rz_lmdesc *lmdesc = channel->lmdesc.head;
> + struct rz_lmdesc *lmdesc = desc->start_lmdesc;
[Severity: High]
Can desc->start_lmdesc be NULL here and cause a kernel panic when
accessing lmdesc->nxla?
Because struct rz_dmac_desc is allocated via kzalloc_obj(), start_lmdesc
is initially NULL and only assigned when the descriptor is prepared by the
hardware.
Due to the driver's internal queue management, if a descriptor is prepared
but not yet submitted, an unrelated IRQ or issue_pending call can move it
from ld_queue to ld_active without processing it.
If rz_dmac_chan_get_residue() is then called and matches this descriptor's
cookie, it will unconditionally dereference the NULL pointer.
I note this is addressed later in the series by commit d09437d0a9b5a
("dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor
processing"), which completely removes ld_queue and ld_active.
> struct dma_chan *chan = &channel->vc.chan;
> struct rz_dmac *dmac = to_rz_dmac(chan->device);
> u32 residue = 0, i = 0;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526084710.3491480-1-claudiu.beznea@kernel.org?part=6
next prev parent reply other threads:[~2026-05-26 9:41 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-26 8:46 [PATCH v6 00/18] Renesas: dmaengine and ASoC fixes Claudiu Beznea
2026-05-26 8:46 ` [PATCH v6 01/18] dmaengine: sh: rz-dmac: Move interrupt request after everything is set up Claudiu Beznea
2026-05-26 8:54 ` Biju Das
2026-05-26 9:45 ` Claudiu Beznea
2026-05-26 9:51 ` Biju Das
2026-05-26 10:25 ` Claudiu Beznea
2026-05-26 10:39 ` Biju Das
2026-05-26 9:20 ` sashiko-bot
2026-05-28 13:44 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 02/18] dmaengine: sh: rz-dmac: Fix incorrect NULL check for list_first_entry() Claudiu Beznea
2026-05-26 9:03 ` sashiko-bot
2026-05-28 13:45 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 03/18] dmaengine: sh: rz-dmac: Use list_first_entry_or_null() Claudiu Beznea
2026-05-28 13:45 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 04/18] dmaengine: sh: rz-dmac: Use rz_dmac_disable_hw() Claudiu Beznea
2026-05-26 9:15 ` sashiko-bot
2026-05-28 13:46 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 05/18] dmaengine: sh: rz-dmac: Add helper to compute the lmdesc address Claudiu Beznea
2026-05-28 13:47 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 06/18] dmaengine: sh: rz-dmac: Save the start LM descriptor Claudiu Beznea
2026-05-26 9:41 ` sashiko-bot [this message]
2026-05-28 13:47 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 07/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is enabled Claudiu Beznea
2026-05-28 13:48 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 08/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is paused Claudiu Beznea
2026-05-28 13:48 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 09/18] dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor processing Claudiu Beznea
2026-05-26 9:28 ` sashiko-bot
2026-05-28 13:49 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 10/18] dmaengine: sh: rz-dmac: Refactor pause/resume code Claudiu Beznea
2026-05-26 9:28 ` sashiko-bot
2026-05-28 13:50 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 11/18] dmaengine: sh: rz-dmac: Drop the update of channel->chctrl with CHCTRL_SETEN Claudiu Beznea
2026-05-26 9:11 ` sashiko-bot
2026-05-28 13:50 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 12/18] dmaengine: sh: rz-dmac: Add cyclic DMA support Claudiu Beznea
2026-05-26 9:31 ` sashiko-bot
2026-05-28 13:51 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 13/18] dmaengine: sh: rz-dmac: Adjust rz_dmac_chan_get_residue() to return error codes Claudiu Beznea
2026-05-28 13:51 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 14/18] dmaengine: sh: rz-dmac: Add runtime PM support Claudiu Beznea
2026-05-26 9:57 ` sashiko-bot
2026-05-28 13:52 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 15/18] dmaengine: sh: rz-dmac: Add suspend to RAM support Claudiu Beznea
2026-05-26 9:43 ` sashiko-bot
2026-05-28 14:38 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 16/18] ASoC: renesas: rz-ssi: Add pause support Claudiu Beznea
2026-05-26 9:46 ` sashiko-bot
2026-05-26 8:47 ` [PATCH v6 17/18] ASoC: renesas: rz-ssi: Use generic PCM dmaengine APIs Claudiu Beznea
2026-05-26 10:00 ` sashiko-bot
2026-05-26 8:47 ` [PATCH v6 18/18] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor Claudiu Beznea
2026-05-26 9:43 ` sashiko-bot
2026-05-28 14:39 ` Tommaso Merciai
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=20260526094142.42FAF1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=claudiu.beznea@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
--cc=wsa+renesas@sang-engineering.com \
/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