sound/soc/loongson/loongson_dma.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
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
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)?
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)?
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().
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().
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).
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().
© 2016 - 2026 Red Hat, Inc.