From: Li Jun Date: Thu, 11 Jun 2026 01:00:45 +0000 (+0800) Subject: ASoC: loongson: Fix invalid position error in ls_pcm_pointer X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=6ad3914e06a48a02e362d0df2b1073c7c567c93d;p=thirdparty%2Fkernel%2Flinux.git ASoC: loongson: Fix invalid position error in ls_pcm_pointer 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.the value of pos should not better a negative,return 0, maybe better. [ 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 [Remove XRUN reporting I'd mistakenly avised adding on prior review -- broonie] Link: https://patch.msgid.link/20260611010045.3668574-1-lijun01@kylinos.cn Signed-off-by: Mark Brown --- diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c index a149b643175c..f3ed14a48bd5 100644 --- a/sound/soc/loongson/loongson_dma.c +++ b/sound/soc/loongson/loongson_dma.c @@ -199,6 +199,7 @@ loongson_pcm_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; + struct device *dev = substream->pcm->card->dev; struct loongson_runtime_data *prtd = runtime->private_data; struct loongson_dma_desc *desc; snd_pcm_uframes_t x; @@ -207,9 +208,16 @@ 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) { + dev_warn(dev, "WARNING! dma_addr:0x%llx\n", addr); x = 0; + } else { + x = bytes_to_frames(runtime, addr - runtime->dma_addr); + if (x == runtime->buffer_size) + x = 0; + } + return x; }