All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] dmaengine: dw-axi-dmac: Fix burst length encoding and LLI dump
@ 2026-08-28  0:48 Jia Wang
  2026-08-28  0:48 ` [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
  2026-08-28  0:48 ` [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
  0 siblings, 2 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  0:48 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Andy Shevchenko,
	Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang

The first patch converts the configured AXI burst length from a beat count
to the ARLEN/AWLEN encoding when constructing hardware descriptors. Without
this conversion, a 256-beat burst overflows the 8-bit hardware fields and
may cause DMA transfer errors.

The second patch bounds the error-path LLI dump by the number of
descriptors in the current transaction. This prevents an original DMA error
from being followed by an out-of-bounds access and kernel panic while
dumping LLIs.

The series was tested with dmatest on all eight channels using
snps,axi-max-burst-len = <256>. All channels completed without errors.

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Jia Wang (2):
      dmaengine: dw-axi-dmac: Fix AXI burst length encoding
      dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access

 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
---
base-commit: 1b78070aaef63512688aebfbc82365ef9d6660f1
change-id: 20260827-dma-fix-c2b27795ce12

Best regards,
--  
Jia Wang <wangjia@ultrarisc.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding
  2026-08-28  0:48 [PATCH 0/2] dmaengine: dw-axi-dmac: Fix burst length encoding and LLI dump Jia Wang
@ 2026-08-28  0:48 ` Jia Wang
  2026-08-28  0:59   ` sashiko-bot
  2026-08-28 19:32   ` Frank Li
  2026-08-28  0:48 ` [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
  1 sibling, 2 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  0:48 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Andy Shevchenko,
	Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang

The snps,axi-max-burst-len property describes the number of beats in an
AXI burst, while the ARLEN and AWLEN fields encode that value minus one.

The driver keeps axi_rw_burst_len as the actual burst length so that
dma_device.max_burst reports the correct value. However, it also programs
that unencoded value directly into the hardware fields. A value of 256
therefore overflows the 8-bit fields and can cause AXI decode errors.

Subtract one only when constructing hardware descriptors, while keeping
the actual value for dma_device.max_burst.

Fixes: c454d16a7d5a ("dmaengine: dw-axi-dmac: Burst length settings")
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index eebed2474210..742e08cfab43 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -706,7 +706,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
 	ctlhi = CH_CTL_H_LLI_VALID;
 
 	if (chan->chip->dw->hdata->restrict_axi_burst_len) {
-		burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
+		burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 		ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN |
 			 burst_len << CH_CTL_H_ARLEN_POS |
 			 burst_len << CH_CTL_H_AWLEN_POS;
@@ -975,7 +975,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
 
 		reg = CH_CTL_H_LLI_VALID;
 		if (chan->chip->dw->hdata->restrict_axi_burst_len) {
-			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
+			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 
 			reg |= (CH_CTL_H_ARLEN_EN |
 				burst_len << CH_CTL_H_ARLEN_POS |

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-08-28  0:48 [PATCH 0/2] dmaengine: dw-axi-dmac: Fix burst length encoding and LLI dump Jia Wang
  2026-08-28  0:48 ` [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
@ 2026-08-28  0:48 ` Jia Wang
  2026-08-28  1:04   ` sashiko-bot
  2026-08-28  7:01   ` Andy Shevchenko
  1 sibling, 2 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  0:48 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Andy Shevchenko,
	Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang

axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
walk the hw_desc[] array of a single transaction. If multiple
transactions have allocated LLIs, the channel count can exceed the
transaction-local nr_hw_descs and make the DMA error path read past the
end of hw_desc[].

Use the descriptor-local nr_hw_descs count when dumping LLIs.

Fixes: ef6fb2d6f1ab ("dmaengine: dw-axi-dmac: simplify descriptor management")
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 742e08cfab43..858004b5a846 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1052,10 +1052,9 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan,
 static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
 				   struct axi_dma_desc *desc_head)
 {
-	int count = atomic_read(&chan->descs_allocated);
 	int i;
 
-	for (i = 0; i < count; i++)
+	for (i = 0; i < desc_head->nr_hw_descs; i++)
 		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
 }
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding
  2026-08-28  0:48 ` [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
@ 2026-08-28  0:59   ` sashiko-bot
  2026-08-28  9:24     ` Jia Wang
  2026-08-28 19:32   ` Frank Li
  1 sibling, 1 reply; 10+ messages in thread
From: sashiko-bot @ 2026-08-28  0:59 UTC (permalink / raw)
  To: Jia Wang; +Cc: dmaengine, Frank.Li, vkoul

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] The error handling path for descriptor allocation failures calls `dma_pool_free` with NULL pointers and underflows the `descs_allocated` counter.
- [High] Missing validation of transfer lengths (`len`, `buf_len`, `period_len`) in DMA prep functions leads to division-by-zero panics and out-of-bounds array accesses.
--

commit 1edc02c6412e562b16e650ad23de4b1395cbcb68
Author: Jia Wang <wangjia@ultrarisc.com>

dmaengine: dw-axi-dmac: Fix AXI burst length encoding

The snps,axi-max-burst-len property describes the number of beats in an
AXI burst, while the ARLEN and AWLEN fields encode that value minus one.

The driver keeps axi_rw_burst_len as the actual burst length so that
dma_device.max_burst reports the correct value. However, it also programs
that unencoded value directly into the hardware fields. A value of 256
therefore overflows the 8-bit fields and can cause AXI decode errors.

Subtract one only when constructing hardware descriptors, while keeping
the actual value for dma_device.max_burst.

> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index eebed2474210d..742e08cfab435 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c

[ ... ]

> @@ -975,7 +975,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
>  
>  		reg = CH_CTL_H_LLI_VALID;
>  		if (chan->chip->dw->hdata->restrict_axi_burst_len) {
> -			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
> +			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;

[Severity: High]
This is a pre-existing issue, but does the error handling in this
function cause a kernel panic if descriptor allocation fails?

If axi_desc_get() fails to allocate a descriptor (e.g., due to memory
exhaustion), the code jumps to err_desc_get and calls axi_desc_put(desc):

	hw_desc->lli = axi_desc_get(chan, &hw_desc->llp);
	if (unlikely(!hw_desc->lli))
		goto err_desc_get;

axi_desc_put() unconditionally loops over all requested descriptors and calls
dma_pool_free() with hw_desc->lli. For elements that were not successfully
allocated, hw_desc->lli is NULL, which causes dma_pool_free() to dereference
a NULL pointer.

Additionally, axi_desc_put() subtracts the full requested number of
descriptors from chan->descs_allocated instead of the successfully allocated
count, which could underflow the counter:

	atomic_sub(descs_put, &chan->descs_allocated);

[Severity: High]
This is also a pre-existing issue, but does this function lack validation for
transfer lengths?

If a DMA client driver provides a len of 0 in dma_chan_prep_dma_memcpy(),
num evaluates to 0 and the transfer setup loop is skipped. The function then
attempts to write to index -1, causing memory corruption:

	/* Set end-of-link to the last link descriptor of list */
	set_desc_last(&desc->hw_desc[num - 1]);

Similarly, in dw_axi_dma_chan_prep_cyclic(), can a period_len of 0 cause an
unhandled division-by-zero panic when calculating num_periods?

	num_periods = buf_len / period_len;

And if buf_len is 0 in dw_axi_dma_chan_prep_cyclic(), making total_segments 0,
does this access out of bounds on the 0-length allocation?

	llp = desc->hw_desc[0].llp;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260828-dma-fix-v1-0-a6947f487e07@ultrarisc.com?part=1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-08-28  0:48 ` [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
@ 2026-08-28  1:04   ` sashiko-bot
  2026-08-28  9:33     ` Jia Wang
  2026-08-28  7:01   ` Andy Shevchenko
  1 sibling, 1 reply; 10+ messages in thread
From: sashiko-bot @ 2026-08-28  1:04 UTC (permalink / raw)
  To: Jia Wang; +Cc: Frank.Li, dmaengine, vkoul

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] The exact same out-of-bounds array access bug that this commit fixes in `axi_chan_list_dump_lli()` remains unpatched in `axi_chan_block_xfer_complete()`, compounded by a TOCTOU race.
- [High] A flawed SG iteration loop in `dw_axi_dma_chan_prep_slave_sg()` exits prematurely, silently truncating transfers and causing an immediate NULL pointer dereference panic.
- [High] On descriptor allocation error paths, `axi_desc_put()` will attempt to free `NULL` pointers to the DMA pool and incorrectly subtract unallocated counts from `chan->descs_allocated`, leading to kernel panics and counter corruption.
--

commit c635f1f1d2b17ebcac96fbdff2d3244d2e75fb83
Author: Jia Wang <wangjia@ultrarisc.com>

dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access

axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
walk the hw_desc[] array of a single transaction. If multiple
transactions have allocated LLIs, the channel count can exceed the
transaction-local nr_hw_descs and make the DMA error path read past the
end of hw_desc[].

> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index 742e08cfab435..858004b5a8467 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1052,10 +1052,9 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan,
>  static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
>  				   struct axi_dma_desc *desc_head)
>  {
> -	int count = atomic_read(&chan->descs_allocated);
>  	int i;
>  
> -	for (i = 0; i < count; i++)
> +	for (i = 0; i < desc_head->nr_hw_descs; i++)
>  		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
>  }

[Severity: High]
This is a pre-existing issue, but the exact same out-of-bounds array access
bug that this commit fixes in axi_chan_list_dump_lli() remains unpatched in
axi_chan_block_xfer_complete():

drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:axi_chan_block_xfer_complete() {
    ...
    int count = atomic_read(&chan->descs_allocated);
    ...
    for (i = 0; i < count; i++) {
        hw_desc = &desc->hw_desc[i];
    ...
}

Does this function also need to be updated to use desc->nr_hw_descs for
its loop limit? Using the channel-wide count (which is fetched outside the
channel spinlock, presenting a TOCTOU race) could cause an out-of-bounds read
on desc->hw_desc[]. If the garbage memory happens to match llp, it will modify
the memory via hw_desc->lli->ctl_hi.


[Severity: High]
This is a pre-existing issue, but looking at dw_axi_dma_chan_prep_slave_sg(),
is there a flaw in the SG iteration loop?

drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:dw_axi_dma_chan_prep_slave_sg() {
    ...
    segment_len = DIV_ROUND_UP(sg_dma_len(sg), num_segments);
    ...
    } while (len >= segment_len);
    ...
    write_desc_llp(hw_desc, llp | lms);
    ...
}

If a DMA client submits a scatter-gather list where the length does not evenly
divide into the hardware maximum block size (e.g., length 4097 and block
length 4096 gives a segment_len of 2049, leaving 2048 bytes), the condition
while (len >= segment_len) evaluates to false and exits the loop prematurely.

Does this silent truncation leave trailing descriptors uninitialized, causing an
immediate NULL pointer dereference panic when write_desc_llp() tries to access
hw_desc->lli?


[Severity: High]
This is a pre-existing issue, but does axi_desc_put() safely handle error
rollbacks?

drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:axi_desc_put() {
    ...
    for (i = 0; i < desc->nr_hw_descs; i++) {
        ...
        dma_pool_free(chan->desc_pool, hw_desc->lli, hw_desc->llp);
        ...
    }
    ...
    atomic_sub(descs_put, &chan->descs_allocated);
}

If descriptor initialization fails midway (e.g., due to OOM causing -ENOMEM),
the error path calls axi_desc_put(). Because it unconditionally iterates over
all desc->nr_hw_descs elements, won't it pass NULL hw_desc->lli pointers to
dma_pool_free() for unallocated entries, resulting in a panic?

Additionally, will subtracting the full capacity (descs_put) from
chan->descs_allocated cause an underflow when only partially allocated?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260828-dma-fix-v1-0-a6947f487e07@ultrarisc.com?part=2

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-08-28  0:48 ` [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
  2026-08-28  1:04   ` sashiko-bot
@ 2026-08-28  7:01   ` Andy Shevchenko
  2026-08-28  9:34     ` Jia Wang
  1 sibling, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2026-08-28  7:01 UTC (permalink / raw)
  To: Jia Wang
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Sia Jee Heng,
	dmaengine, linux-kernel

On Fri, Aug 28, 2026 at 08:48:27AM +0800, Jia Wang wrote:
> axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
> walk the hw_desc[] array of a single transaction. If multiple
> transactions have allocated LLIs, the channel count can exceed the
> transaction-local nr_hw_descs and make the DMA error path read past the
> end of hw_desc[].
> 
> Use the descriptor-local nr_hw_descs count when dumping LLIs.

...

>  {
> -	int count = atomic_read(&chan->descs_allocated);
>  	int i;
>  
> -	for (i = 0; i < count; i++)
> +	for (i = 0; i < desc_head->nr_hw_descs; i++)

While at it,

	for (unsigned int i = 0; i < desc_head->nr_hw_descs; i++)

and drop that 'int i;' as well.

>  		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
>  }

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding
  2026-08-28  0:59   ` sashiko-bot
@ 2026-08-28  9:24     ` Jia Wang
  0 siblings, 0 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  9:24 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: Jia Wang, dmaengine, Frank.Li, vkoul

On 2026-08-28 00:59 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] The error handling path for descriptor allocation failures calls `dma_pool_free` with NULL pointers and underflows the `descs_allocated` counter.
> - [High] Missing validation of transfer lengths (`len`, `buf_len`, `period_len`) in DMA prep functions leads to division-by-zero panics and out-of-bounds array accesses.
> --
> 
> commit 1edc02c6412e562b16e650ad23de4b1395cbcb68
> Author: Jia Wang <wangjia@ultrarisc.com>
> 
> dmaengine: dw-axi-dmac: Fix AXI burst length encoding
> 
> The snps,axi-max-burst-len property describes the number of beats in an
> AXI burst, while the ARLEN and AWLEN fields encode that value minus one.
> 
> The driver keeps axi_rw_burst_len as the actual burst length so that
> dma_device.max_burst reports the correct value. However, it also programs
> that unencoded value directly into the hardware fields. A value of 256
> therefore overflows the 8-bit fields and can cause AXI decode errors.
> 
> Subtract one only when constructing hardware descriptors, while keeping
> the actual value for dma_device.max_burst.
> 
> > diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > index eebed2474210d..742e08cfab435 100644
> > --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> 
> [ ... ]
> 
> > @@ -975,7 +975,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
> >  
> >  		reg = CH_CTL_H_LLI_VALID;
> >  		if (chan->chip->dw->hdata->restrict_axi_burst_len) {
> > -			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
> > +			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
> 
> [Severity: High]
> This is a pre-existing issue, but does the error handling in this
> function cause a kernel panic if descriptor allocation fails?
> 
> If axi_desc_get() fails to allocate a descriptor (e.g., due to memory
> exhaustion), the code jumps to err_desc_get and calls axi_desc_put(desc):
> 
> 	hw_desc->lli = axi_desc_get(chan, &hw_desc->llp);
> 	if (unlikely(!hw_desc->lli))
> 		goto err_desc_get;
> 
> axi_desc_put() unconditionally loops over all requested descriptors and calls
> dma_pool_free() with hw_desc->lli. For elements that were not successfully
> allocated, hw_desc->lli is NULL, which causes dma_pool_free() to dereference
> a NULL pointer.
> 
> Additionally, axi_desc_put() subtracts the full requested number of
> descriptors from chan->descs_allocated instead of the successfully allocated
> count, which could underflow the counter:
> 
> 	atomic_sub(descs_put, &chan->descs_allocated);
> 
> [Severity: High]
> This is also a pre-existing issue, but does this function lack validation for
> transfer lengths?
> 
> If a DMA client driver provides a len of 0 in dma_chan_prep_dma_memcpy(),
> num evaluates to 0 and the transfer setup loop is skipped. The function then
> attempts to write to index -1, causing memory corruption:
> 
> 	/* Set end-of-link to the last link descriptor of list */
> 	set_desc_last(&desc->hw_desc[num - 1]);
> 
> Similarly, in dw_axi_dma_chan_prep_cyclic(), can a period_len of 0 cause an
> unhandled division-by-zero panic when calculating num_periods?
> 
> 	num_periods = buf_len / period_len;
> 
> And if buf_len is 0 in dw_axi_dma_chan_prep_cyclic(), making total_segments 0,
> does this access out of bounds on the 0-length allocation?
> 
> 	llp = desc->hw_desc[0].llp;
> 

I checked these paths and confirmed that the issues are pre-existing and
not introduced by this series. To keep this dmatest-driven fix series
scoped, I will address them in a separate follow-up series.

> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260828-dma-fix-v1-0-a6947f487e07@ultrarisc.com?part=1
> 

Best regards,
Jia Wang



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-08-28  1:04   ` sashiko-bot
@ 2026-08-28  9:33     ` Jia Wang
  0 siblings, 0 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  9:33 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: Jia Wang, Frank.Li, dmaengine, vkoul

On 2026-08-28 01:04 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] The exact same out-of-bounds array access bug that this commit fixes in `axi_chan_list_dump_lli()` remains unpatched in `axi_chan_block_xfer_complete()`, compounded by a TOCTOU race.
> - [High] A flawed SG iteration loop in `dw_axi_dma_chan_prep_slave_sg()` exits prematurely, silently truncating transfers and causing an immediate NULL pointer dereference panic.
> - [High] On descriptor allocation error paths, `axi_desc_put()` will attempt to free `NULL` pointers to the DMA pool and incorrectly subtract unallocated counts from `chan->descs_allocated`, leading to kernel panics and counter corruption.
> --
> 
> commit c635f1f1d2b17ebcac96fbdff2d3244d2e75fb83
> Author: Jia Wang <wangjia@ultrarisc.com>
> 
> dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
> 
> axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
> walk the hw_desc[] array of a single transaction. If multiple
> transactions have allocated LLIs, the channel count can exceed the
> transaction-local nr_hw_descs and make the DMA error path read past the
> end of hw_desc[].
> 
> > diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > index 742e08cfab435..858004b5a8467 100644
> > --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > @@ -1052,10 +1052,9 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan,
> >  static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
> >  				   struct axi_dma_desc *desc_head)
> >  {
> > -	int count = atomic_read(&chan->descs_allocated);
> >  	int i;
> >  
> > -	for (i = 0; i < count; i++)
> > +	for (i = 0; i < desc_head->nr_hw_descs; i++)
> >  		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
> >  }
> 
> [Severity: High]
> This is a pre-existing issue, but the exact same out-of-bounds array access
> bug that this commit fixes in axi_chan_list_dump_lli() remains unpatched in
> axi_chan_block_xfer_complete():
> 
> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:axi_chan_block_xfer_complete() {
>     ...
>     int count = atomic_read(&chan->descs_allocated);
>     ...
>     for (i = 0; i < count; i++) {
>         hw_desc = &desc->hw_desc[i];
>     ...
> }
> 
> Does this function also need to be updated to use desc->nr_hw_descs for
> its loop limit? Using the channel-wide count (which is fetched outside the
> channel spinlock, presenting a TOCTOU race) could cause an out-of-bounds read
> on desc->hw_desc[]. If the garbage memory happens to match llp, it will modify
> the memory via hw_desc->lli->ctl_hi.
> 
> 
> [Severity: High]
> This is a pre-existing issue, but looking at dw_axi_dma_chan_prep_slave_sg(),
> is there a flaw in the SG iteration loop?
> 
> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:dw_axi_dma_chan_prep_slave_sg() {
>     ...
>     segment_len = DIV_ROUND_UP(sg_dma_len(sg), num_segments);
>     ...
>     } while (len >= segment_len);
>     ...
>     write_desc_llp(hw_desc, llp | lms);
>     ...
> }
> 
> If a DMA client submits a scatter-gather list where the length does not evenly
> divide into the hardware maximum block size (e.g., length 4097 and block
> length 4096 gives a segment_len of 2049, leaving 2048 bytes), the condition
> while (len >= segment_len) evaluates to false and exits the loop prematurely.
> 
> Does this silent truncation leave trailing descriptors uninitialized, causing an
> immediate NULL pointer dereference panic when write_desc_llp() tries to access
> hw_desc->lli?
> 
> 
> [Severity: High]
> This is a pre-existing issue, but does axi_desc_put() safely handle error
> rollbacks?
> 
> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:axi_desc_put() {
>     ...
>     for (i = 0; i < desc->nr_hw_descs; i++) {
>         ...
>         dma_pool_free(chan->desc_pool, hw_desc->lli, hw_desc->llp);
>         ...
>     }
>     ...
>     atomic_sub(descs_put, &chan->descs_allocated);
> }
> 
> If descriptor initialization fails midway (e.g., due to OOM causing -ENOMEM),
> the error path calls axi_desc_put(). Because it unconditionally iterates over
> all desc->nr_hw_descs elements, won't it pass NULL hw_desc->lli pointers to
> dma_pool_free() for unallocated entries, resulting in a panic?
> 
> Additionally, will subtracting the full capacity (descs_put) from
> chan->descs_allocated cause an underflow when only partially allocated?
> 

Thanks, confirmed. This is a real pre-existing SG split-loop bug and will be
fixed separately.

> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260828-dma-fix-v1-0-a6947f487e07@ultrarisc.com?part=2
> 

Best regards,
Jia Wang



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-08-28  7:01   ` Andy Shevchenko
@ 2026-08-28  9:34     ` Jia Wang
  0 siblings, 0 replies; 10+ messages in thread
From: Jia Wang @ 2026-08-28  9:34 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Jia Wang, Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Sia Jee Heng, dmaengine, linux-kernel

On 2026-08-28 10:01 +0300, Andy Shevchenko wrote:
> On Fri, Aug 28, 2026 at 08:48:27AM +0800, Jia Wang wrote:
> > axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
> > walk the hw_desc[] array of a single transaction. If multiple
> > transactions have allocated LLIs, the channel count can exceed the
> > transaction-local nr_hw_descs and make the DMA error path read past the
> > end of hw_desc[].
> > 
> > Use the descriptor-local nr_hw_descs count when dumping LLIs.
> 
> ...
> 
> >  {
> > -	int count = atomic_read(&chan->descs_allocated);
> >  	int i;
> >  
> > -	for (i = 0; i < count; i++)
> > +	for (i = 0; i < desc_head->nr_hw_descs; i++)
> 
> While at it,
> 
> 	for (unsigned int i = 0; i < desc_head->nr_hw_descs; i++)
> 
> and drop that 'int i;' as well.
> 

Will update it in v2, thanks.

> >  		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
> >  }
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 
> 

Best regards,
Jia Wang



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding
  2026-08-28  0:48 ` [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
  2026-08-28  0:59   ` sashiko-bot
@ 2026-08-28 19:32   ` Frank Li
  1 sibling, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-08-28 19:32 UTC (permalink / raw)
  To: Jia Wang
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Andy Shevchenko,
	Sia Jee Heng, dmaengine, linux-kernel

On Fri, Aug 28, 2026 at 08:48:26AM +0800, Jia Wang wrote:
> The snps,axi-max-burst-len property describes the number of beats in an
> AXI burst, while the ARLEN and AWLEN fields encode that value minus one.
>
> The driver keeps axi_rw_burst_len as the actual burst length so that
> dma_device.max_burst reports the correct value. However, it also programs
> that unencoded value directly into the hardware fields. A value of 256
> therefore overflows the 8-bit fields and can cause AXI decode errors.
>
> Subtract one only when constructing hardware descriptors, while keeping
> the actual value for dma_device.max_burst.
>
> Fixes: c454d16a7d5a ("dmaengine: dw-axi-dmac: Burst length settings")
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---

suggest switch to use FIELD_PREP() later

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index eebed2474210..742e08cfab43 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -706,7 +706,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
>  	ctlhi = CH_CTL_H_LLI_VALID;
>
>  	if (chan->chip->dw->hdata->restrict_axi_burst_len) {
> -		burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
> +		burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
>  		ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN |
>  			 burst_len << CH_CTL_H_ARLEN_POS |
>  			 burst_len << CH_CTL_H_AWLEN_POS;
> @@ -975,7 +975,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
>
>  		reg = CH_CTL_H_LLI_VALID;
>  		if (chan->chip->dw->hdata->restrict_axi_burst_len) {
> -			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
> +			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
>
>  			reg |= (CH_CTL_H_ARLEN_EN |
>  				burst_len << CH_CTL_H_ARLEN_POS |
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-08-28 19:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-28  0:48 [PATCH 0/2] dmaengine: dw-axi-dmac: Fix burst length encoding and LLI dump Jia Wang
2026-08-28  0:48 ` [PATCH 1/2] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
2026-08-28  0:59   ` sashiko-bot
2026-08-28  9:24     ` Jia Wang
2026-08-28 19:32   ` Frank Li
2026-08-28  0:48 ` [PATCH 2/2] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
2026-08-28  1:04   ` sashiko-bot
2026-08-28  9:33     ` Jia Wang
2026-08-28  7:01   ` Andy Shevchenko
2026-08-28  9:34     ` Jia Wang

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.