* [PATCH 0/2] dmaengine: fix dead empty checks in mpc512x and rz-dmac @ 2026-05-21 14:47 Maoyi Xie 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie 2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie 0 siblings, 2 replies; 10+ messages in thread From: Maoyi Xie @ 2026-05-21 14:47 UTC (permalink / raw) To: Vinod Koul Cc: Frank Li, Geert Uytterhoeven, dmaengine, linux-renesas-soc, linux-kernel Two dmaengine drivers use list_first_entry() and then test the returned pointer against NULL. list_first_entry() never returns NULL, so the NULL check is dead code. The author intent at both sites was clear from the existing recovery path. Switch to list_first_entry_or_null() so the existing NULL path runs. The two sites were raised in an inquiry on 2026-05-20. Frank Li confirmed and asked for a patch. Maoyi Xie (2): dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() drivers/dma/mpc512x_dma.c | 4 ++-- drivers/dma/sh/rz-dmac.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() 2026-05-21 14:47 [PATCH 0/2] dmaengine: fix dead empty checks in mpc512x and rz-dmac Maoyi Xie @ 2026-05-21 14:47 ` Maoyi Xie 2026-05-21 15:42 ` sashiko-bot ` (2 more replies) 2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie 1 sibling, 3 replies; 10+ messages in thread From: Maoyi Xie @ 2026-05-21 14:47 UTC (permalink / raw) To: Vinod Koul Cc: Frank Li, Geert Uytterhoeven, dmaengine, linux-renesas-soc, linux-kernel mpc_dma_prep_slave_sg() reads mchan->free with list_first_entry() and then tests the returned pointer against NULL. list_first_entry() never returns NULL. On an empty free list it returns container_of(&mchan->free, struct mpc_dma_desc, node), an aliased pointer derived from the list head. The recovery path (drop lock, scan completed list, return NULL) is dead code. If the free list is ever empty here, the aliased mdesc points at &mchan->free. The list_del(&mdesc->node) that follows then runs on the head itself, corrupting mchan->free.next and mchan->free.prev. The free list is reachable empty when the descriptor pool is exhausted. The author intent was clear from the recovery path: release the lock, scan the completed list to free descriptors, and return NULL so the caller can retry. Use list_first_entry_or_null() so the empty case returns NULL and the existing recovery path runs as intended. The same shape has been cleaned up elsewhere, for example in commit fbb8bc408027 ("net: qed: Remove redundant NULL checks after list_first_entry()"), commit c708d3fad421 ("crypto: atmel - use list_first_entry_or_null to simplify find_dev"), and commit 10379171f346 ("ksmbd: use list_first_entry_or_null for opinfo_get_list()"). This site was missed by those cleanups. Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> --- drivers/dma/mpc512x_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 0adc8e01057e..f5934136efc4 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, for_each_sg(sgl, sg, sg_len, i) { spin_lock_irqsave(&mchan->lock, iflags); - mdesc = list_first_entry(&mchan->free, - struct mpc_dma_desc, node); + mdesc = list_first_entry_or_null(&mchan->free, + struct mpc_dma_desc, node); if (!mdesc) { spin_unlock_irqrestore(&mchan->lock, iflags); /* Try to free completed descriptors */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie @ 2026-05-21 15:42 ` sashiko-bot 2026-05-21 16:30 ` Frank Li 2026-05-22 15:02 ` [PATCH v2] " Maoyi Xie 2 siblings, 0 replies; 10+ messages in thread From: sashiko-bot @ 2026-05-21 15:42 UTC (permalink / raw) To: Maoyi Xie; +Cc: wsa+renesas, vkoul, Frank.Li, dmaengine Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] Incorrect minor loop byte count calculation causes hardware configuration errors and potential division by zero panic. - [High] Direct C bitfield assignment to an __iomem pointer causes undefined behavior and potential Machine Check Exceptions. -- commit 843ae9154206865fe98175ccec56b456c8445f35 Author: Maoyi Xie <maoyixie.tju@gmail.com> dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() mpc_dma_prep_slave_sg() reads mchan->free with list_first_entry() and then tests the returned pointer against NULL. list_first_entry() never returns NULL. On an empty free list it returns an aliased pointer derived from the list head, making the recovery path dead code. > diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c > index 0adc8e01057e1..f5934136efc4c 100644 > --- a/drivers/dma/mpc512x_dma.c > +++ b/drivers/dma/mpc512x_dma.c > @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, > for_each_sg(sgl, sg, sg_len, i) { > spin_lock_irqsave(&mchan->lock, iflags); > > - mdesc = list_first_entry(&mchan->free, > - struct mpc_dma_desc, node); > + mdesc = list_first_entry_or_null(&mchan->free, > + struct mpc_dma_desc, node); > if (!mdesc) { > spin_unlock_irqrestore(&mchan->lock, iflags); > /* Try to free completed descriptors */ [Severity: High] This isn't a bug introduced by this patch, but in mpc_dma_prep_slave_sg(), the minor loop byte count is calculated using the register enum value tcd->ssize instead of the actual transfer width: drivers/dma/mpc512x_dma.c:mpc_dma_prep_slave_sg() { ... tcd->ssize = buswidth_to_dmatsize(mchan->swidth); tcd->dsize = buswidth_to_dmatsize(mchan->dwidth); if (mdma->is_mpc8308) { ... } else { len = sg_dma_len(sg); tcd->nbytes = tcd_nunits * tcd->ssize; if (!IS_ALIGNED(len, tcd->nbytes)) goto err_prep; iter = len / tcd->nbytes; ... } For a 1-byte transfer width, tcd->ssize is 0, causing tcd->nbytes to be 0. If a client submits a scatterlist with length 0, the IS_ALIGNED(len, tcd->nbytes) check passes (since 0 & -1 == 0), resulting in a division by zero kernel panic when calculating iter. Even for valid lengths, 1-byte transfers always fail the alignment check, and transfers with other widths receive an incorrect minor loop configuration, causing functional failures. Could we update this to use the actual transfer width instead of the enum value? [Severity: High] This is also a pre-existing issue, but in mpc_dma_execute(), a bitfield on a memory-mapped I/O structure is modified directly via C assignment: drivers/dma/mpc512x_dma.c:mpc_dma_execute() { ... /* Send first descriptor in chain into hardware */ memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd)); if (first != prev) mdma->tcd[cid].e_sg = 1; ... } Since mdma->tcd is an __iomem pointer, does dereferencing it directly with standard C assignments invoke undefined behavior and circumvent necessary I/O accessors? As struct mpc_dma_tcd is marked __packed__, the compiler may generate byte-sized read-modify-write instructions. On PowerPC architectures, such non-32-bit accesses to memory-mapped device registers can trigger Machine Check Exceptions (MCE), leading to system crashes. Is there a safer way to update this hardware register using appropriate I/O accessors? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260521144755.3476353-1-maoyixie.tju@gmail.com?part=1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie 2026-05-21 15:42 ` sashiko-bot @ 2026-05-21 16:30 ` Frank Li 2026-05-22 15:02 ` [PATCH v2] " Maoyi Xie 2 siblings, 0 replies; 10+ messages in thread From: Frank Li @ 2026-05-21 16:30 UTC (permalink / raw) To: Maoyi Xie Cc: Vinod Koul, Frank Li, Geert Uytterhoeven, dmaengine, linux-renesas-soc, linux-kernel On Thu, May 21, 2026 at 10:47:54PM +0800, Maoyi Xie wrote: > mpc_dma_prep_slave_sg() reads mchan->free with list_first_entry() > and then tests the returned pointer against NULL. list_first_entry() > never returns NULL. On an empty free list it returns > container_of(&mchan->free, struct mpc_dma_desc, node), an aliased > pointer derived from the list head. The recovery path (drop lock, > scan completed list, return NULL) is dead code. > > If the free list is ever empty here, the aliased mdesc points at > &mchan->free. The list_del(&mdesc->node) that follows then runs on > the head itself, corrupting mchan->free.next and mchan->free.prev. > > The free list is reachable empty when the descriptor pool is > exhausted. The author intent was clear from the recovery path: > release the lock, scan the completed list to free descriptors, and > return NULL so the caller can retry. Nit: You can skip above two parapraph. This problem is quite straight forwards Reviewed-by: Frank Li <Frank.Li@nxp.com> > > Use list_first_entry_or_null() so the empty case returns NULL and > the existing recovery path runs as intended. > > The same shape has been cleaned up elsewhere, for example in > commit fbb8bc408027 ("net: qed: Remove redundant NULL checks after list_first_entry()"), > commit c708d3fad421 ("crypto: atmel - use list_first_entry_or_null to simplify find_dev"), > and commit 10379171f346 ("ksmbd: use list_first_entry_or_null for opinfo_get_list()"). > This site was missed by those cleanups. > > Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> > --- > drivers/dma/mpc512x_dma.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c > index 0adc8e01057e..f5934136efc4 100644 > --- a/drivers/dma/mpc512x_dma.c > +++ b/drivers/dma/mpc512x_dma.c > @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, > for_each_sg(sgl, sg, sg_len, i) { > spin_lock_irqsave(&mchan->lock, iflags); > > - mdesc = list_first_entry(&mchan->free, > - struct mpc_dma_desc, node); > + mdesc = list_first_entry_or_null(&mchan->free, > + struct mpc_dma_desc, node); > if (!mdesc) { > spin_unlock_irqrestore(&mchan->lock, iflags); > /* Try to free completed descriptors */ > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie 2026-05-21 15:42 ` sashiko-bot 2026-05-21 16:30 ` Frank Li @ 2026-05-22 15:02 ` Maoyi Xie 2026-05-22 15:23 ` sashiko-bot 2 siblings, 1 reply; 10+ messages in thread From: Maoyi Xie @ 2026-05-22 15:02 UTC (permalink / raw) To: Vinod Koul Cc: Frank Li, Geert Uytterhoeven, dmaengine, linux-renesas-soc, linux-kernel mpc_dma_prep_slave_sg() reads mchan->free with list_first_entry() and then tests the returned pointer against NULL. list_first_entry() never returns NULL. On an empty free list it returns container_of(&mchan->free, struct mpc_dma_desc, node), an aliased pointer derived from the list head. The recovery path (drop lock, scan completed list, return NULL) is dead code. Use list_first_entry_or_null() so the empty case returns NULL and the existing recovery path runs as intended. The same shape has been cleaned up elsewhere, for example in commit fbb8bc408027 ("net: qed: Remove redundant NULL checks after list_first_entry()"), commit c708d3fad421 ("crypto: atmel - use list_first_entry_or_null to simplify find_dev"), and commit 10379171f346 ("ksmbd: use list_first_entry_or_null for opinfo_get_list()"). This site was missed by those cleanups. Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> --- v2: Trim two paragraphs from the commit message per Frank Li's nit on v1. No code change. Carry forward Frank's Reviewed-by. Drop the rz-dmac patch from v1: Geert pointed out that Claudiu's "[PATCH v5 09/17] dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor processing" rewrites rz_dmac_chan_get_residue() through vchan_find_desc() and removes ld_active, which supersedes the fix. https://lore.kernel.org/r/20260512121219.216159-10-claudiu.beznea.uj@bp.renesas.com v1: https://lore.kernel.org/r/20260521144755.3476353-2-maoyixie.tju@gmail.com drivers/dma/mpc512x_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 0adc8e01057e..f5934136efc4 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, for_each_sg(sgl, sg, sg_len, i) { spin_lock_irqsave(&mchan->lock, iflags); - mdesc = list_first_entry(&mchan->free, - struct mpc_dma_desc, node); + mdesc = list_first_entry_or_null(&mchan->free, + struct mpc_dma_desc, node); if (!mdesc) { spin_unlock_irqrestore(&mchan->lock, iflags); /* Try to free completed descriptors */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() 2026-05-22 15:02 ` [PATCH v2] " Maoyi Xie @ 2026-05-22 15:23 ` sashiko-bot 0 siblings, 0 replies; 10+ messages in thread From: sashiko-bot @ 2026-05-22 15:23 UTC (permalink / raw) To: Maoyi Xie; +Cc: vkoul, Frank.Li, dmaengine, wsa+renesas Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] Incorrect calculation of `tcd->nbytes` using an encoded bus width enum instead of the actual byte count, leading to hardware misconfiguration and potential division by zero. - [High] Activating the previously dead error recovery path triggers severe concurrency issues, including client deadlocks and cookie state corruption. -- commit 534ce02bd48f83d7760dd6fe18bd31e5103a4bad Author: Maoyi Xie <maoyixie.tju@gmail.com> dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() This commit changes the list_first_entry() call to list_first_entry_or_null() in mpc_dma_prep_slave_sg() to correctly handle an empty free list. This ensures the empty case returns NULL and allows the existing recovery path to execute. > diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c > index 0adc8e01057e1..f5934136efc4c 100644 > --- a/drivers/dma/mpc512x_dma.c > +++ b/drivers/dma/mpc512x_dma.c > @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, > for_each_sg(sgl, sg, sg_len, i) { > spin_lock_irqsave(&mchan->lock, iflags); > > - mdesc = list_first_entry(&mchan->free, > - struct mpc_dma_desc, node); > + mdesc = list_first_entry_or_null(&mchan->free, > + struct mpc_dma_desc, node); > if (!mdesc) { > spin_unlock_irqrestore(&mchan->lock, iflags); > /* Try to free completed descriptors */ [Severity: High] This isn't a bug introduced by this patch, but activating the recovery path exposes a design flaw. Is it safe to call mpc_dma_process_completed() from process context here? As seen just below this diff, the recovery path calls mpc_dma_process_completed(mdma). DMA clients often hold a spinlock during dmaengine_prep_slave_sg() and expect to acquire it in their callback. Since mpc_dma_process_completed() invokes client callbacks inline, could this lead to a double-lock deadlock? Additionally, mpc_dma_process_completed() drops mchan->lock to run callbacks. Concurrently, mpc_dma_tasklet can execute, process newer completions, and update mchan->chan.completed_cookie. When process context resumes, it reacquires the lock and overwrites completed_cookie with its older last_cookie, rolling the DMA state backwards. Furthermore, this recovery path iterates over and flushes completions for all DMA channels, which might disrupt other clients. [ ... ] [Severity: High] This is a pre-existing issue, but further down in mpc_dma_prep_slave_sg(), is the minor loop byte count calculated correctly? drivers/dma/mpc512x_dma.c:mpc_dma_prep_slave_sg() { ... tcd->ssize = buswidth_to_dmatsize(mchan->swidth); tcd->dsize = buswidth_to_dmatsize(mchan->dwidth); if (mdma->is_mpc8308) { ... } else { len = sg_dma_len(sg); tcd->nbytes = tcd_nunits * tcd->ssize; if (!IS_ALIGNED(len, tcd->nbytes)) goto err_prep; iter = len / tcd->nbytes; ... } The value tcd->ssize is an encoded hardware value (log2 of the bus width), not the actual byte size. If mchan->swidth is 1 byte, buswidth_to_dmatsize(1) returns 0, making tcd->ssize 0 and tcd->nbytes 0. If len == 0, IS_ALIGNED(0, 0) is true, which could trigger a division by zero when calculating iter. If len > 0, it unconditionally fails the alignment check, which would render 1-byte transfers broken. For larger widths (e.g., 4 bytes), tcd->ssize is 2, causing the hardware to be misconfigured with an incorrect transfer size. Additionally, for DMA_MEM_TO_DEV, does this incorrectly mix the peripheral maxburst with the memory bus width? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260522150214.95651-1-maoyixie.tju@gmail.com?part=1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() 2026-05-21 14:47 [PATCH 0/2] dmaengine: fix dead empty checks in mpc512x and rz-dmac Maoyi Xie 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie @ 2026-05-21 14:47 ` Maoyi Xie 2026-05-21 16:05 ` sashiko-bot 2026-05-22 8:16 ` Geert Uytterhoeven 1 sibling, 2 replies; 10+ messages in thread From: Maoyi Xie @ 2026-05-21 14:47 UTC (permalink / raw) To: Vinod Koul Cc: Frank Li, Geert Uytterhoeven, dmaengine, linux-renesas-soc, linux-kernel rz_dmac_chan_get_residue() reads channel->ld_active with list_first_entry() and then tests the returned pointer against NULL. list_first_entry() never returns NULL. On an empty list it returns container_of(&channel->ld_active, struct rz_dmac_desc, node), an aliased pointer derived from the list head. The "return 0" shortcut is dead code. If ld_active is ever empty here, current_desc points at &channel->ld_active. The subsequent cookie and status processing then reads bogus values from the head's neighbouring memory. ld_active can be empty when a residue query races with descriptor completion on another path. The author intent was clear from the existing comment on the next-following check, which already acknowledges that the descriptor "could now be complete". The empty case is the limit of that race. Use list_first_entry_or_null() so the empty case returns NULL and the existing "return 0" path runs. The same shape has been cleaned up elsewhere, for example in commit fbb8bc408027 ("net: qed: Remove redundant NULL checks after list_first_entry()"), commit c708d3fad421 ("crypto: atmel - use list_first_entry_or_null to simplify find_dev"), and commit 10379171f346 ("ksmbd: use list_first_entry_or_null for opinfo_get_list()"). This site was missed by those cleanups. Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> --- drivers/dma/sh/rz-dmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 625ff29024de..3dd76615881f 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -723,8 +723,8 @@ static u32 rz_dmac_chan_get_residue(struct rz_dmac_chan *channel, u32 crla, crtb, i; /* Get current processing virtual descriptor */ - current_desc = list_first_entry(&channel->ld_active, - struct rz_dmac_desc, node); + current_desc = list_first_entry_or_null(&channel->ld_active, + struct rz_dmac_desc, node); if (!current_desc) return 0; -- 2.34.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() 2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie @ 2026-05-21 16:05 ` sashiko-bot 2026-05-22 8:16 ` Geert Uytterhoeven 1 sibling, 0 replies; 10+ messages in thread From: sashiko-bot @ 2026-05-21 16:05 UTC (permalink / raw) To: Maoyi Xie; +Cc: dmaengine, Frank.Li, vkoul, wsa+renesas Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: New issues: - [High] The patch introduces a logic error that falsely reports pending unissued transfers as DMA_COMPLETE. Pre-existing issues: - [High] Race condition where unsubmitted descriptors are prematurely executed by the hardware. -- commit 0e410e8d5063eb51746f71d6bfff0bc38f086e9b Author: Maoyi Xie <maoyixie.tju@gmail.com> Subject: dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() This commit changes list_first_entry to list_first_entry_or_null in rz_dmac_chan_get_residue to properly check if the active list is empty. If the list is empty, it now safely returns a zero residue instead of reading from invalid neighboring memory. > diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c > index 625ff29024de0..3dd76615881ff 100644 > --- a/drivers/dma/sh/rz-dmac.c > +++ b/drivers/dma/sh/rz-dmac.c > @@ -723,8 +723,8 @@ static u32 rz_dmac_chan_get_residue(struct rz_dmac_chan *channel, > u32 crla, crtb, i; > > /* Get current processing virtual descriptor */ > - current_desc = list_first_entry(&channel->ld_active, > - struct rz_dmac_desc, node); > + current_desc = list_first_entry_or_null(&channel->ld_active, > + struct rz_dmac_desc, node); > if (!current_desc) > return 0; [Severity: High] If a client queries the status of a transfer that has been prepared but not yet issued, or while it is pending in ld_queue waiting for previous transfers, ld_active will be empty. With this patch, current_desc will be null and the function will immediately return 0. Does returning 0 residue here cause rz_dmac_tx_status() to prematurely report the transfer as finished with a DMA_COMPLETE status? Before this patch, the invalid pointer coincidentally bypassed the null check, which allowed the code to continue, correctly search ld_queue, and return the full descriptor length. Returning early here could cause clients to free or reuse buffers while the hardware is still scheduled to access them. [Severity: High] This is a pre-existing issue, but looking at how descriptors are queued, is there a race condition where unsubmitted descriptors are prematurely executed by the hardware? In rz_dmac_prep_slave_sg() and rz_dmac_prep_dma_memcpy(), prepared descriptors are immediately placed into channel->ld_queue before the client calls dmaengine_submit(). If an existing transfer completes, the hardware interrupt handler rz_dmac_irq_handler_thread() appears to blindly pull the next descriptor from ld_queue and initiates the transfer via rz_dmac_xfer_desc(). Could this result in the hardware executing transfers before the client has filled the data buffers or actually submitted the transfer? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260521144755.3476353-1-maoyixie.tju@gmail.com?part=2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() 2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie 2026-05-21 16:05 ` sashiko-bot @ 2026-05-22 8:16 ` Geert Uytterhoeven 2026-05-22 8:37 ` Maoyi Xie 1 sibling, 1 reply; 10+ messages in thread From: Geert Uytterhoeven @ 2026-05-22 8:16 UTC (permalink / raw) To: Maoyi Xie Cc: Claudiu Beznea, Vinod Koul, Frank Li, dmaengine, linux-renesas-soc, linux-kernel Hi Maoyi, On Thu, 21 May 2026 at 16:48, Maoyi Xie <maoyixie.tju@gmail.com> wrote: > rz_dmac_chan_get_residue() reads channel->ld_active with > list_first_entry() and then tests the returned pointer against > NULL. list_first_entry() never returns NULL. On an empty list it > returns container_of(&channel->ld_active, struct rz_dmac_desc, > node), an aliased pointer derived from the list head. The "return > 0" shortcut is dead code. > > If ld_active is ever empty here, current_desc points at > &channel->ld_active. The subsequent cookie and status processing > then reads bogus values from the head's neighbouring memory. > > ld_active can be empty when a residue query races with descriptor > completion on another path. The author intent was clear from the > existing comment on the next-following check, which already > acknowledges that the descriptor "could now be complete". The > empty case is the limit of that race. > > Use list_first_entry_or_null() so the empty case returns NULL and > the existing "return 0" path runs. > > The same shape has been cleaned up elsewhere, for example in > commit fbb8bc408027 ("net: qed: Remove redundant NULL checks after list_first_entry()"), > commit c708d3fad421 ("crypto: atmel - use list_first_entry_or_null to simplify find_dev"), > and commit 10379171f346 ("ksmbd: use list_first_entry_or_null for opinfo_get_list()"). > This site was missed by those cleanups. > > Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> Thanks for your patch! > --- a/drivers/dma/sh/rz-dmac.c > +++ b/drivers/dma/sh/rz-dmac.c > @@ -723,8 +723,8 @@ static u32 rz_dmac_chan_get_residue(struct rz_dmac_chan *channel, > u32 crla, crtb, i; > > /* Get current processing virtual descriptor */ > - current_desc = list_first_entry(&channel->ld_active, > - struct rz_dmac_desc, node); > + current_desc = list_first_entry_or_null(&channel->ld_active, > + struct rz_dmac_desc, node); > if (!current_desc) > return 0; > Note that proposed "[PATCH v5 09/17] dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor processing" would remove this code. https://lore.kernel.org/20260512121219.216159-10-claudiu.beznea.uj@bp.renesas.com Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() 2026-05-22 8:16 ` Geert Uytterhoeven @ 2026-05-22 8:37 ` Maoyi Xie 0 siblings, 0 replies; 10+ messages in thread From: Maoyi Xie @ 2026-05-22 8:37 UTC (permalink / raw) To: Geert Uytterhoeven Cc: Claudiu Beznea, Vinod Koul, Frank Li, dmaengine, linux-renesas-soc, linux-kernel Hi Geert, Thanks for the pointer. I had not seen Claudiu's v5 09/17 series. Looking at it, rz_dmac_chan_get_residue() is rewritten through virt_dma APIs (vchan_find_desc + channel->desc) and ld_active is removed. The fix I sent is superseded. I will drop the rz-dmac patch from v2 of this series and send only the mpc512x patch. Thanks, Maoyi ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-22 15:23 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-21 14:47 [PATCH 0/2] dmaengine: fix dead empty checks in mpc512x and rz-dmac Maoyi Xie 2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie 2026-05-21 15:42 ` sashiko-bot 2026-05-21 16:30 ` Frank Li 2026-05-22 15:02 ` [PATCH v2] " Maoyi Xie 2026-05-22 15:23 ` sashiko-bot 2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie 2026-05-21 16:05 ` sashiko-bot 2026-05-22 8:16 ` Geert Uytterhoeven 2026-05-22 8:37 ` Maoyi Xie
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox