DMA Engine development
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Ben Dooks <ben.dooks@codethink.co.uk>,
	Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>,
	Eugeniy.Paltsev@synopsys.com, dmaengine@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-5.15] dmaengine: dw-axi-dmac: fix __le32 on set of CH_CTL_H_LLI_VALID
Date: Mon, 19 Oct 2026 09:52:15 -0400	[thread overview]
Message-ID: <20261019135441.1420968-444-sashal@kernel.org> (raw)
In-Reply-To: <20261019135441.1420968-1-sashal@kernel.org>

From: Ben Dooks <ben.dooks@codethink.co.uk>

[ Upstream commit 89aba9c39bdda8a973a6ffed7c9e93321edcfc16 ]

When writing the lli->ctl_hi, this is an __le32 type so the
value being orred should be convered to __le32 by cpu_to_le32.

Fixes 1deb96c0fa58a ("dmaegine: dw-axi-dmac: Support device_prep_dma_cyclic()")
--
Note, the call to axi_chan_irq_clear() is passing lli->status_lo
through which is also an __le32 but it does not seem to be set
anywhere. Is this also a bug?

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Link: https://patch.msgid.link/20260617084944.705266-1-ben.dooks@codethink.co.uk
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

# Stable backport analysis: `89aba9c39bdda` (`dmaengine: dw-axi-dmac:
fix __le32 on set of CH_CTL_H_LLI_VALID`)

Local tree: **v7.3-rc4** (`7.3.0-rc4`, detached HEAD `f0100363d8c37`).
The cyclic DW AXI DMA path exists here (introduced in v5.12). Decision
is for this checkout only.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[dmaengine / dw-axi-dmac] [fix] [endian-convert
`CH_CTL_H_LLI_VALID` before OR into `__le32` `lli->ctl_hi`]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Fixes 1deb96c0fa58a ("dmaegine: dw-axi-dmac: Support
  device_prep_dma_cyclic()")` — malformed (`Fixes` missing the colon),
  so it would not auto-route to stable. SHA is real:
  `1deb96c0fa58afe0f5c4aa8e5916baa9454979d6`.
- `Link: https://patch.msgid.link/20260617084944.705266-1-
  ben.dooks@codethink.co.uk`
- `Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>` (author)
- `Signed-off-by: Vinod Koul <vkoul@kernel.org>` (dmaengine maintainer)
- No `Reported-by`, `Tested-by`, `Reviewed-by`, `Acked-by`, `Cc:
  stable`, syzbot, or CVE.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `lli->ctl_hi` is `__le32`; the cyclic completion path ORs in
  host-endian `CH_CTL_H_LLI_VALID` (`BIT(31)`).
- **Symptom:** On a big-endian CPU the LLI_VALID bit is written as the
  wrong byte, so the DMA engine does not see the descriptor as valid
  when cyclic transfers re-arm. Little-endian is a no-op (`cpu_to_le32`
  is identity).
- **Version:** Introduced with cyclic support (`1deb96c0fa58a`,
  v5.12-rc1).
- **Side note in the message:** `axi_chan_irq_clear(chan,
  lli->status_lo)` also passes `__le32` as `u32`; that is a separate
  pre-existing issue, not changed here.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject and body say “fix”. Author later told
