[PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer

Li Jun posted 1 patch 6 days, 20 hours ago
There is a newer version of this series
sound/soc/loongson/loongson_dma.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
[PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by Li Jun 6 days, 20 hours ago
The "invalid position" error occurred when the DMA position descriptor
returned an invalid address value (e.g., pos = -1048838144). This happened
because the `bytes_to_frames()` function returns a signed value, but when
`addr < runtime->dma_addr`, the subtraction produces a negative result that
gets interpreted as a large unsigned integer in comparisons.
when the addr is abnormal, for example,the DMA controller is abnormal in
hardware,x=0 should not be a point(x == runtime->buffer_size),but a range,
which includes the addr address being less than runtime ->dma1-adr, and
the addr exceeding the DMA address range.

[   32.834431][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   32.845019][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   32.855588][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   32.866145][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   32.995394][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   33.006025][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144
[   33.016748][ 2]  soc-audio soc-audio: invalid position: , pos = -1048838144

Signed-off-by: Li Jun <lijun01@kylinos.cn>
---
 sound/soc/loongson/loongson_dma.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
index a149b643175c..f0a7065ddae7 100644
--- a/sound/soc/loongson/loongson_dma.c
+++ b/sound/soc/loongson/loongson_dma.c
@@ -207,9 +207,15 @@ loongson_pcm_pointer(struct snd_soc_component *component,
 	desc = dma_desc_save(prtd);
 	addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
 
-	x = bytes_to_frames(runtime, addr - runtime->dma_addr);
-	if (x == runtime->buffer_size)
+	if (addr < runtime->dma_addr ||
+	    addr >= runtime->dma_addr + runtime->dma_bytes) {
 		x = 0;
+	} else {
+		x = bytes_to_frames(runtime, addr - runtime->dma_addr);
+		if (x >= runtime->buffer_size)
+			x = 0;
+	}
+
 	return x;
 }
 
-- 
2.25.1
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by Mark Brown 6 days, 11 hours ago
On Mon, Jun 01, 2026 at 04:43:09PM +0800, Li Jun wrote:
> The "invalid position" error occurred when the DMA position descriptor
> returned an invalid address value (e.g., pos = -1048838144). This happened
> because the `bytes_to_frames()` function returns a signed value, but when
> `addr < runtime->dma_addr`, the subtraction produces a negative result that
> gets interpreted as a large unsigned integer in comparisons.
> when the addr is abnormal, for example,the DMA controller is abnormal in
> hardware,x=0 should not be a point(x == runtime->buffer_size),but a range,
> which includes the addr address being less than runtime ->dma1-adr, and
> the addr exceeding the DMA address range.

I'm not clear in what circumstances we see an address that's outside the
DMA buffer?  Is this an error that should be reported as an XRUN instead
of silently masked (which will presumably lead to audible issues)?
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by lijun 6 days, 4 hours ago
for example,the DMA controller is abnormal in hardware
the addr = 0,
addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
x = bytes_to_frames(runtime, addr - runtime->dma_addr);
addr = 0 dma_addr=4195352576   x=-1048838144 i think the value of pos 
should not be a negative,return 0, maybe better.

2026/6/2 02:28, Mark Brown :
> I'm not clear in what circumstances we see an address that's outside the
> DMA buffer?  Is this an error that should be reported as an XRUN instead
> of silently masked (which will presumably lead to audible issues)?
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by Mark Brown 5 days, 16 hours ago
On Tue, Jun 02, 2026 at 08:49:29AM +0800, lijun wrote:

Please don't top post, reply in line with needed context.  This allows
readers to readily follow the flow of conversation and understand what
you are talking about and also helps ensure that everything in the
discussion is being addressed.

> for example,the DMA controller is abnormal in hardware
> the addr = 0,
> addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
> x = bytes_to_frames(runtime, addr - runtime->dma_addr);
> addr = 0 dma_addr=4195352576   x=-1048838144 i think the value of pos should
> not be a negative,return 0, maybe better.

Right, the question is if this happens in normal operation somehow or if
this is an error condition.  If this is an error should we be reporting
it as such, for example with snd_pcm_stop_xrun().
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by lijun 5 days, 4 hours ago
Is it handled like this?
desc = dma_desc_save(prtd);
addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
if (addr < runtime->dma_addr || addr > runtime->dma_addr + 
runtime->dma_bytes) {
         dev_warn(dev, "WARNING! dma_addr:0x%x\n", addr);
         snd_pcm_stop_xrun(substream);
         x = 0;
} else {
         x = bytes_to_frames(runtime, addr - runtime->dma_addr);
         if (x == runtime->buffer_size)
         x = 0;
}

在 2026/6/2 21:13, Mark Brown 写道:
> On Tue, Jun 02, 2026 at 08:49:29AM +0800, lijun wrote:
>
> Please don't top post, reply in line with needed context.  This allows
> readers to readily follow the flow of conversation and understand what
> you are talking about and also helps ensure that everything in the
> discussion is being addressed.
>
>> for example,the DMA controller is abnormal in hardware
>> the addr = 0,
>> addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
>> x = bytes_to_frames(runtime, addr - runtime->dma_addr);
>> addr = 0 dma_addr=4195352576   x=-1048838144 i think the value of pos should
>> not be a negative,return 0, maybe better.
> Right, the question is if this happens in normal operation somehow or if
> this is an error condition.  If this is an error should we be reporting
> it as such, for example with snd_pcm_stop_xrun().
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by Mark Brown 4 days, 21 hours ago
On Wed, Jun 03, 2026 at 09:07:30AM +0800, lijun wrote:
> Is it handled like this?
> desc = dma_desc_save(prtd);
> addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
> if (addr < runtime->dma_addr || addr > runtime->dma_addr +
> runtime->dma_bytes) {
>         dev_warn(dev, "WARNING! dma_addr:0x%x\n", addr);
>         snd_pcm_stop_xrun(substream);

I think that should do the trick (assuming this isn't something that
occurs all the time but only in error conditions).
Re: [PATCH v2] ASoC: loongson: Fix invalid position error in ls_pcm_pointer
Posted by lijun 5 days, 4 hours ago
Is it handled like this?
desc = dma_desc_save(prtd); addr = ((u64)desc->saddr_hi << 32) | 
desc->saddr; if (addr < runtime->dma_addr || addr > runtime->dma_addr + 
runtime->dma_bytes) { dev_warn(dev, "WARNING! dma_addr:0x%x\n", addr); 
snd_pcm_stop_xrun(substream); x = 0; } else { x = 
bytes_to_frames(runtime, addr - runtime->dma_addr); if (x == 
runtime->buffer_size) x = 0; }

  2026/6/2 21:13, Mark Brown :
> On Tue, Jun 02, 2026 at 08:49:29AM +0800, lijun wrote:
>
> Please don't top post, reply in line with needed context.  This allows
> readers to readily follow the flow of conversation and understand what
> you are talking about and also helps ensure that everything in the
> discussion is being addressed.
>
>> for example,the DMA controller is abnormal in hardware
>> the addr = 0,
>> addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
>> x = bytes_to_frames(runtime, addr - runtime->dma_addr);
>> addr = 0 dma_addr=4195352576   x=-1048838144 i think the value of pos should
>> not be a negative,return 0, maybe better.
> Right, the question is if this happens in normal operation somehow or if
> this is an error condition.  If this is an error should we be reporting
> it as such, for example with snd_pcm_stop_xrun().