From: Mahad Ibrahim <mahad.ibrahim.dev@gmail.com>
To: Keguang Zhang <keguang.zhang@gmail.com>, Vinod Koul <vkoul@kernel.org>
Cc: Frank Li <Frank.Li@kernel.org>,
linux-mips@vger.kernel.org, dmaengine@vger.kernel.org,
linux-kernel@vger.kernel.org,
Mahad Ibrahim <mahad.ibrahim.dev@gmail.com>
Subject: [PATCH] dmaengine: loongson1-apb-dma: fix residue calculation for queued descriptors
Date: Mon, 20 Jul 2026 14:25:38 +0000 [thread overview]
Message-ID: <20260720142538.2766-1-mahad.ibrahim.dev@gmail.com> (raw)
ls1x_dma_tx_status() locates the descriptor actively being processed by
walking the LLI list and comparing the hardware reported next descriptor
pointer against each element's next-descriptor pointer.
A list_for_each_entry macro is used in the comparison phase, which
internally expands to the container_of macro to find the current
ls1x_dma_lli's next-descriptor pointer to compare against. However a
problem occurs when the loop reaches the final lli list element and wraps
around to the head. The head is a different struct ls1x_dma_desc. It goes
down to the offset the node member would be at in ls1x_dma_lli inside of
ls1x_dma_desc.
This leaves the lli pointer somewhere inside of ls1x_dma_desc at the end
of the loop. The subsequent phys debug value read therefore would print
garbage as a valid phys address.
The primary bug occurs in the residue calculation list_for_each_entry_from
macro. The lli pointer still points to somewhere inside of ls1x_dma_desc,
when the list_for_each_entry_from performs the same wrong offset
calculation on ls1x_dma_desc to determine the stop condition of the loop,
it lands at the same offset that lli pointer is on, and the loop
immediately stops.
This produces a 0 residue value, while it should be the entire length of
the lli list chain. The driver advertises DMA_RESIDUE_GRANULARITY_SEGMENT,
so a 0 residue would mean the transfer has completed.
Found by the following Coccinelle check:
scripts/coccinelle/iterators/use_after_iter.cocci
drivers/dma/loongson/loongson1-apb-dma.c:461:6-9: ERROR: invalid
reference to the index variable of the iterator on line 450
Note the check still reports this line after the fix; the remaining use
is safe (the cursor is only dereferenced on the match path, or reset to
the first entry otherwise).
I did not see a bug upstream detailing this error, nor do I have the
hardware to confirm this bug or error, all this is from a pure code
examination.
As I do not possess the hardware, I cannot test the patch. Compile tested
only with mips64-linux-gnu-gcc.
Signed-off-by: Mahad Ibrahim <mahad.ibrahim.dev@gmail.com>
---
drivers/dma/loongson/loongson1-apb-dma.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/loongson/loongson1-apb-dma.c b/drivers/dma/loongson/loongson1-apb-dma.c
index 89786cbd20ab..8bb6e6e5719d 100644
--- a/drivers/dma/loongson/loongson1-apb-dma.c
+++ b/drivers/dma/loongson/loongson1-apb-dma.c
@@ -439,6 +439,7 @@ static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan,
struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vd);
struct ls1x_dma_lli *lli;
dma_addr_t next_phys;
+ bool found = false;
/* get the current lli */
if (ls1x_dma_query(chan, &chan->curr_lli->phys))
@@ -447,11 +448,17 @@ static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan,
/* locate the current lli */
next_phys = chan->curr_lli->hw[LS1X_DMADESC_NEXT];
list_for_each_entry(lli, &desc->lli_list, node)
- if (lli->hw[LS1X_DMADESC_NEXT] == next_phys)
+ if (lli->hw[LS1X_DMADESC_NEXT] == next_phys) {
+ found = true;
break;
-
- dev_dbg(chan2dev(dchan), "current lli_phys=%pad",
- &lli->phys);
+ }
+
+ if (!found)
+ lli = list_first_entry(&desc->lli_list,
+ struct ls1x_dma_lli, node);
+ else
+ dev_dbg(chan2dev(dchan), "current lli_phys=%pad",
+ &lli->phys);
/* count the residues */
list_for_each_entry_from(lli, &desc->lli_list, node)
--
2.54.0
next reply other threads:[~2026-07-20 14:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 14:25 Mahad Ibrahim [this message]
2026-07-20 14:40 ` [PATCH] dmaengine: loongson1-apb-dma: fix residue calculation for queued descriptors sashiko-bot
2026-07-21 7:32 ` Keguang Zhang
2026-07-21 16:14 ` Mahad Ibrahim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260720142538.2766-1-mahad.ibrahim.dev@gmail.com \
--to=mahad.ibrahim.dev@gmail.com \
--cc=Frank.Li@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=keguang.zhang@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.