Frank Li this was a **sparse `__le32` cast warning**; that is still a
real endian/type bug in a hardware LLI, not style cleanup.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c` (`1` insertion,
  `1` deletion)
- Function: `axi_chan_block_xfer_complete()`
- Scope: **single-file, 1-line surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Cyclic IRQ path only (`chan->cyclic`). After matching the
current LLP, the old code did `hw_desc->lli->ctl_hi |=
CH_CTL_H_LLI_VALID`. New code uses `|= cpu_to_le32(CH_CTL_H_LLI_VALID)`.
Non-cyclic completion is unchanged.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **(f) Type / endianness.** `struct axi_dma_lli.ctl_hi` is
`__le32`; `CH_CTL_H_LLI_VALID` is `BIT(31)` in `dw-axi-dmac.h`.
Descriptor setup already stores `ctl_hi` with `cpu_to_le32()`
(`dw_axi_dma_set_hw_desc()` ~line 715, memcpy path ~line 985). This
cyclic re-arm was the missed conversion from `1deb96c0fa58a`.

On BE, `|= BIT(31)` stores `80 00 00 00`; the LE engine reads `BIT(7)`
instead of bit 31, so LLI_VALID is not set and the cyclic ring does not
restart.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: **Obviously correct** and consistent with every other `ctl_hi`
store in the file. Minimal. LE codegen is unchanged. No
API/locking/refcount change. Does not fix the `status_lo` IRQ-clear
question; that does not make this line wrong.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record: Cyclic block and the original `|= CH_CTL_H_LLI_VALID` are from
**`1deb96c0fa58a` (Sia Jee Heng, 2021-01-25)**. First contained in
**v5.12-rc1**. Long-lived, not recent.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: `1deb96c0fa58a` added `device_prep_dma_cyclic()` (ALSA-style
cyclic DMA). It is an ancestor of HEAD (`git merge-base --is-ancestor`
exit 0). No later LLI_VALID fix besides this commit.

**Step 3.3: CHECK FILE HISTORY**
Record: Recent work is PM, CV1800B, StarFive, per-channel IRQ — none of
it is a prerequisite for this one-line OR. **Standalone**, not `patch
X/Y`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Ben Dooks has prior dw-axi-dmac fixes (`ignore interrupt if no
descriptor`, `do not print NULL LLI`). Not the subsystem maintainer;
Vinod Koul applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Needs cyclic support (`chan->cyclic`, `hw_desc->lli->ctl_hi`).
That is in this tree since v5.12. **Applies standalone.**

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore / msgid: https://patch.msgid.link/20260617084944.705266-1-
  ben.dooks@codethink.co.uk
- **v1 only** (`b4 dig -a`); committed version is that v1
  (`89aba9c39bdda`).
- Frank Li: asked whether it would pass sparse.
- Ben Dooks: *“This was fixing a __le32 cast warning from sparse, forgot
  to put the actual warning in the commit message.”*
- Vinod Koul: **Applied, thanks!** No NAK, no `Cc: stable` request.
- Sashiko bot flagged **pre-existing** issues (`status_lo`,
  `descs_allocated` vs `nr_hw_descs`, cyclic period math) — not
  introduced by this patch.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Ben Dooks, Eugeniy Paltsev (Synopsys / binding
maintainer), Vinod Koul, Frank Li, `dmaengine@vger.kernel.org`, `linux-
kernel@vger.kernel.org`. Maintainer applied it. Frank commented; no
formal Reviewed-by.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: **No user bugzilla/syzbot report.** Trigger was sparse, not a
field crash. Direct lore fetch of the msgid returned 403; the full
thread was recovered via `b4 dig -m`.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone. Author asked about `status_lo`; that was **not**
patched here and is not required for this conversion.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: Web search of lore stable for this subject did not turn up a
prior stable discussion or an explicit rejection. **UNVERIFIED** that
every stable archive was exhaustively scanned (lore HTML is 403 /
Anubis-protected).

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `axi_chan_block_xfer_complete()` (modified). Related:
`dw_axi_dma_interrupt()`, `dw_axi_dma_chan_prep_cyclic()`,
`dw_axi_dma_set_hw_desc()`.

**Step 5.2: TRACE CALLERS**
Record: Only caller is `dw_axi_dma_interrupt()` when
`DWAXIDMAC_IRQ_DMA_TRF` is set. Same handler is registered from probe
(`devm_request_irq`). **IRQ context.** Userspace reaches it via
dmaengine cyclic prep (ALSA and other slave cyclic clients).

**Step 5.3: TRACE CALLEES**
Record: `axi_chan_irq_clear()`, `vchan_cyclic_callback()`,
`axi_chan_enable()`, `vchan_next_desc()`. The important store is into
the DMA-visible LLI.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: userspace cyclic DMA → `dw_axi_dma_chan_prep_cyclic` (sets
LLI_VALID via `cpu_to_le32`, `set_desc_last`) → HW completes a block →
IRQ → re-set LLI_VALID → `axi_chan_enable`. **Reachable from userspace**
on boards that use this DMAC for cyclic audio/peripheral DMA.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Every other `ctl_hi` assignment already uses `cpu_to_le32()`.
This was the remaining `|=` of a host `BIT()` into `__le32`. No sibling
driver copy of this exact bug was searched beyond this file.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes, in this lineage.** Cyclic path is present; the bug was
the missing `cpu_to_le32` on the re-arm OR, from **v5.12**. Current HEAD
already has the fixed line (`ctl_hi |= cpu_to_le32(CH_CTL_H_LLI_VALID)`
at line 1129). Introduced after 5.12, long before 7.3.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Surrounding cyclic IRQ code is still the 2021 structure. **Clean
apply** on a tree that still has the unconverted `|=`. No conflicting
refactor in this function.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This exact conversion is the only LLI_VALID endian fix. No
alternate fix. Presence of `89aba9c39bdda` on 7.3-rc4 is expected for a
mainline commit and is **not** treated as “already selected for stable.”

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **dmaengine / Synopsys DW AXI DMAC** (`CONFIG_DW_AXI_DMAC`).
**IMPORTANT** for those SoCs, not core mm/VFS. In-tree users: StarFive
JH7110/JH8100, Intel Keem Bay / Agilex5, Sophgo CV1800B/SG2044, T-Head
TH1520, Canaan K210, **ARC HSDK** (`CONFIG_DW_AXI_DMAC=y` in
`hsdk_defconfig`).

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Actively maintained (StarFive, Sophgo, PM, per-channel IRQ).
Cyclic completion itself has been stable since 2021.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Driver-specific**, plus **endian-specific**. Production DTs
are RISC-V/ARM64 (LE), where this is a no-op. ARC can be built
`CPU_BIG_ENDIAN`; HSDK defconfig is LE but BE ARC + this IP is a valid
config. Cyclic clients (ALSA) are the functional path.

**Step 8.2: TRIGGER CONDITIONS**
Record: Cyclic DMA block-complete IRQ. Common on audio; unused if the
channel is memcpy-only. Unprivileged users can trigger it if they have
the PCM/DMA device. Not a race.

**Step 8.3: FAILURE MODE SEVERITY**
Record: On BE, LLI_VALID is not set → cyclic DMA does not re-arm →
**audio/DMA stall or dropped periods**, not an oops. On LE, **no runtime
change**. Severity: **MEDIUM** on BE, **none** on LE. Not
UAF/panic/corruption.

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** Restores cyclic DMA descriptor validity on BE; matches
  the rest of the driver; zero LE behavior change.
- **Risk:** Very low (1 line, standard conversion).
- **Ratio:** Favorable. The strict “crash/security/deadlock” bar is not
  met; the recognized **endianness/type** class and zero regression risk
  still make it appropriate.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real `__le32` vs host `BIT(31)` mismatch in a DMA-visible LLI.
- Same file already converts every other `ctl_hi` store.
- Bug present since v5.12 cyclic support; that commit is in this tree.
- 1 line, obviously correct, maintainer-applied.
- BE cyclic DMA would fail to re-validate descriptors.
- Standalone; no new API.

**AGAINST:**
- Author described it as a sparse warning; no user/syzbot report.
- In-tree boards are LE, so this is a no-op for typical 7.3 users of
  JH7110/Keem Bay/Sophgo.
- Not a crash, UAF, deadlock, or security issue.
- `status_lo` concern left unfixed (out of scope).

**UNRESOLVED:** Exhaustive stable-list search (lore 403). Exact sparse
warning text was never pasted in the commit.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — matches existing stores;
   applied by Vinod Koul. No extra Tested-by.
2. Fixes a real bug that affects users? **PASS** — wrong LLI bit on BE;
   type-incorrect on all builds.
3. Important issue? **PASS (low end of the bar)** — functional cyclic
   DMA failure on BE, not a panic. Endianness/type fixes of this shape
   are accepted stable material; this is not a warning-only whitespace
   change.
4. Small and contained? **PASS** — 1 line, one function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — cyclic path and `Fixes:`
   target exist; context is unchanged.

**Step 9.3: EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/docs exception. Closest: type-
correctness / sparse, but the runtime BE effect is a real hardware-
descriptor bug.

**Step 9.4: DECISION**
This tree has the driver and the v5.12 cyclic path the bug was
introduced in. The change is a one-line, obviously correct endian
conversion on a DMA linked-list field. Risk is negligible; on BE it is
the difference between a valid LLI_VALID bit and a silent cyclic stall.
That meets stable rules for this checkout.

---

### What the commit solves for this tree
Cyclic completion re-arms `CH_CTL_H_LLI_VALID` in an `__le32` LLI.
Without `cpu_to_le32()`, a big-endian CPU writes the wrong bit and the
DW AXI engine will not treat the descriptor as valid. Little-endian
machines (StarFive, Intel, Sophgo, default HSDK) generate the same code
as before.

### Risk vs benefit
Benefit is correctness of cyclic DMA on BE and type-safety of a hardware
descriptor. Risk is essentially zero. No dependencies beyond cyclic
support, which is already here.

---

## Verification
- **[Phase 1]** Parsed tags: malformed `Fixes 1deb96c0fa58a` (no colon);
  Link msgid; SOBs Ben Dooks + Vinod Koul; no syzbot/Reported-by/Cc
  stable.
- **[Phase 2]** Diff: 1 line in `axi_chan_block_xfer_complete()`;
  `ctl_hi` is `__le32` (`dw-axi-dmac.h:85`); `CH_CTL_H_LLI_VALID` is
  `BIT(31)` (line 256); other stores already use `cpu_to_le32` (lines
  715, 985, 1129 after the fix).
- **[Phase 3]** `git blame`: cyclic OR from `1deb96c0fa58a`; `git
  describe --contains 1deb96c0fa58a` → `v5.12-rc1~57^2~12`.
- **[Phase 3]** `git merge-base --is-ancestor 1deb96c0fa58a HEAD` → 0
  (present). `git merge-base --is-ancestor 89aba9c39bdda HEAD` → 0
  (commit is in this mainline checkout; not used as a circular “already
  selected” NO).
- **[Phase 3]** `git show 1deb96c0fa58a`: added `hw_desc->lli->ctl_hi |=
  CH_CTL_H_LLI_VALID` without conversion.
- **[Phase 4]** `b4 dig -c 89aba9c39bdda`: msgid
  `20260617084944.705266-1-ben.dooks@codethink.co.uk`.
- **[Phase 4]** `b4 dig -a`: v1 only.
- **[Phase 4]** `b4 dig -w`: Vinod, Eugeniy Paltsev, Frank Li, dmaengine
  list.
- **[Phase 4]** `b4 dig -m`: Frank Li sparse question; Ben confirmed
  sparse `__le32` warning; Vinod applied; Sashiko pre-existing notes
  only.
- **[Phase 4]** WebFetch lore URL: 403; thread recovered from mbox
  instead.
- **[Phase 4]** Stable lore search: no hit for this patch (UNVERIFIED
  exhaustive).
- **[Phase 5]** Callers: only `dw_axi_dma_interrupt()` on
  `DWAXIDMAC_IRQ_DMA_TRF`; IRQ from probe.
- **[Phase 6]** `git describe HEAD` → `v7.3-rc4-27-gf0100363d8c37`;
  `make kernelversion` → `7.3.0-rc4`.
- **[Phase 6]** Buggy cyclic path exists; `1deb96c0fa58a` is ancestor;
  apply context still the 2021 function.
- **[Phase 7]** DTs: `snps,axi-dma-1.01a` / StarFive / Sophgo / Intel /
  ARC HSDK; `hsdk_defconfig` has `CONFIG_DW_AXI_DMAC=y`, not
  `CPU_BIG_ENDIAN`.
- **[Phase 8]** Failure mode: BE cyclic DMA fails to set LLI_VALID
  (stall), not oops; LE no-op.
- **UNVERIFIED:** Exact sparse warning string; whether any production BE
  board actually ships this IP.

**YES**

 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 ea4e47ee0d710..343d32eeaa29a 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1128,7 +1128,7 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
 				hw_desc = &desc->hw_desc[i];
 				if (hw_desc->llp == llp) {
 					axi_chan_irq_clear(chan, hw_desc->lli->status_lo);
-					hw_desc->lli->ctl_hi |= CH_CTL_H_LLI_VALID;
+					hw_desc->lli->ctl_hi |= cpu_to_le32(CH_CTL_H_LLI_VALID);
 					desc->completed_blocks = i;
 
 					if (((hw_desc->len * (i + 1)) % desc->period_len) == 0)
-- 
2.53.0


       reply	other threads:[~2026-10-19 14:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:52 ` Sasha Levin [this message]
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] dmaengine: pl330: remove debugfs file on teardown Sasha Levin

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=20261019135441.1420968-444-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=Eugeniy.Paltsev@synopsys.com \
    --cc=ben.dooks@codethink.co.uk \
    --cc=dmaengine@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=stable@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox