Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup()
@ 2026-10-19 13:44 Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] iommu/rockchip: Clear stale page faults before enabling stall Sasha Levin
                   ` (48 more replies)
  0 siblings, 49 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:44 UTC (permalink / raw)
  To: patches, stable
  Cc: Daniel Golle, Jakub Kicinski, Sasha Levin, chester.a.unal, andrew,
	olteanv, davem, edumazet, pabeni, matthias.bgg,
	angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
	linux-mediatek

From: Daniel Golle <daniel@makrotopia.org>

[ Upstream commit 1ae63b018d3d70e96d420b59a1334860cf232bc6 ]

mt7531_setup() reads CORE_PLL_GROUP4 through the MT7531 indirect c45
PHY access, modifies it and writes it back to enable the PHY core
PLL, but checks neither the read nor the write. Now that the indirect
access functions propagate command-write failures, a failed read
returns a negative errno that would be bit-modified and written back
into the PLL register, and a failed write-back would go unnoticed.
Check both and bail out. The adjacent EEE advertisement writes push a
constant value and cannot corrupt state, so they are left as is.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://patch.msgid.link/a7dfe3b66ea6ac1ae7915034de0527060e6ddcd4.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a real, small error-path fix for this 6.12 tree: an unchecked
CORE_PLL_GROUP4 RMW can write a negative errno into the MT7531 PHY PLL.
The buggy code is present here, and a related callee change already
landed.

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: `[net: dsa: mt7530]` `[check]` Check CORE_PLL_GROUP4 read/write
results in `mt7531_setup()`. “check” is used as a missing-return-value
fix, not a feature add.

**Step 1.2 — Tags (from the candidate message)**
Record:
- `Signed-off-by: Daniel Golle <daniel@makrotopia.org>` (author)
- `Link: https://patch.msgid.link/a7dfe3b66ea6ac1ae7915034de0527060e6ddc
  d4.1785811140.git.daniel@makrotopia.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer
  applied it)

Ignored per instructions: any pipeline “already selected” markers.

Original mailing-list version (openwall/lkml, same msgid) also had:
- `Fixes: c288575f7810 ("net: dsa: mt7530: Add the support of MT7531
  switch")`
- No `Cc: stable`, no `Reported-by`, no `Reviewed-by` on this patch
  itself

Cover letter for the series: Andrew Lunn’s `Reviewed-by` was collected
on patches 1–3 and 6, not on this one (it was new in v2).

**Step 1.3 — Body**
Record:
- Bug: `mt7531_setup()` RMW of `CORE_PLL_GROUP4` via
  `mt7531_ind_c45_phy_read/write` does not check either result.
- Failure mode: a failed read returns a negative errno that is bit-
  modified and written into the PHY core PLL; a failed write is ignored.
- Author’s framing: this became acute once the indirect helpers
  propagate command-write failures.
- Adjacent EEE advertisement writes are constant `0`, so they cannot
  corrupt RMW state and are left alone.

**Step 1.4 — Hidden bug fix?**
Record: Not hidden. It is an explicit missing-error-check fix. The “now
that …” wording is series context (patch 3/6), not a cleanup-only
change.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- File: `drivers/net/dsa/mt7530.c` only
- Function: `mt7531_setup()`
- ~10 insertions, ~4 deletions (candidate hunk); net +6 lines of checks
- Scope: single-file surgical caller fix

**Step 2.2 — Flow**
Record: Before, `u32 val = mt7531_ind_c45_phy_read(...)` then OR/AND
bits and write back, ignoring errors. After, store the `int` in `ret`,
return if `ret < 0`, copy into `val` only on success, check the write,
return on write failure. Probe/`sw_setup` fails instead of programming
PLL from an errno.

**Step 2.3 — Bug mechanism**
Record: **Logic / error-path correctness**, specifically “treat errno as
register data.”
- `mt7531_ind_c45_phy_read()` returns `int` (PHY data or negative
  errno).
- Assigned to `u32 val`, then modified (`MT7531_RG_SYSPLL_DMY2 |
  MT7531_PHY_PLL_BYPASS_MODE`, clear `MT7531_PHY_PLL_OFF`).
- Written through `mt7531_ind_c45_phy_write(..., u16 data)`, so a value
  such as `(u32)-ETIMEDOUT` (`0xFFFFFF92`) truncates to
  `0xFF92`/`0xFFD2` and is programmed into the PHY PLL.
- Write errors (already returned on poll timeout in this tree) are
  ignored.

**Step 2.4 — Fix quality**
Record: Obviously correct. `ret` is already declared in
`mt7531_setup()`. No API/locking/data-structure change. Regression risk
is that a failing MDIO access now fails switch setup instead of
continuing with a bogus PLL; that is the intended behavior. Risk of the
fix itself is very low.

## Phase 3: Git history

**Step 3.1 — Blame**
Record:
- Unchecked RMW originates in `c288575f7810` (Landen Chao, 2020-09-14):
  “Add the support of MT7531 switch”.
- Helper names/`MT753X_CTRL_PHY_ADDR` from later Arınç ÜNAL refactors
  (`868ff5f4944aa9`, `06dfcd4098cfdc`, 2024).
- Poll path in this tree already uses `regmap_read_poll_timeout()` from
  `96e0f5184af69` (Daniel Golle, applied 2026-08-09): “error out on
  failed reads in MT7531 PHY polling”.

**Step 3.2 — Fixes: target**
Record: `c288575f7810` **is** an ancestor of this tree. The original
MT7531 support (and this RMW) has been here since well before 6.12.

**Step 3.3 — Related file history**
Record:
- `96e0f5184af69` — already in this tree. Makes poll/read failures
  return negative errno instead of continuing with garbage “success”
  data.
- `93d46870c5440` — already in this tree. Same class: do not treat
  `bus->read()` errno as register data.
- This candidate is the missing **caller** check for the one in-driver
  RMW of `mt7531_ind_c45_phy_read()`.

**Step 3.4 — Author**
Record: Daniel Golle is a regular MT7530 contributor (PLL/PHY access,
MT7988, MT7531BE). Same author as the already-backported poll-error fix.

**Step 3.5 — Prerequisites**
Record: This is patch **4/6** of “fix remaining swallowed MDIO access
errors”. Patch 3 (`error out on failed PHY_IAC command writes`, upstream
`1c95dcb7e923`) is **not** in this tree. It is not required to compile
or to apply this hunk: the helpers already return `int`, and
`mt7531_ind_c45_phy_read/write` already return negative errno on
`regmap_read_poll_timeout()` failure. Patch 3 only adds extra error
returns from discarded `mt7530_mii_write()` of `MT7531_PHY_IAC`.
Standalone apply: **yes**.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
Record:
- `b4 dig` on the msgid failed (`Cannot find a commit matching …`).
- lore.kernel.org fetches returned 403.
- Fallback: openwall + lkml + cover letter.
- Lore/openwall URL: msgid `a7dfe3b66ea6ac1ae7915034de0527060e6ddcd4.178
  5811140.git.daniel@makrotopia.org` (Tue 4 Aug 2026).
- Cover: https://lists.openwall.net/netdev/2026/08/04/90
- This patch was **new in v2**, flagged by Sashiko AI review of v1 as
  another swallowed MDIO error.
- Cover letter: “the call site exposed once patch 3 makes the MT7531
  indirect c45 access propagate command-write failures.”
- Applied by Jakub Kicinski; patchwork bot lists upstream as
  `1ae63b018d3d`.
- No NAK found in the material that could be retrieved.

**Step 4.2 — Recipients**
Record: To/Cc included Andrew Lunn, Vladimir Oltean, netdev maintainers,
MediaTek/DSA people, `netdev@`, `linux-mediatek@`. Appropriate audience.
Andrew reviewed 1–3 and 6; this patch 4 had no `Reviewed-by` in the
submission.

**Step 4.3 — Bug report**
Record: No syzbot/bugzilla. Found by AI review of the MDIO-error series,
not a user crash report.

**Step 4.4 — Series**
Record: v2 6-patch series. Patches 1, 2, 3, 5, 6 are **not** in this
tree. This patch is self-contained at the `mt7531_setup()` call site.

**Step 4.5 — Stable list**
Record: No stable-specific discussion found (lore.kernel.org/stable
search did not return this subject). UNVERIFIED: whether anyone later
nominated it on stable@.

## Phase 5: Code semantic analysis

**Step 5.1 — Functions**
Record: `mt7531_setup()` only. Helpers `mt7531_ind_c45_phy_read/write`
are not modified.

**Step 5.2 — Callers**
Record:
- `mt7531_setup` is `.sw_setup` for `ID_MT7531` only (`mt753x_table`).
- `mt753x_setup()` calls `priv->info->sw_setup(ds)` and aborts on error.
- `mt753x_setup` is `.setup` in `mt7530_switch_ops` → DSA switch setup /
  probe.
- MT7988/EN7581 use `mt7988_setup()` → `mt7531_setup_common()`; they do
  **not** run this PLL RMW.

**Step 5.3 — Callees**
Record: `mt7531_ind_c45_phy_read/write` lock the MDIO mutex, write
`MT7531_PHY_IAC`, poll `MT7531_PHY_ACS_ST`. On poll/read failure they
`goto out` and return negative `ret`. `mt7530_mii_write()` already
returns `regmap_write` errors, but those returns are still discarded in
this tree (patch 3).

**Step 5.4 — Reachability**
Record: Probe-time only, when an MT7531 DSA switch is instantiated
(`CONFIG_NET_DSA_MT7530`). Not a syscall hot path. Userspace cannot
trigger it except by causing device probe. Trigger is MDIO/regmap
failure or IAC poll timeout during setup.

**Step 5.5 — Similar patterns**
Record: The only in-driver `mt7531_ind_c45_phy_read()` call site is this
PLL RMW. Other `mt7531_ind_c45_phy_write()` uses in the same function
are constant EEE-adv `0`. Phylib also uses these as `.phy_read_c45` /
`.phy_write_c45`.

## Phase 6: Local tree (6.12.111 / `pending-6.12`)

**Step 6.1 — Buggy code present?**
Record: **Yes.** `drivers/net/dsa/mt7530.c` `mt7531_setup()` still does:

```2665:2672:drivers/net/dsa/mt7530.c
        val = mt7531_ind_c45_phy_read(priv,
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
                                      MDIO_MMD_VEND2, CORE_PLL_GROUP4);
        val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
        val &= ~MT7531_PHY_PLL_OFF;
        mt7531_ind_c45_phy_write(priv,
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
                                 MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
```

Bug introduced with MT7531 support (`c288575f7810`, v5.10-era). Present
in 6.12.

**Step 6.2 — Backport difficulty**
Record: **Clean apply** aside from line-number offset (2665 here vs 2764
in the candidate diff). Surrounding comments and EEE loop match. `ret`
is already in scope.

**Step 6.3 — Related fixes already here**
Record: `96e0f5184af69` already backported. That change makes failed IAC
polls/reads return errno into this unchecked caller, so this tree
already has the callee half of the fix without the caller half. No
equivalent caller check exists yet.

## Phase 7: Subsystem context

**Step 7.1**
Record: `drivers/net/dsa/mt7530.c` — MediaTek MT7530/MT7531 DSA.
**IMPORTANT** for MediaTek routers/SBCs (MT7621/MT7622/MT7531), not core
mm/vfs. `CONFIG_NET_DSA_MT7530`.

**Step 7.2**
Record: File is actively maintained; recent 6.12 backports already
include two MDIO-error fixes from the same author.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: Driver-specific: MT7531 switch users (common on MediaTek ARM
routers). Not MT7988/EN7581 setup (`mt7988_setup`).

**Step 8.2 — Trigger**
Record: MDIO/regmap failure or PHY_IAC poll timeout during `dsa_switch`
setup. Uncommon on healthy hardware. Not an unprivileged syscall
trigger. After `96e0f5184af69`, a failed bus read during poll is a
**negative errno**, not silent garbage success — so this caller bug is
easier to hit than before that backport.

**Step 8.3 — Failure mode**
Record: Hardware misconfiguration: PHY core PLL programmed from a
truncated errno instead of a real `CORE_PLL_GROUP4` value, then setup
continues. Switch can probe “successfully” with PHYs/PLL in a bad state.
Not a KASAN crash. Severity: **HIGH** for that hardware (silent wrong
PLL), not a generic kernel panic. Failing probe is the correct outcome.

**Step 8.4 — Risk/benefit**
Record:
- Benefit: medium-high for MT7531 — closes a hole opened/worsened by the
  already-applied poll-error backport; avoids writing errno into PLL.
- Risk: very low (6 lines of `if (ret < 0) return ret`).
- Ratio: favorable.

## Phase 9: Synthesis

**Evidence FOR**
- Real bug: negative errno used as PLL register data, then written back.
- Buggy RMW is in this 6.12 tree; `Fixes:` target `c288575f7810` is
  here.
- Companion to `96e0f5184af69`, already in this tree: that commit made
  failed reads return errno; this caller still treats the result as PHY
  data.
- Small, obviously correct, no new API, applies cleanly.
- Same class as other swallowed-MDIO fixes already accepted here
  (`93d46870c5440`, `96e0f5184af69`).
- Author intended it as a bug fix (`Fixes: c288575f7810` on the list).
- Applied to mainline by Jakub Kicinski (`1ae63b018d3d`).

**Evidence AGAINST**
- Error path only; no syzbot/user crash report.
- Driver-specific, probe-time, not a UAF/panic/CVE.
- Series patch 4/6; Andrew Lunn did not `Reviewed-by` this specific
  patch.
- Patch 3 (PHY_IAC command-write checks) is not in this tree; the
  author’s “now that writes propagate” story is only fully true after
  patch 3.

**Unresolved / UNVERIFIED**
- Full lore thread (403); no individual review replies beyond cover
  letter and patchwork apply notice.
- Whether patch 3 will be evaluated separately for this tree (not
  required for this hunk).

**Stable rules**
1. Obviously correct and tested? **PASS** — trivial return-value checks;
   merged to net by Kicinski.
2. Real bug affecting users? **PASS** — MT7531 setup can program PHY PLL
   from errno on MDIO/poll failure.
3. Important? **PASS** — hardware PLL corruption and silent “success”
   after a failed access; worsened by an already-backported callee fix.
   Not a generic oops, but it is serious for this switch.
4. Small and contained? **PASS** — one function, ~6 net lines.
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **PASS**.

**Exception category:** none (not a device ID/quirk/DT/build/docs
exception). It qualifies on ordinary bug-fix rules.

The missing patch 3 does not make this a NO: poll timeout and failed
`regmap_read_poll_timeout()` already return errno here, and those values
are what get written into `CORE_PLL_GROUP4` today.

### What it solves for this tree
On MT7531 probe, a failed indirect C45 read of `CORE_PLL_GROUP4` is
currently folded into the PLL enable RMW and written back. This tree
already backported the helper change that returns those failures as
errno. Without this caller check, 6.12 can program the PHY core PLL from
that errno and keep going. The fix fails setup instead. It is small,
matches local code, and does not need the rest of the series.

Verification:
- [Phase 1] Parsed subject/tags/body; list version has `Fixes:
  c288575f7810`; candidate message has Link + Golle/Kicinski SOBs
- [Phase 2] Diff: `mt7531_setup()` only; check read and write; `ret`
  already declared
- [Phase 3] `git blame` on 2660–2686: RMW from `c288575f7810`; helpers
  renamed later; poll uses `96e0f5184af69`
- [Phase 3] `git merge-base --is-ancestor c288575f7810 HEAD` → yes
- [Phase 3] `git merge-base --is-ancestor 96e0f5184af69 HEAD` → yes
  (callee error propagation already here)
- [Phase 3] `git log --grep="PHY_IAC command writes"` → patch 3 **not**
  in this tree
- [Phase 3] `git show 96e0f5184af69` confirms
  `regmap_read_poll_timeout()` returns negative on failed reads
- [Phase 4] `b4 dig` on msgid failed; lore 403; used openwall/lkml/cover
  letter; upstream SHA `1ae63b018d3d`; v2 new patch; Andrew reviewed 1–3
  and 6 only
- [Phase 4] UNVERIFIED: full review-reply text; stable@ thread
- [Phase 5] grep: only in-driver `mt7531_ind_c45_phy_read` call is this
  RMW; `.sw_setup = mt7531_setup` for `ID_MT7531`; `mt753x_setup()`
  returns that error
- [Phase 6] `git describe HEAD` → `p-6.12-4-gbf6fcdf761abd`; `make
  kernelversion` → 6.12.111; buggy code at mt7530.c:2665–2672
- [Phase 6] Pre-image matches the candidate hunk; clean apply expected
- [Phase 8] Failure mode: PHY PLL programmed from truncated errno on
  probe MDIO failure; severity HIGH for MT7531, trigger uncommon but
  real after `96e0f5184af69`

**YES**

 drivers/net/dsa/mt7530.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d2dcc2f1522f4..4f391ef797ea3 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2758,14 +2758,20 @@ mt7531_setup(struct dsa_switch *ds)
 	 * phy_[read,write]_mmd_indirect is called, we provide our own
 	 * mt7531_ind_mmd_phy_[read,write] to complete this function.
 	 */
-	val = mt7531_ind_c45_phy_read(priv,
+	ret = mt7531_ind_c45_phy_read(priv,
 				      MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
 				      MDIO_MMD_VEND2, CORE_PLL_GROUP4);
+	if (ret < 0)
+		return ret;
+
+	val = ret;
 	val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
 	val &= ~MT7531_PHY_PLL_OFF;
-	mt7531_ind_c45_phy_write(priv,
-				 MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-				 MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
+	ret = mt7531_ind_c45_phy_write(priv,
+				       MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+				       MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
+	if (ret < 0)
+		return ret;
 
 	/* Disable EEE advertisement on the switch PHYs. */
 	for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] iommu/rockchip: Clear stale page faults before enabling stall
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
@ 2026-10-19 13:44 ` Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-6.6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Sasha Levin
                   ` (47 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:44 UTC (permalink / raw)
  To: patches, stable
  Cc: Jiaxing Hu, Will Deacon, Sasha Levin, joro, heiko, iommu,
	linux-arm-kernel, linux-rockchip, linux-kernel

From: Jiaxing Hu <gahing@gahingwoo.com>

[ Upstream commit b10d5920cafa292ee3cab9c20f813da4fe4f00b8 ]

Boot firmware can leave an IOMMU bank in PAGE_FAULT_ACTIVE before the
driver has configured paging:

  PAGE_FAULT_ACTIVE=1  STALL_ACTIVE=0  IDLE=1

Such a bank ignores CMD_ENABLE_STALL and never reaches STALL_ACTIVE, so
rk_iommu_enable_stall()'s readx_poll_timeout() spins until it times out
(seen on the RK3576 NPU, whose MMUs share this poll across banks).

Rather than special-casing these banks in the stall path, acknowledge the
stale fault with CMD_PAGE_FAULT_DONE before enabling stall, so every bank
starts from a clean state and the normal stall sequence applies to all of
them.  Banks without a pending fault are untouched.

Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local checkout is mainline **7.3-rc4**. The stall-timeout path is in
this tree, and the 13-line firmware leftover workaround is a real IOMMU
enable failure, not a new API.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[iommu/rockchip] [Clear] [acknowledge leftover
PAGE_FAULT_ACTIVE so stall enable does not poll-timeout]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: Jiaxing Hu \<gahing@gahingwoo.com\> (author)
- Signed-off-by: Will Deacon \<will@kernel.org\> (IOMMU maintainer;
  applied the patch)
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, Link:,
  or Cc: stable (absence of Fixes/Cc:stable is expected for this review)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Boot firmware can leave an IOMMU bank in
  `PAGE_FAULT_ACTIVE=1`, `STALL_ACTIVE=0`, `IDLE=1` before the driver
  configures paging.
- **Symptom:** That bank ignores `CMD_ENABLE_STALL` and never reaches
  `STALL_ACTIVE`. `rk_iommu_enable_stall()`’s `readx_poll_timeout()`
  fails. Observed on the RK3576 NPU, whose MMUs share the stall poll
  across banks (`rk_iommu_is_stall_active()` ANDs every bank).
- **Root cause:** Stale firmware page-fault state blocks the stall
  command.
- **Fix:** Issue `CMD_PAGE_FAULT_DONE` on any bank that still has
  `PAGE_FAULT_ACTIVE`, then use the normal stall sequence. Banks without
  a pending fault are untouched.
- **Version info in message:** none beyond RK3576 NPU.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. This is an explicit hardware/firmware leftover
workaround that prevents a stall-enable timeout.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/iommu/rockchip-iommu.c` — **+13 / -0**
- Function: `rk_iommu_enable_stall()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** If stall is not already active and paging is enabled,
  broadcast `CMD_ENABLE_STALL` and poll until every bank reports
  `STALL_ACTIVE` (1 ms timeout, `RK_MMU_POLL_TIMEOUT_US=1000`). One
  stuck bank fails the whole poll.
- **After:** Same path, but first walk each bank; if
  `RK_MMU_STATUS_PAGE_FAULT_ACTIVE` is set, write
  `RK_MMU_CMD_PAGE_FAULT_DONE` to that bank’s command register, then
  enable stall as before.
- Path: initialization / attach / resume (`rk_iommu_enable` →
  `rk_iommu_enable_stall`), and also disable/suspend (return value
  ignored there).

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Hardware workaround / logic correctness]** Firmware leaves
`PAGE_FAULT_ACTIVE`. Hardware ignores `CMD_ENABLE_STALL` in that state.
`rk_iommu_enable()` treats stall timeout as fatal (`if (ret) goto
out_disable_clocks`), so the IOMMU never reaches
`rk_iommu_force_reset()` / paging setup and **device attach fails**. The
fix acks the leftover fault with the same command the IRQ handler
already uses (`RK_MMU_CMD_PAGE_FAULT_DONE`).

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Minimal and readable. Gated on `PAGE_FAULT_ACTIVE`, so idle
banks are unchanged. Uses the existing command encoding. Regression risk
is low; the only flagged concern is not also writing `RK_MMU_INT_CLEAR`
(see Phase 4), which is incomplete-ack, not a new deadlock or API
change.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `rk_iommu_enable_stall()` introduced in **c68a292152d32**
  (`iommu/rockchip: rk3288 iommu driver`, 2014) — contained in
  **v3.19-rc1**.
- Multi-bank `num_mmu` loop: **cd6438c5f8446**, contained in
  **v4.6-rc1**.
- `readx_poll_timeout`: **0416bf6479acef**, contained in **v4.17-rc1**.
- The 13-line ack loop is this commit (**b10d5920cafa2**).

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Not applicable. Buggy interaction is firmware
leftover vs stall path that has existed for years.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Immediate parent on the file: **841363ebb5082** `iommu/rockchip: Take
  all DT clocks` — same author, same RFC series (patch 4/8). Different
  problem (extra clocks so DTE_ADDR writes land). **Not a code
  dependency** of the stall ack.
- No later commits on this file after b10d5920cafa2 in this tree.
- Standalone IOMMU change; Will applied 4/8 and 5/8 without the rest of
  the NPU series.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Jiaxing Hu is not the IOMMU maintainer. In this tree, two
rockchip-iommu commits (clocks + this). Will Deacon applied both.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Diff only needs `rk_iommu_enable_stall`, `num_mmu`,
`RK_MMU_STATUS_PAGE_FAULT_ACTIVE`, `RK_MMU_CMD_PAGE_FAULT_DONE` — all
present long before 7.3. **Can apply standalone.**

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore (via b4):
  https://patch.msgid.link/20260718031146.3368811-6-gahing@gahingwoo.com
- Series: **[RFC PATCH v2 0/8] accel/rocket: RK3576 NPU (RKNN)
  enablement**
- This patch is **v2 5/8**. v1 had two “skip orphaned-fault banks”
  patches; v2 replaced them with this fault-ack after Chaoyi Chen asked
  whether clearing the fault avoids skipping banks.
- Will Deacon (2026-07-26): “Applied driver changes to iommu (rockchip)”
  for 4/8 and 5/8. No NAK on this patch.
- Cover letter: NPU bring-up is still incomplete (“full inference is not
  correct yet”). This IOMMU fix was still taken on its own.
- v3 of the wider series was not out when Will applied this; applied
  version is the latest for this hunk.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Recipients included Will Deacon, Joerg Roedel, Robin Murphy,
Heiko Stuebner, iommu@lists.linux.dev, linux-rockchip. No human
Reviewed-by on 5/8 in the thread. Will applied it. Sashiko bot
(automated) commented.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Author hit it on a Radxa ROCK 4D while
bringing up the RK3576 NPU IOMMUs. Cover letter lists “clearing a stale
firmware page fault” as required for those IOMMUs to come up.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: RFC 8-patch NPU enablement. Only the two IOMMU driver patches
were merged. NPU DT/driver patches are **not** in this tree (no NPU
IOMMU nodes in `rk3576.dtsi`). This stall patch does not depend on them.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search returned HTTP 403. **UNVERIFIED**
whether stable@ discussed this. No in-tree grep hit except this commit.

Sashiko bot concern (verified from mbox): `CMD_PAGE_FAULT_DONE` without
`RK_MMU_INT_CLEAR` might leave a raw IRQ pending. On `rockchip,disable-
mmu-reset` instances (in-tree: px30, rk3288, rk3368, rk3399, rk356x,
rk3576 vdec), `rk_iommu_force_reset()` is skipped, then
`RK_MMU_INT_MASK` is programmed in `rk_iommu_enable()`. A leftover raw
bit could fire a page-fault IRQ. The existing IRQ handler already logs,
optionally `report_iommu_fault()`, zaps cache, issues `PAGE_FAULT_DONE`,
and clears INT_STATUS. That is a possible spurious IRQ/log, not a
verified panic. No follow-up commit addressed it; Will still applied the
patch.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `rk_iommu_enable_stall()` (modified). Helpers used:
`rk_iommu_read`, `rk_iommu_is_stall_active`,
`rk_iommu_is_paging_enabled`, `rk_iommu_command`.

**Step 5.2: TRACE CALLERS**
Record:
- `rk_iommu_disable()` line 928 — detach / runtime suspend. Return
  ignored.
- `rk_iommu_enable()` line 950 — attach / runtime resume. **Failure
  aborts enable.**
- `rk_iommu_enable()` called from `rk_iommu_attach_device()` (line 1064)
  and `rk_iommu_resume()` (line 1349).

**Step 5.3: TRACE CALLEES**
Record: MMIO status/command. No allocation, no new locks.
`writel(RK_MMU_CMD_PAGE_FAULT_DONE, base + RK_MMU_COMMAND)` matches
`rk_iommu_base_command()`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace/DMA attach or runtime PM resume →
`rk_iommu_attach_device` / `rk_iommu_resume` → `rk_iommu_enable` →
`rk_iommu_enable_stall`. Reachable on Rockchip SoCs with
`CONFIG_ROCKCHIP_IOMMU`. Trigger is firmware leftover + paging already
enabled. Not a syscall fuzz path; it is device bring-up.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: IRQ path already does `RK_MMU_CMD_PAGE_FAULT_DONE` (line 642)
plus `RK_MMU_INT_CLEAR`. No other stall-path fault ack. In-tree RK3576
`vdec_mmu` is two-bank (`reg` two regions), so the AND-poll issue is not
NPU-only in principle.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Local tree: `git describe HEAD` =
**v7.3-rc4-27-gf0100363d8c37**, `make kernelversion` = **7.3.0-rc4**.
`rk_iommu_enable_stall()` is present; this commit is already an ancestor
of HEAD (`git merge-base --is-ancestor b10d5920cafa2 HEAD` succeeded).
Landed via `iommu-updates-v7.3` (not in v7.2). Stall path itself dates
to v3.19.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Hunk is a contiguous insert after the paging-enabled check.
Expected apply: **clean** on trees that have the 2016 multi-bank
`num_mmu` loop (v4.6+). No conflicting later edits on this function in
this checkout.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This is the only “stale page fault” commit. No alternate fix.
Sibling clocks change is independent.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/iommu/rockchip-iommu.c** — Rockchip IOMMU.
Criticality: **IMPORTANT** (platform IOMMU for multimedia/NPU DMA; not
core mm/VFS, but attach failure takes down the consumer device).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (2014), still receiving Rockchip bring-up fixes.
Joerg’s v7.3 pull: “Rework Rockchip state handling and fix clock, probe
and stale-fault handling.”

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **driver-specific / platform-specific** —
`CONFIG_ROCKCHIP_IOMMU` on Rockchip. Practical trigger reported on
RK3576 NPU MMUs (those DT nodes are **not** in this tree). Any multi-
bank instance whose firmware leaves `PAGE_FAULT_ACTIVE` can hit the same
poll (e.g. in-tree RK3576 `vdec_mmu` has two banks).

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Boot firmware leftover fault, then first stall enable while
paging is still enabled. Timing: probe/attach or resume, not a hot path.
Unprivileged users do not trigger it directly; it is firmware × driver
init. No public reproducer beyond the author’s ROCK 4D bring-up.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **IOMMU enable fails after a 1 ms poll**
(`RK_MMU_POLL_TIMEOUT_US=1000`). Attach returns error; the DMA device
does not get a working IOMMU. **Not** a panic, hang, UAF, or corruption.
Severity: **HIGH** for the affected device (non-functional), **MEDIUM**
system-wide (1 ms timeout + error, rest of the machine continues).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Hardware/firmware workaround so stall enable succeeds;
  IOMMU attach can proceed. High for RK3576 NPU users; modest for other
  Rockchip boards unless firmware leaves the same bit.
- **Risk:** 13 lines, status-gated. Theoretical spurious IRQ if
  INT_STATUS is not cleared on `disable-mmu-reset` devices. No new
  locks/APIs.
- **Ratio:** Benefit outweighs risk. Same class as other hardware
  leftover/quirk fixes.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, explained failure: stall poll times out, `rk_iommu_enable()`
  aborts, device attach fails.
- Small (+13), contained, status-gated.
- Same command the IRQ handler already uses.
- Will Deacon applied it independently of the unfinished NPU RFC.
- v7.3 IOMMU pull listed stale-fault handling as a fix.
- Driver and stall path exist in this tree since v3.19 / v4.6.
- Hardware/firmware workaround (stable exception category).
- No new APIs or features.

AGAINST:
- Originated in an RFC series to enable RK3576 NPU; NPU IOMMU DT is
  still not in this tree.
- Observed on that NPU, not reported on long-shipped VOP/VDEC.
- Not crash/security/corruption; 1 ms timeout then enable failure.
- Sashiko noted missing `INT_CLEAR`; unaddressed.
- No Fixes:/Cc:stable (not a negative by itself).

UNRESOLVED:
- lore.kernel.org/stable search HTTP 403.
- Whether in-tree vdec/vop firmware also leaves `PAGE_FAULT_ACTIVE`
  (author only cited NPU).
- Whether a leftover INT_STATUS after `PAGE_FAULT_DONE` actually fires
  on `disable-mmu-reset` hardware.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — logic matches the described
   hardware state; author tested on ROCK 4D; IOMMU maintainer applied
   it.
2. Fixes a real bug that affects users? **PASS** — stall timeout
   prevents IOMMU enable/attach.
3. Important issue? **PASS** — device IOMMU never comes up (not a panic,
   but hardware non-functional). Severity HIGH for that device.
4. Small and contained? **PASS** — 13 lines, one function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — stall path and symbols are
   here; hunk is a clean insert.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: **Hardware quirk/workaround** — firmware leftover
`PAGE_FAULT_ACTIVE` so stall commands work. Not a new driver, not a new
userspace API.

**Step 9.4: MAKE YOUR DECISION**

This tree is 7.3-rc4; the stall path is old and the bug is a firmware
leftover vs that path, not a 7.3-only feature. The patch is a small,
maintainer-acked workaround that stops IOMMU attach from failing. Origin
in an unfinished NPU RFC does not make it a new API; Will merged it as a
standalone IOMMU fix. Missing `INT_CLEAR` is a residual IRQ-ack concern,
not a reason to drop a stall-timeout fix that already uses the
documented fault-done command.

Verification:
- [Phase 1] Parsed tags: only author SOB + Will Deacon SOB; no
  Fixes/Reported-by/Cc:stable
- [Phase 1] Body: PAGE_FAULT_ACTIVE leftover → ENABLE_STALL ignored →
  poll timeout on RK3576 NPU multi-bank poll
- [Phase 2] Diff: +13 in `rk_iommu_enable_stall()`; loop acks
  `PAGE_FAULT_ACTIVE` with `CMD_PAGE_FAULT_DONE`
- [Phase 2] `rk_iommu_enable()` returns on stall timeout before
  `force_reset` (line 950-952) — attach fails
- [Phase 3] git blame: function from c68a292152d32 (v3.19); poll from
  0416bf6479acef (v4.17); multi-mmu cd6438c5f8446 (v4.6)
- [Phase 3] git merge-base --is-ancestor b10d5920cafa2 HEAD: yes; not in
  v7.2; in v7.3-rc1
- [Phase 3] Sibling 841363ebb5082 is clocks-only; not required for this
  hunk
- [Phase 4] b4 dig -c b10d5920cafa2:
  https://patch.msgid.link/20260718031146.3368811-6-gahing@gahingwoo.com
- [Phase 4] b4 dig -a: RFC v1 (skip banks) → v2 (this ack); Will applied
  v2 4/8 and 5/8
- [Phase 4] b4 dig -w: iommu maintainers + rockchip list on CC
- [Phase 4] mbox: Will “Applied driver changes to iommu (rockchip)”;
  Sashiko INT_CLEAR warning; no human NAK
- [Phase 4] lore.kernel.org WebFetch/curl: HTTP 403 — stable-list
  discussion UNVERIFIED
- [Phase 5] Callers: disable (unchecked) and enable (fatal); enable from
  attach_device and resume
- [Phase 5] IRQ handler already issues PAGE_FAULT_DONE at line 642
- [Phase 6] git describe HEAD: v7.3-rc4-27-gf0100363d8c37; Makefile
  7.3.0-rc4; file present
- [Phase 6] No NPU IOMMU nodes in
  arch/arm64/boot/dts/rockchip/rk3576.dtsi; vdec_mmu is two-bank +
  disable-mmu-reset
- [Phase 7] iommu-updates-v7.3 merge text: “fix clock, probe and stale-
  fault handling”
- [Phase 8] Failure: 1 ms poll then IOMMU enable/attach failure; not
  oops/UAF
- UNVERIFIED: whether firmware leaves this bit on in-tree vdec/vop;
  whether INT_STATUS spurious IRQ reproduces; stable@ thread

The fix is small, surgical, and meets the stable criteria as a hardware
leftover workaround in a long-lived driver.

**YES**

 drivers/iommu/rockchip-iommu.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 309ba78e27d4f..982ea9cafee1b 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -422,6 +422,19 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
 	if (!rk_iommu_is_paging_enabled(iommu))
 		return 0;
 
+	/*
+	 * Boot firmware can leave a bank in PAGE_FAULT_ACTIVE with no handler
+	 * (PAGE_FAULT_ACTIVE & !STALL_ACTIVE & IDLE).  Such a bank ignores
+	 * CMD_ENABLE_STALL and never reaches STALL_ACTIVE, timing out the poll
+	 * below.  Acknowledge any stale fault first so every bank starts clean.
+	 */
+	for (i = 0; i < iommu->num_mmu; i++) {
+		if (rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
+		    RK_MMU_STATUS_PAGE_FAULT_ACTIVE)
+			writel(RK_MMU_CMD_PAGE_FAULT_DONE,
+			       iommu->bases[i] + RK_MMU_COMMAND);
+	}
+
 	rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
 
 	ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] iommu/rockchip: Clear stale page faults before enabling stall Sasha Levin
@ 2026-10-19 13:44 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: clocking-wizard: fix clock difference detection Sasha Levin
                   ` (46 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:44 UTC (permalink / raw)
  To: patches, stable
  Cc: Mukesh Ojha, Konrad Dybcio, Will Deacon, Sasha Levin, robin.clark,
	joro, iommu, linux-arm-msm, linux-arm-kernel, linux-kernel

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit cb776a03a53429aa59e25a8cbc3d1a48bd11afdb ]

qcom_iommu_ctx_probe() reads and writes the CB_FSR register to clear any
stale IRQ left by the bootloader. This happens during
devm_of_platform_populate() which is called from the parent device's
probe before any pm_runtime_get(). The parent's clocks (iface, bus, tbu)
are therefore not guaranteed to be on, making the register access
unreliable on rebind or after a suspend cycle.

Use pm_runtime_resume_and_get() on the parent device to ensure clocks
are enabled before the register access, and release the reference
immediately after.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[iommu/qcom] [Enable] clocks before hardware access in
`qcom_iommu_ctx_probe()`**
“Enable” here is a missing power/clock step before MMIO, not a new
feature.

**Step 1.2: Tags**
Record:
- `Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>`
- `Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>` (author)
- `Signed-off-by: Will Deacon <will@kernel.org>` (IOMMU/SMMU maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Acked-by:`, `Link:`, or
  `Cc: stable` (absence is expected)

**Step 1.3: Body**
Record:
- **Bug:** `qcom_iommu_ctx_probe()` reads/writes `CB_FSR` to clear a
  stale bootloader IRQ during `devm_of_platform_populate()`, which runs
  from the parent probe **before** any `pm_runtime_get()`. Parent clocks
  (`iface`, `bus`, `tbu`) may be off.
- **Symptom:** Register access is **unreliable on rebind or after a
  suspend cycle**.
- **Root cause:** Child MMIO without a runtime-PM resume of the parent
  that actually enables the clocks.
- **Fix:** `pm_runtime_resume_and_get(dev->parent)` around the FSR
  access, then `pm_runtime_put_sync()`.
- No stack trace, syzbot, or version range in the message.

**Step 1.4: Hidden bug fix?**
Record: Yes. The subject sounds like enablement, but this is a
correctness fix for MMIO with clocks gated.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/iommu/arm/arm-smmu/qcom_iommu.c` (+6 / −1)
- Function: `qcom_iommu_ctx_probe()`
- Scope: single-file, surgical

**Step 2.2: Flow change**
Record: **Before:** if the context is not secure, immediately
`readl`/`writel` `ARM_SMMU_CB_FSR`. **After:** same access, but only
after a successful parent `pm_runtime_resume_and_get()`, then
`pm_runtime_put_sync()`. Resume failure fails probe. This is the child
probe path invoked from parent `devm_of_platform_populate()`.

**Step 2.3: Bug mechanism**
Record: **Hardware access / PM correctness.** Clocks are enabled only in
`qcom_iommu_resume()` via `clk_bulk_prepare_enable()`. Parent probe
order is `devm_pm_runtime_enable()` then `devm_of_platform_populate()` —
RPM enable does not turn clocks on. The parent already wraps its own
`SMMU_INTR_SEL_NS` write with resume/get; the child FSR access did not.

**Step 2.4: Fix quality**
Record: Obviously correct and matches the parent’s existing pattern.
`pm_runtime_resume_and_get()` drops the usage count on failure, so there
is no extra `put` needed. Regression risk is low: resume runs after
clocks/drvdata are set; multiple context banks each get/put
independently. No API or data-structure change.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: FSR-clear comment and access come from **`0ae349a0f33fb0`
(“iommu/qcom: Add qcom_iommu”, Rob Clark, 2017-08-09)**, first in
**v4.14-rc1**. Secure-ctx skip is from `e30c960d3f44b7` (2023). The bug
is old, not recent.

**Step 3.2: Fixes: tag**
Record: None. The introducing commit is `0ae349a0f33fb0`, present in
this tree (`git merge-base --is-ancestor` succeeded).

**Step 3.3: Related file history**
Record: Same-day series by Mukesh Ojha (v2 6/6 “Misc Fixes”):
1. `1f33b8208a197` inverted fault report
2. `bf69e515b1802` `devm_pm_runtime_enable()` (cleanup)
3. `e910315ae08a2` check RPM return on parent `SMMU_INTR_SEL_NS` write
4. `3c748a5554f96` pgtbl_ops leak
5. `a05b67cd45ad0` pgtbl_ops publish vs mutex
6. **this commit** `cb776a03a5342`

This patch does not need 2–5. It only uses
`pm_runtime_resume_and_get()`, present since `dd8088d5a8969`.

**Step 3.4: Author**
Record: Qualcomm engineer; series reviewed by Konrad Dybcio (Qualcomm)
and applied by Will Deacon. Not a drive-by.

**Step 3.5: Dependencies**
Record: Standalone. Applies to the pre-commit `ctx_probe` body in this
tree. No new helpers.

---

## Phase 4: Mailing list

**Step 4.1: Original discussion**
Record:
- Lore/msgid: https://patch.msgid.link/20260717144608.3216274-7-
  mukesh.ojha@oss.qualcomm.com
- v1: `[PATCH 7/8]` 2026-06-23, same diff
- v2: `[PATCH v2 6/6]` 2026-07-17 (dropped unrelated 6/8 and 8/8)
- Cover: “Series to address fixes in legacy qcom_iommu driver”
- Konrad Reviewed-by on v1 7/8 with no requested changes; v2 unchanged
- Will: “Applied to iommu (arm/smmu/updates)”
- No NAK, no `Cc: stable` request

**Step 4.2: Recipients (`b4 dig -w`)**
Record: Will Deacon, Joerg Roedel, Robin Murphy, Rob Clark, Konrad
Dybcio, iommu@lists.linux.dev, linux-arm-msm, linux-arm-kernel.

**Step 4.3: Bug report**
Record: No external bugzilla/syzbot. Qualcomm-authored; trigger
described as rebind / post-suspend.

**Step 4.4: Series**
Record: Independent of the other five patches. Same pattern as patch 3/6
on the parent.

**Step 4.5: Stable list**
Record: **UNVERIFIED** — lore.kernel.org returned 403; no stable thread
in the saved mbox.

---

## Phase 5: Code semantics

**Step 5.1: Functions**
Record: `qcom_iommu_ctx_probe()` only.

**Step 5.2: Callers**
Record: Sole caller is `.probe = qcom_iommu_ctx_probe` on
`qcom_iommu_ctx_driver`. Invoked from `qcom_iommu_device_probe()` →
`devm_of_platform_populate()`. Device-init / bind path, not a syscall
hot path.

**Step 5.3: Callees**
Record: `pm_runtime_resume_and_get(parent)` → `qcom_iommu_resume()` →
`clk_bulk_prepare_enable()` (and optional `qcom_scm_restore_sec_cfg`);
then `iommu_readl`/`iommu_writel` `ARM_SMMU_CB_FSR`; then
`pm_runtime_put_sync()`.

**Step 5.4: Reachability**
Record: Yes, on every non-secure context probe for `qcom,msm-iommu-v1` /
`v2`. DT users include MSM8916/8917/8937/8939/8953/8976. First boot
often still has bootloader clocks; **rebind, deferred probe after
`clk_disable_unused`, and probe after suspend/remove** can have clocks
off. Unprivileged users do not trigger this directly; driver
bind/suspend does.

**Step 5.5: Similar patterns**
Record: Parent already does resume/get around `SMMU_INTR_SEL_NS`
(`e910315ae08a2`). This is the matching child-side hole.

---

## Phase 6: This checkout

**Step 6.1: Buggy code in this tree?**
Record: **Yes.** Tree is **v7.3-rc4** (`VERSION=7 PATCHLEVEL=3
SUBLEVEL=0 EXTRAVERSION=-rc4`, `git describe`:
`v7.3-rc4-27-gf0100363d8c37`). Driver and FSR-clear exist since v4.14.
Candidate `cb776a03a5342` is already an ancestor of HEAD (merged via
`iommu-updates-v7.3`, in v7.3-rc1). Pre-commit code still has the
unguarded FSR access.

**Step 6.2: Backport difficulty**
Record: Clean apply on this file’s `ctx_probe`. Needs
`linux/pm_runtime.h` (already included) and
`pm_runtime_resume_and_get()` (in this tree).

**Step 6.3: Related fixes already here**
Record: The candidate itself is already in this 7.3-rc4 tree. No
alternate FSR-clock fix besides this commit.

---

## Phase 7: Subsystem

**Step 7.1**
Record: **iommu / Qualcomm legacy SMMU** (`drivers/iommu/arm/arm-
smmu/qcom_iommu.c`). **IMPORTANT** for those SoCs (DMA/IOMMU), not core-
mm/VFS. `CONFIG_QCOM_IOMMU`, `depends on ARCH_QCOM`.

**Step 7.2**
Record: Mature “legacy qcom_iommu” driver; low churn except this 2026
fix series.

---

## Phase 8: Impact and risk

**Step 8.1: Who**
Record: Qualcomm MSM IOMMU v1/v2 platforms (older/mid-range SoCs still
in LTS images), not all machines.

**Step 8.2: Trigger**
Record: Child probe with parent clocks off: driver rebind, probe after
`pm_runtime_force_suspend` on remove, deferred probe after unused clocks
are gated. Not every boot. Not a userspace exploit path.

**Step 8.3: Failure mode**
Record: MMIO to a clock-gated SMMU context bank. On these platforms that
is typically a **bus timeout / NOC hang / SError**, or a failed FSR
clear so a bootloader IRQ fires as soon as `devm_request_irq()` runs.
Severity: **HIGH** (probe hang/abort), not a confirmed UAF/CVE.

**Step 8.4: Risk-benefit**
Record: **Benefit: medium-high** for affected hardware (prevents bad
MMIO during probe). **Risk: low** (6 lines, existing RPM API, same
pattern as parent). Ratio favors backport.

---

## Phase 9: Synthesis

**For:**
- Real bug: FSR MMIO before parent clocks are enabled; present since
  v4.14.
- Can hang or fail IRQ clear on rebind / post-suspend / deferred probe.
- 6-line, obviously correct; reviewed by Konrad, applied by Will.
- Standalone; no new API.
- Same RPM wrap the parent already uses for `SMMU_INTR_SEL_NS`.
- Driver still used (MSM8916-class DT).

**Against:**
- No `Reported-by` / syzbot / crash log.
- Message says “unreliable”, not “panic”.
- Not a universal hot path.
- Lore stable search could not be fetched (403).

**Unresolved:** Exact production crash vs silent bad read on every SoC
variant — not verified beyond Qualcomm’s description.

**Stable rules:**
1. Obviously correct and tested? **PASS** (review + maintainer apply;
   pattern already in-tree)
2. Real user-facing bug? **PASS** (clock-gated MMIO on probe/rebind)
3. Important (crash/hang/corruption)? **PASS** (HIGH: interconnect hang
   / SError / stale IOMMU IRQ)
4. Small and contained? **PASS** (6 lines, one function)
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS** (driver and RPM API present)

**Exception category:** none (not an ID/quirk/DT/build/doc add). It is a
normal small driver bugfix.

This tree is v7.3-rc4 and already contains `cb776a03a5342`; that is the
upstream commit, not a reason to reject on merit. The buggy FSR-without-
clocks path is in this driver and has been since v4.14. The fix is
small, local, and prevents a real probe-time hardware access failure on
Qualcomm IOMMU platforms.

### What it solves for stable users
Without the RPM get, context-bank probe can touch `CB_FSR` while
iface/bus/tbu clocks are off. That is the same class of bug the parent
already fixed for `SMMU_INTR_SEL_NS`. On rebind or after suspend/remove
(and on deferred probe after unused clocks are disabled), that access is
a hang or a missed IRQ clear, then a surprise fault IRQ.

### Risk vs benefit
Benefit is avoiding probe-time MMIO with clocks gated on still-shipping
MSM IOMMU v1/v2 boards. Risk is a few lines of standard
`resume_and_get`/`put_sync` around an existing register poke. No locking
or API change.

### Concerns
No public reproducer. Independent of the rest of the “Misc Fixes”
series. `pm_runtime_resume_and_get()` is already in this tree.

Verification:
- [Phase 1] Tags: Reviewed-by Konrad Dybcio; SOBs Mukesh Ojha, Will
  Deacon; no Fixes/Reported-by/Cc-stable
- [Phase 2] Diff: +6/−1 in `qcom_iommu_ctx_probe()` wrapping FSR MMIO
  with parent RPM get/put
- [Phase 3] Blame: FSR clear from `0ae349a0f33fb0` (v4.14-rc1); ancestor
  of HEAD
- [Phase 3] Series mates `bf69e515b1802` / `e910315ae08a2` are not
  prerequisites
- [Phase 3] `pm_runtime_resume_and_get` from `dd8088d5a8969`; ancestor
  of HEAD
- [Phase 4] `b4 dig -c cb776a03a5342`: https://patch.msgid.link/20260717
  144608.3216274-7-mukesh.ojha@oss.qualcomm.com
- [Phase 4] `b4 dig -a`: v1 7/8 identical diff; Konrad R-b; v2 applied
  by Will; no NAK
- [Phase 4] Cover letter: “fixes in legacy qcom_iommu driver”
- [Phase 4] UNVERIFIED: lore.kernel.org/stable HTTP 403
- [Phase 5] Only caller: platform `.probe` via
  `devm_of_platform_populate()` from parent probe
- [Phase 5] Resume path enables clocks in `qcom_iommu_resume()` →
  `clk_bulk_prepare_enable()`
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` = 7.3.0-rc4
- [Phase 6] `git merge-base --is-ancestor cb776a03a5342 HEAD` succeeded
  (fix already in this 7.3 tree)
- [Phase 6] Pre-image of the commit still has unguarded
  `iommu_writel`/`iommu_readl` on `ARM_SMMU_CB_FSR`
- [Phase 8] Failure mode: clock-gated SMMU MMIO → hang/SError or stale
  fault IRQ; severity HIGH
- UNVERIFIED: no captured oops from a reporter

**YES**

 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index fbe4bd3ec0c42..792585321bd11 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -704,8 +704,13 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
 	/* clear IRQs before registering fault handler, just in case the
 	 * boot-loader left us a surprise:
 	 */
-	if (!ctx->secured_ctx)
+	if (!ctx->secured_ctx) {
+		ret = pm_runtime_resume_and_get(dev->parent);
+		if (ret)
+			return ret;
 		iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
+		pm_runtime_put_sync(dev->parent);
+	}
 
 	ret = devm_request_irq(dev, irq,
 			       qcom_iommu_fault,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] clk: clocking-wizard: fix clock difference detection
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] iommu/rockchip: Clear stale page faults before enabling stall Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-6.6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (45 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Colin Foster, Shubhrajyoti Datta, Brian Masney, Sasha Levin,
	sboyd, bmasney+clk, jbrunet+clk, michal.simek, anatoliy.klymenko,
	linux-clk, linux-arm-kernel, linux-kernel

From: Colin Foster <colin.foster@in-advantage.com>

[ Upstream commit 006ba909c240b832c876b7aed29c6beec9d1f5e5 ]

Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
change is a one-line restoration of `abs()` in Xilinx Clocking Wizard
divisor search: unsigned wrap made frequencies below the request look
like ~2^64 error, so they were ignored.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[clk / xilinx clocking-wizard] [fix] [clock difference
detection]** — restore correct closest-match comparison when computed
frequency is below the requested rate.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record (from `git show 006ba909c240b`):
- Reviewed-by: Shubhrajyoti Datta \<shubhrajyoti.datta@amd.com\>
  (Xilinx/AMD clocking-wizard author)
- Reviewed-by: Brian Masney \<bmasney@redhat.com\> (clk co-maintainer;
  also committer)
- Signed-off-by: Colin Foster \<colin.foster@in-advantage.com\> (author)
- Signed-off-by: Brian Masney \<bmasney@redhat.com\>
- No Fixes:, Cc: stable, Reported-by, Tested-by, Link, or Acked-by in
  the **merged** commit
- Absence of Fixes/Cc:stable is expected for this review pipeline and is
  not a negative

The merged git message has **no body**. The mailing-list submission did
(see Phase 4).

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Merged commit: subject + tags only.

Mailing-list body (from b4 mbox, not in git): unsigned “rollover” in
`diff = freq - rate`. Frequencies below the request produced diffs like
`18446744073708237796` (2^64 wrap) and were not considered. Author
included before/after traces at 133312500 Hz / parent 99999000 Hz.

Cover letter: this is patch **1/3** of “clock-wizard fixups”. The series
also optimizes exact-match search (2/3) and removes the 20 kHz
`WZRD_MIN_ERR` cutoff (3/3). Cover letter: the 20 kHz check made **out-
of-tree consumers fail `clk_set_rate`**; patch 1 is the separate
difference-calculation bug.

Record: **[Bug: unsigned underflow when freq \< rate] [Symptom: wrong
closest match and/or -EBUSY from set_rate/determine_rate] [Root cause:
abs() dropped in a later refactor] [No version tags in the commit
itself]**

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject says “fix”. It is a real comparison bug,
not cleanup.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/clk/xilinx/clk-xlnx-clock-wizard.c` — **1 insertion, 1
  deletion**
- Function: `clk_wzrd_get_divisors()`
- Scope: **single-file surgical one-liner**
- Versal sibling `clk_wzrd_get_divisors_ver()` is **not** changed
  (already uses `abs()`)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Before: `diff = freq - rate` with `freq`/`diff` as `u64`. If `freq <
rate`, subtraction wraps. `best_diff` starts at `-1ULL`. Wrapped diffs
lose to any over-rate candidate; if every candidate is under-rate,
`best_diff` stays huge and `return best_diff < WZRD_MIN_ERR ? 0 :
-EBUSY` returns **-EBUSY** (20 kHz threshold still present in the parent
of this commit).

After: `diff = abs(freq - rate)` so both sides of the target compete;
closest match wins.

Path: clock **determine_rate / set_rate** for non-Versal Clocking Wizard
(dynamic reconfig / fractional M and O).

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Logic / correctness + unsigned wrap]** — `abs()` was dropped
when 7681f64e6404ed switched the search to `u64` and `best_diff`.
Original v6.4 code in 595c88cda65d30 used `diff = abs(freq - rate)`.
This restores that.

Kernel `abs()` on the `u64` difference works here: wrap of a small Hz
delta becomes a negative `signed long long`, then `abs()` yields the
true delta. Clock Hz values are far below 2^63. Same pattern as the
Versal function.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: **Obviously correct, minimal, matches the pre-regression and
Versal code.** Regression risk is low: set_rate may now succeed with a
slightly-below rate instead of failing or picking a worse over-rate.
That is the intended fix. `abs_diff()` would be cleaner with matching
types, but reviewers accepted `abs()`, and it matches the sibling.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Current `abs()` line: **006ba909c240b** (this commit), 2026-06-29
- Surrounding fractional search: **7681f64e6404ed** (“calculate dividers
  fractional parts”), 2025-01-06, **v6.13-rc1**
- Function introduced: **595c88cda65d30** (v6.4-rc1) **with abs()
  already**
- 7681f64e **removed** `abs()` and used `diff = freq - rate`

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No Fixes: tag.** Buggy commit is **7681f64e6404ed**, ancestor
of HEAD (`git merge-base --is-ancestor`).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: 3-patch series, same author/date:
1. **006ba909c240b** — this fix (1/3)
2. **9329714414d1f** — early-out on exact match (optimization, 2/3)
3. **54ed94b709e03** — drop 20 kHz `WZRD_MIN_ERR` (3/3)

This patch is **standalone**. It does not need 2/3 or 3/3. With the 20
kHz check still present, `abs()` is what lets a close **under**-rate
pass `best_diff < 20000` instead of wrapping to -EBUSY.

Related: **4adf593c6fc5a** overflow fix in the same file (`Cc: stable`,
Fixes: 7681f64e). **e0a94c6bb5b48** (v6.18-rc1) already used `abs()` on
the Versal path.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Colin Foster is not the historical driver author (that is
Shubhrajyoti Datta / AMD). Datta reviewed this. Foster’s three clocking-
wizard commits are this series.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Needs `clk_wzrd_get_divisors()` with `u64` `freq`/`diff` as in
7681f64e. That is in this tree. **Applies standalone.** `abs()` is in
`include/linux/math.h`.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 006ba909c240b` →
  https://patch.msgid.link/20260629205346.3228886-2-colin.foster@in-
  advantage.com
- `b4 dig -a`: only **PATCH v2 1/3** (v2: rebase + signoffs). v1 not in
  the matched thread.
- Saved mbox: cover + 3 patches, **no reply NAKs** in that thread
- WebFetch/curl to lore.kernel.org: **403** — discussion beyond the mbox
  is UNVERIFIED

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
`b4 dig -w` To/Cc: linux-clk, linux-arm-kernel, linux-kernel,
Shubhrajyoti Datta, Michal Simek, Brian Masney, Stephen Boyd, Michael
Turquette.

Record: **Clk lists + clk maintainers CC’d; Reviewed-by from AMD driver
author and Brian Masney.**

**Step 4.3: SEARCH FOR THE BUG REPORT**
No syzbot/bugzilla. Evidence is the author’s traces (unsigned wrap
~2^64) and cover-letter `clk_set_rate` failures.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: **v2 0/3 “clock-wizard fixups”.** 1/3 is this logic fix; 2/3
optimization; 3/3 policy (allow error ≥ 20 kHz). 1/3 does not depend on
the others.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search returned **403**. UNVERIFIED
whether stable@ discussed it.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

semcode MCP: **not available**. Used grep + callers in this file.

**Step 5.1: KEY FUNCTIONS**
Record: **`clk_wzrd_get_divisors()`** only.

**Step 5.2: TRACE CALLERS**
- `clk_wzrd_dynamic_all_nolock()` → `clk_wzrd_dynamic_all()` →
  `clk_wzrd_clk_div_all_ops.set_rate`
- `clk_wzrd_determine_rate_all()` →
  `clk_wzrd_clk_div_all_ops.determine_rate`

Versal ops use `clk_wzrd_get_divisors_ver()`, already using `abs()`.

**Step 5.3: TRACE CALLEES**
`div64_u64`, `DIV_ROUND_CLOSEST_ULL`, writes into
`divider->{m,m_frac,d,o,o_frac}`. No allocation/locking inside the
search.

**Step 5.4: FOLLOW THE CALL CHAIN**
Probe registers outputs with `clk_wzrd_clk_div_all_ops` for non-Versal
dynamic-reconfig Clocking Wizard (`xlnx,clocking-wizard`, v5.2, v6.0).
`clk_set_rate` / `clk_round_rate` from consumers (display pixel clocks
were the reason fractional M/O were added).

Record: **Reachable from userspace/driver clock APIs on that IP. Not a
syscall bug by itself; standard clk consumer path.**

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Versal `clk_wzrd_get_divisors_ver()` already has `diff = abs(freq -
rate)` (e0a94c6bb5b48). Original non-Versal code had abs() until
7681f64e dropped it.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- Tree: **v7.3-rc4** / Makefile **7.3.0-rc4**
- File and `clk_wzrd_get_divisors()` **exist**
- HEAD already has `diff = abs(freq - rate)` because **006ba909c240b is
  an ancestor** (`git merge-base --is-ancestor` → yes). `git describe
  --contains` → **v7.3-rc1**
- Bug introduced **v6.13** (7681f64e), long before 7.3
- Pre-fix code (parent of 006ba909) still had `diff = freq - rate` and
  `WZRD_MIN_ERR` 20000

This is **not** “bug added after this branch.” The driver and the
regression are part of this 7.3 line.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
On **this** checkout the one-liner is already applied; a second apply
would not change anything. Against the pre-fix function the hunk is
context-identical (one line). Expected difficulty: **clean apply** on a
tree that still has `diff = freq - rate`.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This exact fix **is** in HEAD, plus 2/3 and 3/3. That is the
mainline landing, not a separate in-tree workaround. No competing
alternate fix.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **`drivers/clk/xilinx/`** — Xilinx Clocking Wizard
(`CONFIG_COMMON_CLK_XLNX_CLKWZRD`, `depends on OF`). **PERIPHERAL /
platform-specific** (FPGA/SoC), but it is the clock provider for that
IP, including pixel-clock accuracy.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Active through 2025–2026 (fractional dividers, Versal, overflow
fix, this series). Mature in-tree driver, not staging.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific / config-specific** —
`COMMON_CLK_XLNX_CLKWZRD`, non-Versal Clocking Wizard with dynamic
reconfig / fractional search. Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: **`clk_set_rate` / determine_rate** when the closest achievable
frequency is below the request, or when under-rate candidates must
compete with worse over-rate ones. Common for arbitrary pixel/device
rates. Unprivileged userspace can hit it if a consumer exposes clock
control; typically a device driver at probe/modeset.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **Wrong clock chosen or `clk_wzrd_get_divisors()` returns
-EBUSY** so rate set fails. Not oops/UAF/deadlock. Author showed
wraparound and `clk_set_rate` failure in the series. **Severity:
MEDIUM** (functional breakage on that hardware, including display
clocks).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: medium** for Clocking Wizard users (correct closest
rate; fewer false -EBUSY). **Risk: very low** (1 line, same as
old/Versal code). **Ratio: favorable.**

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real unsigned wrap; traces show ~2^64 diffs for freq \< rate
- Regression: 595c88cd used `abs()`; 7681f64e dropped it in v6.13
- Restores closest-match; can avoid -EBUSY under the 20 kHz check
- 1 line, obviously correct
- Reviewed by AMD driver author and clk co-maintainer
- Driver and function exist in this 7.3 tree; bug predates 7.3
- Standalone; not a new API

AGAINST:
- Merged commit message has no body (explanation only on list)
- Not crash/security/corruption
- Peripheral Xilinx FPGA/SoC driver
- Cover letter also talks about OOT consumers and patch 3’s 20 kHz
  policy
- Author’s 133312500 Hz sample still picked the over-rate 19500 Hz
  candidate; abs() matters when the **best** match is below the request
- lore.kernel.org HTTP 403; no stable@ thread verified

UNRESOLVED:
- Full v1 review thread
- Whether stable@ already took this (403)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — wrap math is clear; author
   posted before/after; two Reviewed-by
2. Fixes a real bug that affects users? **PASS** — wrong diffs; set_rate
   can fail or pick a worse rate
3. Important issue? **PASS** (medium) — not a panic, but the driver’s
   job is correct rates; pixel-clock path was the reason fractional
   search exists
4. Small and contained? **PASS** — 1 line, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — same function is here; HEAD
   already contains this commit as of v7.3-rc1, which means 7.3’s own
   code already includes the fix. That does not make the fix unsuitable;
   it confirms the code matches.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: **None** (not a device ID, quirk, DT, build, or docs exception).
It is a normal small correctness fix.

**Step 9.4: MAKE YOUR DECISION**

This tree is 7.3-rc4 and already contains the line, because the commit
landed in v7.3-rc1. The decision is still whether this is appropriate
**for this tree’s code**, not whether the pipeline already “selected”
it.

It is a **v6.13 regression** (accidental drop of `abs()`), one line,
reviewed, and it fixes real closest-rate / -EBUSY behavior on Xilinx
Clocking Wizard. That meets stable rules for this checkout. Later series
patches (search micro-opt, dropping 20 kHz) are separate and not
required.

===============================================================
DETAILED EXPLANATION
===============================================================

**Problem:** `clk_wzrd_get_divisors()` ranked candidates with unsigned
`freq - rate`. Any frequency below the request wrapped to ~2^64, so
those configs were ignored. Combined with `best_diff < 20000`, that
yields **-EBUSY** when the only close match is slightly low, or a
**worse higher** clock when a closer lower one exists. That is exactly
the fractional-divider accuracy the v6.13 work was supposed to provide
(pixel clocks).

**Why it matters here:** This 7.3 tree has that search (7681f64e).
Consumers of `xlnx,clocking-wizard` that call `clk_set_rate` can fail or
lock the IP to the wrong rate.

**Stable rules:** Small, obvious, real bug, no new API. Risk is a
correct rate instead of failure/wrong rate.

**Concerns:** Empty merged commit message; not a crash. Series 3/3 is a
policy change and should not be required. No backport rework is needed
on a tree that still has `diff = freq - rate`.

===============================================================
Verification:
- [Phase 1] `git show 006ba909c240b`: subject+tags only; Reviewed-by
  Datta and Masney; no Fixes/stable
- [Phase 1] b4 mbox body: wraparound explanation and traces (133312500
  Hz)
- [Phase 2] Diff: one line `diff = freq - rate` → `diff = abs(freq -
  rate)` in `clk_wzrd_get_divisors`
- [Phase 2] Parent still has `return best_diff < WZRD_MIN_ERR ? 0 :
  -EBUSY` with `WZRD_MIN_ERR` 20000
- [Phase 2] `include/linux/math.h`: `abs()` signed conversion; Hz deltas
  fit
- [Phase 3] blame: abs line is 006ba909; search from 7681f64e6404ed
  (v6.13-rc1)
- [Phase 3] 595c88cda65d30 originally used `diff = abs(freq - rate)`;
  7681f64e removed it
- [Phase 3] `git merge-base --is-ancestor 006ba909c240b HEAD` → yes;
  `--contains` → v7.3-rc1
- [Phase 3] Series 006ba909, 9329714414d1f, 54ed94b709e03; this patch is
  1/3 standalone
- [Phase 4] `b4 dig -c`:
  patch.msgid.link/20260629205346.3228886-2-colin.foster@in-
  advantage.com
- [Phase 4] `b4 dig -a`: v2 1/3 only in match; cover v2 rebase +
  signoffs
- [Phase 4] `b4 dig -w`: linux-clk, Boyd, Turquette, Datta, Simek,
  Masney
- [Phase 4] WebFetch/curl lore: 403; stable@ discussion UNVERIFIED
- [Phase 5] Callers: `clk_wzrd_dynamic_all_nolock`,
  `clk_wzrd_determine_rate_all` (non-Versal ops)
- [Phase 5] Versal sibling already `abs()` via e0a94c6bb5b48 (v6.18-rc1)
- [Phase 6] `git describe HEAD` v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` 7.3.0-rc4
- [Phase 6] HEAD already has `diff = abs(freq - rate)` at lines 375 and
  416
- [Phase 7] Kconfig `COMMON_CLK_XLNX_CLKWZRD`; compatibles
  xlnx,clocking-wizard{,-v5.2,-v6.0}
- [Phase 8] Failure mode: wrong rate or -EBUSY on set_rate; severity
  MEDIUM
- UNVERIFIED: v1 thread contents; stable@ history (lore 403)
===============================================================

**YES**

 drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index dbef983eb4252..4ef0595f7d993 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -406,7 +406,7 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
 			if (o < omin || o > omax)
 				continue;
 			freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
-			diff = freq - rate;
+			diff = abs(freq - rate);
 			if (diff < best_diff) {
 				best_diff = diff;
 				divider->m = m >> 3;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (2 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: clocking-wizard: fix clock difference detection Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.1] net: stmmac: fix device node reference leaks in stmmac_mtl_setup() Sasha Levin
                   ` (44 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Brian Masney, Sasha Levin, y.oudjana, sboyd,
	bmasney+clk, jbrunet+clk, matthias.bgg, angelogioacchino.delregno,
	linux-clk, linux-mediatek, linux-kernel, linux-arm-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 36cf8d279ff90835f4b002dec28eedb059554842 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Connection lost, reconnecting to https://agentn.us.api5.cursor.sh
(attempt 1)...
Retry attempt 1...
This tree is **Linux 7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
driver exists here; the change is a one-line `MODULE_DEVICE_TABLE(of,
...)` so the vencsys clock module can autoload from DT.

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
- Record: `[clk/mediatek] [add] add missing MODULE_DEVICE_TABLE() for
  mt6735-vencsys`

**Step 1.2: Tags**
- Record:
  - **Fixes:** none (expected for this review)
  - **Reported-by:** none
  - **Tested-by:** none
  - **Reviewed-by:** Brian Masney `<bmasney@redhat.com>` (COMMON CLK
    FRAMEWORK maintainer)
  - **Acked-by:** none
  - **Link:** none in the commit; mailing list found via `b4 dig`
  - **Cc: stable:** none (not a negative signal)
  - **Signed-off-by:** Pengpeng Hou `<pengpeng@iscas.ac.cn>` (author);
    Brian Masney `<bmasney@redhat.com>` (clk maintainer who applied it)
  - Notable: maintainer review + maintainer SOB; no user/syzbot report

**Step 1.3: Body**
- Record:
  - **Bug:** OF match table is wired to `.of_match_table` but not
    exported with `MODULE_DEVICE_TABLE()`, so `file2alias` does not emit
    `of:` aliases.
  - **Symptom:** when `CONFIG_COMMON_CLK_MT6735_VENCSYS=m`,
    udev/modprobe cannot autoload `clk-mt6735-vencsys` from
    `mediatek,mt6735-vencsys`.
  - **Version info:** none in the message. Git: driver added in
    **v6.13-rc1** (`0bd9b1211f741`); this fix first appears in
    **v7.3-rc1**.
  - **Root cause:** omitted alias publication, not a runtime logic
    error.

**Step 1.4: Hidden bug fix?**
- Record: Not hidden. It is a real functional gap (module autoload), not
  a crash/UAF. The “source-level fix / no hardware reproduction” wording
  matches the original lore submission, not pipeline decoration.

## Phase 2: Diff analysis

**Step 2.1: Inventory**
- Record:
  - `drivers/clk/mediatek/clk-mt6735-vencsys.c`: **+1 / -0**
  - Function/data: `of_match_mt6735_vencsys[]` (file scope)
  - Scope: single-file, one-line surgical change

**Step 2.2: Code flow**
- Record: Before, the table is only consumed by
  `platform_driver.driver.of_match_table` (bind if the module is already
  loaded or built-in). After, `MODULE_DEVICE_TABLE(of,
  of_match_mt6735_vencsys)` also creates a `__mod_device_table` alias so
  `scripts/mod/file2alias.c` `do_of_entry()` emits
  `of:N*T*Cmediatek,mt6735-vencsys`. Build-time metadata only; no probe-
  path change.

**Step 2.3: Bug mechanism**
- Record: **Hardware matching / module autoload** (same class as missing
  device IDs). Match table exists but is not published for modules.

**Step 2.4: Fix quality**
- Record: Obviously correct; matches sibling MT6735 files that shipped
  with `MODULE_DEVICE_TABLE` (`apmixedsys`, `infracfg`, `pericfg`,
  `topckgen`). No runtime lock/API/data-structure change. Regression
  risk is essentially none. `imgsys` and `mfgcfg` still lack the macro;
  this patch does not depend on those.

## Phase 3: Git history

**Step 3.1: Blame**
- Record: Match table and driver introduced by `0bd9b1211f741` (“clk:
  mediatek: Add drivers for MT6735 syscon clock and reset controllers”,
  Yassine Oudjana, 2024-11-06, applied 2024-11-14). First in
  **v6.13-rc1**. `MODULE_DEVICE_TABLE` line is this commit
  `36cf8d279ff90`.

**Step 3.2: Fixes: tag**
- Record: No `Fixes:` tag. The omission dates from the introducing
  commit `0bd9b1211f741`, which **is** an ancestor of this tree.

**Step 3.3: File history**
- Record: Only two commits on this file: introducer + this fix. No later
  conflicting refactor. Sibling same-day commit `096ab64a0e694` does the
  same for `clk-mt6735-vdecsys.c`. Standalone; not patch 2/N.

**Step 3.4: Author**
- Record: Pengpeng Hou is not the MT6735 clk maintainer (that is Yassine
  Oudjana). Same author also added `MODULE_DEVICE_TABLE` in `clk-
  mt6735-vdecsys.c` and two i.MX clk drivers. Applied by clk co-
  maintainer Brian Masney.

**Step 3.5: Dependencies**
- Record: None. Uses existing `MODULE_DEVICE_TABLE` / `of_device_id`.
  Applies on top of the original driver with no prerequisites.

## Phase 4: Mailing list and external research

**Step 4.1: Original discussion**
- Record: `b4 dig -c 36cf8d279ff90` →
  https://patch.msgid.link/20260704124808.19916-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only** (2026-07-04). Applied version is that v1.
- Thread (mbox): author patch + Brian Masney `Reviewed-by`. No NAK, no
  stable nomination, no risk discussion.

**Step 4.2: Recipients (`b4 dig -w`)**
- Record: Yassine Oudjana (MT6735 clk maintainer), Stephen Boyd, Brian
  Masney, Michael Turquette, Matthias Brugger, AngeloGioacchino Del
  Regno; `linux-clk`, `linux-mediatek`, `linux-arm-kernel`, `linux-
  kernel`. Right maintainers and lists.

**Step 4.3: Bug report**
- Record: No Reported-by, no syzbot, no bugzilla. Author states there
  was no hardware reproduction.

**Step 4.4: Series**
- Record: Independent single patches (vencsys + vdecsys), not a numbered
  series. This commit does not need the vdecsys patch.

**Step 4.5: Stable list**
- Record: **UNVERIFIED.** `curl` to lore.kernel.org/stable returned HTTP
  403. No in-tree evidence this was rejected for stable.

## Phase 5: Code semantic analysis

**Step 5.1: Functions**
- Record: No function body changed. Adds `MODULE_DEVICE_TABLE` next to
  `of_match_mt6735_vencsys[]`. Driver still uses
  `module_platform_driver` → `mtk_clk_simple_probe` /
  `mtk_clk_simple_remove`.

**Step 5.2: Callers**
- Record: Platform core binds via OF compatible. Probe is boot/device-
  instantiation, not a syscall hot path. Impact is whether the **module
  is loaded at all**.

**Step 5.3: Callees**
- Record: Unchanged. `mtk_clk_simple_probe()` in `clk-mtk.c` registers
  the vencsys gates from `vencsys_clks`.

**Step 5.4: Reachability**
- Record: Reachable when DT has `mediatek,mt6735-vencsys` and the driver
  is a module. **No in-tree `.dts`/`.dtsi` uses that compatible** (only
  `Documentation/devicetree/bindings/clock/mediatek,syscon.yaml`). Users
  need out-of-tree DT (typical for older MT6735 phones). Built-in (`=y`)
  is unaffected.

**Step 5.5: Similar patterns**
- Record: Same omission still present in `clk-mt6735-imgsys.c` and `clk-
  mt6735-mfgcfg.c`. Four other MT6735 clk files had
  `MODULE_DEVICE_TABLE` from day one (`43c04ed791892` for apmixedsys).
  Pattern is systematic but this patch is complete for vencsys.

## Phase 6: Local tree cross-reference

**Step 6.1: Buggy code in this tree?**
- Record: Yes. File exists; current tree already has the fix at line 40.
  Bug was the missing alias from v6.13 until v7.3-rc1.
  `CONFIG_COMMON_CLK_MT6735_VENCSYS` is **tristate**.

**Step 6.2: Backport difficulty**
- Record: **Clean apply.** File is essentially unchanged since
  introduction. One inserted line after the match table.

**Step 6.3: Related fixes already here**
- Record: This exact commit is already an ancestor of HEAD (`git merge-
  base --is-ancestor 36cf8d279ff90 HEAD` → yes). That is mainline
  history, not a reason to reject on merit. No alternate fix. Sibling
  vdecsys fix is also present; imgsys/mfgcfg still missing.

## Phase 7: Subsystem context

**Step 7.1: Subsystem / criticality**
- Record: `drivers/clk/mediatek/` — SoC clock driver. **PERIPHERAL**
  (MT6735 video-encoder clocks only). Not mm/fs/net core.

**Step 7.2: Activity**
- Record: Mediatek clk is actively maintained; this file is not. Two
  commits total. Mature omission, not churn.

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
- Record: Only MT6735 systems with `CONFIG_COMMON_CLK_MT6735_VENCSYS=m`
  and a DT node `mediatek,mt6735-vencsys`. Driver- and config-specific;
  small population (no in-tree board DTS).

**Step 8.2: Trigger**
- Record: Modular boot + OF device present. Not a race. Unprivileged
  users do not trigger it; udev autoload fails. Built-in and manual
  `modprobe` work.

**Step 8.3: Failure mode**
- Record: Module does not autoload → vencsys clocks (smi_larb3, venc,
  jpgenc, jpgdec) never register → video encode/JPEG on that SoC can
  fail. **Severity: MEDIUM** (functional miss, not
  oops/corruption/deadlock). Fits stable-rules “oh, that’s not good” and
  the device-ID-style enablement exception.

**Step 8.4: Risk-benefit**
- Record: **Benefit:** correct autoload for a supported tristate driver;
  one line. **Risk:** negligible (modinfo/depmod metadata only). Ratio
  favors applying it on trees that have this driver.

## Phase 9: Final synthesis

**Step 9.1: Evidence**

FOR:
- Real autoload bug: match table used, aliases not published
- One line, obviously correct, reviewed and applied by clk maintainer
  Brian Masney
- Driver is tristate; modular build is an intended config
- Same class as device-ID additions (publish existing OF IDs)
- Sibling MT6735 files already had the macro; this was an omission from
  `0bd9b1211f741`
- Zero runtime regression risk; applies cleanly
- Driver and bug exist in this 7.3 tree (introduced v6.13)

AGAINST:
- Not a crash, UAF, deadlock, or security issue
- No user report and no hardware reproduction
- No in-tree DT consumer for this compatible
- Niche SoC; often clocks are built-in

UNRESOLVED:
- Whether this was discussed on the stable list (lore HTTP 403)

**Step 9.2: Stable rules checklist**
1. Obviously correct and tested? **PASS** — one-line, standard macro,
   maintainer Reviewed-by/SOB. No runtime test; correctness is
   mechanical.
2. Real bug that affects users? **PASS** — modular OF autoload is
   broken. User set is small but real if they use `=m`.
3. Important issue? **PASS** (low end of “oh, that’s not good” /
   hardware-enablement), not CRITICAL.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — publishes existing match table.
6. Can apply to this tree? **PASS** — file and table exist; patch is a
   clean one-liner.

**Step 9.3: Exception category**
- Record: Closest match is **device ID / hardware matching** (OF module
  aliases), not a new driver.

**Step 9.4: Decision**

Backport this. It is a one-line, obviously correct fix for failed OF
module autoload on an existing tristate driver. That is the same kind of
enablement stable already takes for new device IDs, with no runtime
behavior change if the module is built-in or loaded by other means. This
7.3 tree has the driver (since v6.13); there are no missing
prerequisites. Limited hardware and no crash report lower urgency, not
correctness.

### What it solves for stable users
If `clk-mt6735-vencsys` is a module, userspace cannot match
`mediatek,mt6735-vencsys` and load it. Video-encoder clocks then never
appear. `MODULE_DEVICE_TABLE(of, ...)` generates the aliases
`file2alias` already knows how to emit.

### Risk vs benefit
Benefit is correct autoload on MT6735 modular configs. Risk is
negligible: no probe, locking, or ABI change.

## Verification
- [Phase 1] Parsed tags: Reviewed-by + SOB Brian Masney; no
  Fixes/Reported-by/Cc:stable
- [Phase 1] `git show -s 36cf8d279ff90`: body matches the candidate;
  “source-level fix” is in the real commit and lore v1
- [Phase 2] Diff: +1 `MODULE_DEVICE_TABLE(of, of_match_mt6735_vencsys)`
  in `clk-mt6735-vencsys.c`
- [Phase 2] `include/linux/module.h` and `scripts/mod/file2alias.c`
  `do_of_entry()`: confirmed alias generation from that macro
- [Phase 3] `git blame`: table from `0bd9b1211f741` (v6.13-rc1); macro
  from `36cf8d279ff90`
- [Phase 3] `git describe --contains 0bd9b1211f741`: v6.13-rc1; fix
  contained in v7.3-rc1; `git merge-base --is-ancestor` vs v7.2: not in
  v7.2
- [Phase 3] File log: only introducer + this commit; sibling
  `096ab64a0e694` for vdecsys
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 lore thread; Masney Reviewed-by;
  correct clk/mediatek CCs; no NAK
- [Phase 4] WebFetch lore/msgid.link: HTTP 403; used mbox instead
- [Phase 5] Kconfig: `COMMON_CLK_MT6735_VENCSYS` tristate; Makefile
  `obj-$(CONFIG_COMMON_CLK_MT6735_VENCSYS)`
- [Phase 5] `mtk_clk_simple_probe` in `clk-mtk.c` used unchanged
- [Phase 5] Grep: no in-tree dts/dtsi `mediatek,mt6735-vencsys`; binding
  in `mediatek,syscon.yaml`
- [Phase 5] imgsys/mfgcfg still lack `MODULE_DEVICE_TABLE`
- [Phase 6] `make kernelversion` / `git describe HEAD`: 7.3.0-rc4 /
  v7.3-rc4-27-gf0100363d8c37
- [Phase 6] File currently contains the macro; `git merge-base --is-
  ancestor 36cf8d279ff90 HEAD` = yes
- [Phase 7] MAINTAINERS: MT6735 clk → Yassine Oudjana; COMMON CLK →
  Stephen Boyd, Brian Masney, Jerome Brunet
- [Phase 8] Failure mode: missing module autoload, not oops; severity
  MEDIUM
- UNVERIFIED: stable@ lore discussion (HTTP 403)

**YES**

 drivers/clk/mediatek/clk-mt6735-vencsys.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt6735-vencsys.c b/drivers/clk/mediatek/clk-mt6735-vencsys.c
index 8dec7f98492ac..64ba9da9fd427 100644
--- a/drivers/clk/mediatek/clk-mt6735-vencsys.c
+++ b/drivers/clk/mediatek/clk-mt6735-vencsys.c
@@ -37,6 +37,7 @@ static const struct of_device_id of_match_mt6735_vencsys[] = {
 	{ .compatible = "mediatek,mt6735-vencsys", .data = &vencsys_clks },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, of_match_mt6735_vencsys);
 
 static struct platform_driver clk_mt6735_vencsys = {
 	.probe = mtk_clk_simple_probe,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] net: stmmac: fix device node reference leaks in stmmac_mtl_setup()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (3 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching Sasha Levin
                   ` (43 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Md Rabbani, Jakub Kicinski, Sasha Levin, maxime.chevallier,
	andrew+netdev, davem, edumazet, pabeni, mcoquelin.stm32,
	alexandre.torgue, netdev, linux-stm32, linux-arm-kernel,
	linux-kernel

From: Md Rabbani <rabbanyhmm@gmail.com>

[ Upstream commit 317fe168f4c0fc30e5c375c22d9c8911940aea9b ]

In stmmac_mtl_setup(), q_node is shared across the RX and TX queue
parsing loops. When the RX queue loop breaks early because the number
of parsed queues reaches plat->rx_queues_to_use, q_node retains an
acquired reference count. If the error check passes
(queue == plat->rx_queues_to_use), execution proceeds directly to the
TX queue loop, where of_get_next_child() immediately overwrites q_node
with the first TX child, permanently leaking the retained RX child
device node reference.

Switch both loops to for_each_child_of_node_scoped() so child node
references are automatically dropped upon loop exit or early break,
and remove the now-unnecessary function-scoped q_node variable and
its manual of_node_put() at the exit label.

Signed-off-by: Md Rabbani <rabbanyhmm@gmail.com>
Link: https://patch.msgid.link/20260821055718.57-1-rabbanyhmm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The leak is real in this 6.12 tree: `stmmac_mtl_setup()` can drop an OF
child reference when RX queue parsing breaks early, and in-tree DTs
actually hit that path.

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
- Record: `[net: stmmac:] [fix] [OF device-node reference leaks in
  stmmac_mtl_setup()]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- Record:
  - `Signed-off-by: Md Rabbani <rabbanyhmm@gmail.com>` (author)
  - `Link:
    https://patch.msgid.link/20260821055718.57-1-rabbanyhmm@gmail.com`
  - `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev
    maintainer; applied to `netdev/net`)
  - No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
    by:`, or `Cc: stable` (absence of Fixes/Cc-stable is expected for
    this review)
  - Upstream SHA (from patchwork bot):
    `317fe168f4c0fc30e5c375c22d9c8911940aea9b`

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
- Record: [Bug] Shared `q_node` is used by both RX and TX
  `for_each_child_of_node()` loops. An early `break` in the RX loop
  leaves `q_node` holding a live OF reference. If `queue ==
  plat->rx_queues_to_use`, the function continues into the TX loop,
  which calls `of_get_next_child(tx_node, NULL)` and overwrites `q_node`
  without putting the RX child.
- [Symptom] Permanent `device_node` refcount leak (kobject/`device_node`
  never released).
- [Version info] None in the message. The loops date to 2017
  (`d976a525c37127`, v4.12-rc1).
- [Root cause] Early-break + reused iterator; `of_get_next_child(parent,
  NULL)` does not drop the previous pointer.

**Step 1.4: DETECT HIDDEN BUG FIXES**
- Record: Not hidden. Subject/body explicitly describe a refcount leak.
  The `_scoped` conversion is the fix mechanism, not a style-only
  cleanup.

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
- Record: Single file
  `drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c`. Actual commit
  is **+2 / -4**. Functions: `stmmac_mtl_setup()` only. Surgical,
  single-file.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
- Record:
  - RX loop: `for_each_child_of_node(rx_node, q_node)` →
    `for_each_child_of_node_scoped(...)`. Early `break` now auto-drops
    the current child via `__free(device_node)`.
  - TX loop: same conversion.
  - Function-scope `struct device_node *q_node` removed;
    `of_node_put(q_node)` at `out:` removed (would not compile with the
    loop-scoped iterator).
  - Probe/DT parse path only; no datapath change.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
- Record: [Category] Reference counting / resource leak.
- [Mechanism] `for_each_child_of_node` is `of_get_next_child()`, which
  gets `next` and puts `prev`. `break` skips the put of the current
  node. Reusing the same pointer in the TX loop with `prev=NULL` leaks
  that RX child. TX extra children were previously dropped by the
  trailing `of_node_put(q_node)`; RX extra children were not.

**Step 2.4: ASSESS THE FIX QUALITY**
- Record: Obviously correct. `for_each_child_of_node_scoped` exists in
  this tree and is already used widely. `__free(device_node)` is `if
  (_T) of_node_put(_T)`, so NULL at loop end is safe. Regression risk is
  very low: no locking, no ABI, no behavior change besides dropping the
  leaked ref. The `_scoped` form is stronger than a one-off
  `of_node_put()` before the TX loop because it also covers TX early-
  break without a manual put.

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
- Record: Buggy loops introduced by `d976a525c37127` ("net: stmmac:
  multiple queues dt configuration", Joao Pinto, 2017-03-10), first in
  **v4.12-rc1**. Present for many years. `goto out` / extra
  `of_node_put(q_node)` added by `2ee2132ffb83e` (2018), which still
  leaves the RX-then-TX overwrite leak.

**Step 3.2: FOLLOW THE FIXES: TAG**
- Record: No `Fixes:` tag. Introducer is `d976a525c37127`, and `git
  merge-base --is-ancestor d976a525c37127 HEAD` succeeds. That code is
  in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
- Record: Recent `stmmac_platform.c` work is unrelated (bus_id, probe
  error path, IRQ). Historical OF leak fixes in this driver:
  `a249708bc2aa1`, `d2ed0a7755fe1`, `4613b279bee79`. Standalone
  `[PATCH]`, not `X/Y`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
- Record: `git log --author="Md Rabbani"` on this path is empty in this
  tree (new contributor). Applied by Jakub Kicinski to `netdev/net.git`
  (fixes tree), which is a strong maintainer signal.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
- Record: Depends on `for_each_child_of_node_scoped` /
  `DEFINE_FREE(device_node)` (`34af4554fb0ce1` / `9448e55d032d99`,
  2024-02-25). Both are already in this 6.12 tree (`git merge-base --is-
  ancestor` succeeded). Can apply standalone. `stmmac_platform.c`
  already includes `<linux/of.h>`, which includes `<linux/cleanup.h>`.

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
- Record: `b4 dig -c <sha>` cannot match because `317fe168f4c0` is not
  an ancestor of HEAD. Used msgid instead. Lore thread: `https://lore.ke
  rnel.org/netdev/20260821055718.57-1-rabbanyhmm@gmail.com/`
- Series: single v1 `[PATCH]` (2 messages: submission + patchwork-bot).
  Applied to `netdev/net.git (main)` as
  `https://git.kernel.org/netdev/net/c/317fe168f4c0`. No v2, no NAK.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
- Record: To/Cc included STMMAC maintainers (Torgue, Coquelin,
  Chevallier), netdev maintainers (Miller, Dumazet, Kicinski, Abeni),
  `netdev@`, `linux-stm32@`, `linux-arm-kernel@`. No written review
  comments; Kicinski applied it to the **net fixes** tree.

**Step 4.3: SEARCH FOR THE BUG REPORT**
- Record: No syzbot/bugzilla. Bug is from code inspection. Real in-tree
  DTs trigger it (see Phase 6/8).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
- Record: Standalone. No other patches required.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
- Record: lore.kernel.org/stable search for `stmmac_mtl_setup` shows
  older stmmac stable backports (probe error-path, MDIO, Tx COE), not
  this leak. No prior rejection of this fix.

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
- Record: `stmmac_mtl_setup()` (modified). Helpers:
  `for_each_child_of_node_scoped`, `of_get_next_child` /
  `__of_get_next_child`, `of_node_put`.

**Step 5.2: TRACE CALLERS**
- Record: Only caller is `stmmac_probe_config_dt()` in the same file
  (line 603). That is used via `devm_stmmac_probe_config_dt()` from many
  glue drivers: `dwmac-rk`, `dwmac-qcom-ethqos`, `dwmac-imx`, `dwmac-
  stm32`, `dwmac-sun8i`, `dwmac-mediatek`, `dwmac-generic`, and others.
  Probe/init context, not IRQ/hot path.

**Step 5.3: TRACE CALLEES**
- Record: `of_parse_phandle`, `of_property_read_*`, `of_get_next_child`,
  `of_node_put`. DT parse only.

**Step 5.4: FOLLOW THE CALL CHAIN**
- Record: Userspace cannot trigger it directly. It runs on every DT-
  based stmmac probe. Reachable on common ARM/ARM64 SoCs (Rockchip,
  i.MX, STM32, Qualcomm, MediaTek). Leak fires when the RX config node
  has more children than `snps,rx-queues-to-use`.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
- Record: Same file still has `for_each_child_of_node(np, mdio_node)` in
  `stmmac_of_get_mdio()` (line 324); not the same shared-iterator bug.
  In-tree DTs with extra RX children:
  `arch/arm64/boot/dts/qcom/sa8540p-ride.dts` uses `snps,rx-queues-to-
  use = <1>` with `queue0`–`queue3` on both ethernet0 and ethernet1.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
- Record: Yes. This tree is **6.12.111** (`pending-6.12`,
  `p-6.12-3-gc504cf0baa3d8`). Current code at `stmmac_platform.c:177` /
  `:240` still uses unscoped loops and `of_node_put(q_node)` at `:293`.
  `317fe168f4c0` is **not** an ancestor of HEAD. Bug present since
  v4.12.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
- Record: Expected difficulty: **minor context conflicts**. Upstream
  context has later `stmmac_axi_blen_to_mask` / `MTL_MAX_*` clamping
  that 6.12 does not have. The three functional edits (two loop macros,
  drop `q_node` + trailing put) match 6.12 1:1. Needs a small context-
  adjusted backport, not a rewrite.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
- Record: No commit with this subject in this tree. Older stmmac
  `of_node_put` fixes do not cover this iterator reuse.

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
- Record: [Subsystem] `drivers/net/ethernet/stmicro/stmmac` (Synopsys
  DWMAC). [Criticality] **IMPORTANT** — common platform Ethernet on many
  SoCs, not core mm/VFS, not staging.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
- Record: Actively maintained (many recent stmmac fixes on this branch).
  The leak itself is old (2017), not a new-feature bug.

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
- Record: Driver/config-specific: `CONFIG_STMMAC_ETH` +
  `CONFIG_STMMAC_PLATFORM` + DT `snps,mtl-rx-config` with extra child
  nodes. Confirmed affected in-tree board: Qualcomm SA8540P Ride
  (`sa8540p-ride.dts`). Many other boards have matching child counts and
  do not leak.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
- Record: Device probe (and every unbind/rebind). Common on boards whose
  DT lists more queue children than `snps,rx-queues-to-use`. Not a
  userspace syscall; not a race. Extra TX children were already put at
  `out:`; extra RX children leak.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
- Record: [Failure] One `device_node` ref leak per probe when extra RX
  children exist. [Severity] **MEDIUM** — not oops/deadlock/corruption,
  but a real lifetime leak of an OF kobject. Repeatable on module
  reload. Can pin overlay/node teardown.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
- Record: Benefit: medium (fixes a real, DT-triggered leak on a widely
  used NIC driver, including an in-tree Qualcomm board). Risk: **very
  low** (2 insertions / 4 deletions, existing helper, probe-only). Ratio
  favors backport.

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real OF refcount leak, mechanism verified against
  `of_get_next_child()` / `__of_get_next_child()`.
- Buggy code is in this 6.12 tree and has been since v4.12.
- In-tree DT `sa8540p-ride.dts` has 4 RX queue children with `rx-queues-
  to-use = <1>` — the leak path is not theoretical.
- Tiny, obviously correct fix; helper already in 6.12.
- Applied to `netdev/net` (fixes) by Kicinski.
- Same class of bug as prior stmmac `of_node_put` fixes already in
  history.
- No new API/feature; no series dependency.

AGAINST:
- Probe-time leak of a single node, not a crash/UAF/security issue.
- Surrounding file context differs slightly from mainline, so `git am`
  of the raw mainline diff may need a trivial refresh.
- No user crash report / syzbot.

UNRESOLVED:
- No written mailing-list review beyond maintainer application (v1
  accepted as-is).

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — scoped put on break/exit is
   the intended helper; applied to netdev/net.
2. Fixes a real bug that affects users? **PASS** — leak on probe;
   triggered by in-tree Qualcomm DT.
3. Important issue? **PASS** at medium importance — resource leak, not
   panic, but a genuine lifetime bug in a common Ethernet driver.
4. Small and contained? **PASS** — +2/-4, one function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — same loops exist; scoped
   macro exists; minor context tweak only.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
- Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
  bugfix.

**Step 9.4: DECISION**
Backport to this 6.12 tree. The bug exists here, the helper exists here,
the fix is surgical, and at least one in-tree board hits it.

---

### What the commit solves and why it matters here
`stmmac_mtl_setup()` parses `snps,mtl-rx-config` / `snps,mtl-tx-config`
at probe. The RX iterator `break`s once `queue >=
plat->rx_queues_to_use`, leaving `q_node` referenced. The TX loop then
starts with `of_get_next_child(tx_node, NULL)`, which never puts that RX
child. That is a permanent OF node leak.
`arch/arm64/boot/dts/qcom/sa8540p-ride.dts` is written exactly that way
(1 queue in use, 4 queue child nodes).

### Stable rules / risk
Meets the rules: small, obviously correct, no new API, real leak, helper
already in 6.12. Risk is a possible trivial context conflict around
later mainline-only `stmmac_platform.c` edits; the functional change
does not depend on those.

### Verification
- [Phase 1] Parsed tags: author SOB, msgid Link, Kicinski SOB; no
  Fixes/Reported-by; upstream `317fe168f4c0`
- [Phase 2] Diff: +2/-4 in `stmmac_mtl_setup()`; two loops to `_scoped`;
  drop `q_node` + `of_node_put(q_node)`
- [Phase 2] `__of_get_next_child()` does `of_node_get(next);
  of_node_put(prev)` (`drivers/of/base.c:600-603`); `prev=NULL` does not
  put the overwritten pointer
- [Phase 3] Blame: loops from `d976a525c37127` (v4.12-rc1); ancestor of
  HEAD
- [Phase 3] `34af4554fb0ce1` / `DEFINE_FREE(device_node)` are ancestors
  of HEAD
- [Phase 3] `git merge-base --is-ancestor 317fe168f4c0 HEAD` failed (fix
  not in this tree)
- [Phase 4] `b4 mbox` msgid: 2-message thread; applied to netdev/net; no
  NAK
- [Phase 4] stable lore search: no discussion of this leak
- [Phase 5] Caller: `stmmac_probe_config_dt()` → many `dwmac-*` platform
  probes
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111
  `pending-6.12`; buggy loops still present at lines 177 and 240
- [Phase 6] `sa8540p-ride.dts` `ethernet0_mtl_rx_setup` /
  `ethernet1_mtl_rx_setup`: `rx-queues-to-use = <1>` with queue0–queue3
- [Phase 8] Failure mode: OF `device_node` leak at probe, severity
  MEDIUM
- UNVERIFIED: Could not use `b4 dig -c` against HEAD (commit not in this
  checkout); lore HTML fetch returned 403, raw/mbox succeeded

**YES**

 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 0cb51935c4056..ceb913a3a6c69 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -131,7 +131,6 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
 static int stmmac_mtl_setup(struct platform_device *pdev,
 			    struct plat_stmmacenet_data *plat)
 {
-	struct device_node *q_node;
 	struct device_node *rx_node;
 	struct device_node *tx_node;
 	u8 queue = 0;
@@ -174,7 +173,7 @@ static int stmmac_mtl_setup(struct platform_device *pdev,
 		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
 
 	/* Processing individual RX queue config */
-	for_each_child_of_node(rx_node, q_node) {
+	for_each_child_of_node_scoped(rx_node, q_node) {
 		if (queue >= plat->rx_queues_to_use)
 			break;
 
@@ -237,7 +236,7 @@ static int stmmac_mtl_setup(struct platform_device *pdev,
 	queue = 0;
 
 	/* Processing individual TX queue config */
-	for_each_child_of_node(tx_node, q_node) {
+	for_each_child_of_node_scoped(tx_node, q_node) {
 		if (queue >= plat->tx_queues_to_use)
 			break;
 
@@ -290,7 +289,6 @@ static int stmmac_mtl_setup(struct platform_device *pdev,
 out:
 	of_node_put(rx_node);
 	of_node_put(tx_node);
-	of_node_put(q_node);
 
 	return ret;
 }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (4 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.1] net: stmmac: fix device node reference leaks in stmmac_mtl_setup() Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Sasha Levin
                   ` (42 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: K Prateek Nayak, Peter Zijlstra (Intel), Catalin Marinas,
	Charlie Jenkins, Sasha Levin, will, linux-arm-kernel,
	linux-kernel

From: K Prateek Nayak <kprateek.nayak@amd.com>

[ Upstream commit a6690350a4ae7558b39d15fcc776c4d1ab5bbf39 ]

The current scheme to directly patch the kernel text for runtime
constants runs into the following issue with futex adapted to using
runtime constants on arm64:

  Unable to handle kernel write to read-only memory at virtual address ...

The pc points to the *p assignment in the following call chain:

  futex_init()
    runtime_const_init(shift, __futex_shift)
      __runtime_fixup_shift()
        *p = cpu_to_le32(insn);

which suggests that core_initcall() is too late to patch the kernel text
directly unlike the "d_hash_shift" which is initialized during
vfs_caches_init_early() before the protections are in place.

Use aarch64_insn_patch_text_nosync() to patch the runtime constants
instead of doing it directly to allow runtime_const_init() slightly
later into the boot.

Since aarch64_insn_patch_text_nosync() calls caches_clean_inval_pou()
internally, __runtime_fixup_caches() ends up being redundant.
runtime_const_init() are rare and the overheads of multiple calls to
caches_clean_inval_pou() instead of batching them together should be
negligible in practice.

The cpu_to_le32() conversion of instruction isn't necessary since it is
handled later in the aarch64_insn_patch_text_nosync() call-chain:

  aarch64_insn_patch_text_nosync(addr, insn)
    aarch64_insn_write(addr, insn)
      __aarch64_insn_write(addr, cpu_to_le32(insn))

Sashiko noted that aarch64_insn_patch_text_nosync() does not expect a
lm_alias() address and Catalin suggested it is safe to drop the
lm_alias() for runtime patching since the kernel text is readable. The
address passed to fixup function is interpreted as a __le32 and
dereferenced as is to read the opcode at the patch site.

No functional changes are intended.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Link: https://patch.msgid.link/20260728052540.4728-3-kprateek.nayak@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Connection lost, reconnecting to https://agentn.us.api5.cursor.sh
(attempt 1)...
Retry attempt 1...
## Phase 1: Commit message forensics

**Step 1.1 — Subject line**
- Record: **[arm64/runtime-const] [Use] switch text patching from a
  direct store to `aarch64_insn_patch_text_nosync()`**

**Step 1.2 — Tags**
- Record:
  - Signed-off-by: K Prateek Nayak (author)
  - Signed-off-by: Peter Zijlstra (locking/futex maintainer)
  - Reviewed-by: Catalin Marinas (arm64 maintainer)
  - Reviewed-by: Charlie Jenkins
  - Tested-by: Charlie Jenkins
  - Link: https://patch.msgid.link/20260728052540.4728-3-
    kprateek.nayak@amd.com
  - No Fixes:, no Reported-by, no Cc: stable (absence expected)
  - Ignore pipeline SOBs if present; none in the real commit

**Step 1.3 — Body**
- Record:
  - **Bug:** arm64 runtime-const writes the patched opcode with `*p =
    cpu_to_le32(insn)` through `lm_alias()`. That faults once kernel
    text (including the linear alias) is read-only.
  - **Symptom:** `Unable to handle kernel write to read-only memory`
    during `futex_init()` → `runtime_const_init()` →
    `__runtime_fixup_shift()`.
  - **Root cause:** `d_hash_shift` is patched in
    `vfs_caches_init_early()` while the linear alias is still writable.
    `futex_init()` is a `core_initcall`, after
    `mark_linear_text_alias_ro()`.
  - **Fix:** use the existing text-poking helper (fixmap writable alias
    + cache maintenance). Drop redundant `__runtime_fixup_caches()` and
    `cpu_to_le32()` (done inside the helper). Drop `lm_alias()` because
    the helper wants a kernel-text address.
  - **Version info:** none beyond the futex/runtime-const interaction.

**Step 1.4 — Hidden bug fix?**
- Record: Not hidden. The message describes a concrete oops. “No
  functional changes are intended” means the patched immediates are the
  same; the write path is what changes so late `runtime_const_init()`
  can succeed.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
- Record: one file, `arch/arm64/include/asm/runtime-const.h` (~5
  insertions, 12 deletions). Functions: `__runtime_fixup_16()`,
  `__runtime_fixup_caches()` (removed), `__runtime_fixup_ptr()`,
  `__runtime_fixup_shift()`. Surgical, single-header.

**Step 2.2 — Flow change**
- Record:
  - **Before:** read opcode at `lm_alias(where)`, store new insn with
    `*p = cpu_to_le32(insn)`, then `caches_clean_inval_pou()` on the
    original VA.
  - **After:** pass the kernel-text pointer and host-endian insn to
    `aarch64_insn_patch_text_nosync()`, which maps a writable fixmap
    page, writes, and flushes I/D caches.
  - Affected path: boot-time `runtime_const_init()` only (not a hot
    path).

**Step 2.3 — Bug mechanism**
- Record: **logic/correctness of text patching after RO protection**.
  Direct store to RO kernel text. The helper uses `patch_map()` →
  `FIX_TEXT_POKE0`, the same path as kprobes/jump labels/ftrace.

**Step 2.4 — Fix quality**
- Record: Obviously correct. Matches how arm64 already patches text.
  Regression risk is low: leftover `#include <asm/cacheflush.h>` is
  unused after the helper absorbs the flush; return value of the helper
  is ignored (old path had no error check either; kernel text is 4-byte
  aligned). Catalin confirmed dropping `lm_alias()` is safe because
  kernel text remains readable for the opcode load.

## Phase 3: Git history

**Step 3.1 — Blame**
- Record: Buggy direct-write scheme introduced in `94a2bc0f611cd`
  (“arm64: add 'runtime constant' support”, Linus, 2024-07-09). Present
  since ~v6.11. The crash only appears when `runtime_const_init()` runs
  after `mark_linear_text_alias_ro()`.

**Step 3.2 — Fixes: tag**
- Record: none. Introducing commit is `94a2bc0f611cd` (in this tree).
  The late caller that actually faults is `b78b0b6582527` (“futex: Use
  runtime constants for `__futex_hash()` hot path”), also in this tree
  (v7.3-rc1).

**Step 3.3 — File history**
- Record: `94a2bc0f611cd` add support → `0100e495cdf04` modules ban →
  **`a6690350a4ae7` this fix** → `7eccf137dc044`
  `runtime_const_mask_32()`. Same series as the futex conversion; this
  patch is 2/8 and does not depend on later patches. Later mask support
  *uses* this helper.

**Step 3.4 — Author**
- Record: K Prateek Nayak (AMD), not the arm64 maintainer. Arm64 review
  is from Catalin. Peter Zijlstra signed off (locking tree). Related:
  `7eccf137dc044` immediately after.

**Step 3.5 — Dependencies**
- Record: Needs `aarch64_insn_patch_text_nosync()` / `<asm/text-
  patching.h>` — present at the parent and on HEAD. Standalone vs the
  rest of the series. On *this* tree the futex caller is already
  present, so the fix is load-bearing.

## Phase 4: Mailing list

**Step 4.1 — Original discussion**
- Record: `b4 dig -c a6690350a4ae` → `[PATCH v6 2/8] arm64/runtime-
  const: Use aarch64_insn_patch_text_nosync() for patching` at
  https://patch.msgid.link/20260728052540.4728-3-kprateek.nayak@amd.com.
  Cover: `[PATCH v6 0/8] futex: Use runtime constants for futex_hash
  computation`. v5→v6: no diff change on this patch; tags collected. No
  NAKs. Sashiko noted the helper must not get an `lm_alias()` address;
  Catalin said dropping it is fine. No reviewer asked for Cc: stable.

**Step 4.2 — Recipients**
- Record: Catalin Marinas, Will Deacon, Peter Zijlstra, Thomas Gleixner,
  linux-arm-kernel, linux-arch. Right maintainers were on the To/Cc
  list. Catalin Reviewed-by is on the committed patch.

**Step 4.3 — Bug report**
- Record: No syzbot/bugzilla. The oops is from the author’s own
  futex+runtime-const bring-up on arm64. Charlie Jenkins Tested-by.
  Cover letter: build+boot on x86 bare metal and QEMU for other arches.

**Step 4.4 — Series**
- Record: v6 8-patch feature series. This commit is the arm64 text-
  poking prerequisite. Patch 8 adds `runtime_const_init()` in
  `futex_init()`. Both are in this 7.3-rc4 tree.

**Step 4.5 — Stable list**
- Record: UNVERIFIED for a dedicated stable@ thread (lore HTTP 403). No
  stable mention in the saved v6 mbox.

## Phase 5: Code semantics

**Step 5.1 — Functions**
- Record: `__runtime_fixup_16`, `__runtime_fixup_ptr`,
  `__runtime_fixup_shift`; `__runtime_fixup_caches` removed. Current
  tree also has `__runtime_fixup_mask` (later commit) using the same
  helper.

**Step 5.2 — Callers**
- Record: `runtime_const_init()` → `runtime_const_fixup()` → those
  fixups. Call sites in this tree:
  - `kernel/futex/core.c` `futex_init()` — `core_initcall` — **after**
    `smp_cpus_done()` → `mark_linear_text_alias_ro()`
  - `fs/dcache.c`, `fs/file_table.c`, `fs/namei.c` —
    `vfs_caches_init[_early]()` in `start_kernel()` — **before** that RO
    switch

**Step 5.3 — Callees**
- Record: `aarch64_insn_patch_text_nosync()` → `aarch64_insn_write()` →
  `__aarch64_insn_write()` (`patch_map` + `copy_to_kernel_nofault`) +
  `caches_clean_inval_pou()`.

**Step 5.4 — Reachability**
- Record: Unconditional on arm64. `futex_init` is a `core_initcall`.
  Every arm64 boot on this tree hits the late patch. Without this fix:
  boot oops.

**Step 5.5 — Similar patterns**
- Record: x86 runtime-const still does a direct store and documents
  “only at init before text is RO”. arm64’s linear-map alias is marked
  RO earlier (`smp_cpus_done`), so arm64 cannot follow that model for
  `core_initcall`.

## Phase 6: This tree

**Step 6.1 — Buggy code here?**
- Record: Yes. Tree is **v7.3-rc4** (`7.3.0-rc4`, HEAD `f0100363d8c37`).
  File exists. Pre-fix body is at `a6690350a4ae^`. `futex_init()` still
  calls `runtime_const_init()` (`kernel/futex/core.c`). The fix commit
  **is already an ancestor of HEAD** (in v7.3-rc1). Current `runtime-
  const.h` already calls `aarch64_insn_patch_text_nosync()`.

**Step 6.2 — Backport difficulty**
- Record: Clean on the parent snapshot. Current HEAD already has this
  plus `runtime_const_mask_32()`; re-applying the exact hunk would be a
  no-op / already-applied.

**Step 6.3 — Related fixes already here**
- Record: This *is* the fix. No later Fixes: for `a6690350`. Follow-up
  `7eccf137dc044` only adds mask patching on the new helper.

## Phase 7: Subsystem

**Step 7.1**
- Record: **arch/arm64** text-patching used by **futex** (core locking).
  Criticality: **IMPORTANT** — every arm64 boot.

**Step 7.2**
- Record: Active in the 7.3 window (futex runtime-const series). The
  underlying helper is old, stable infrastructure.

## Phase 8: Impact and risk

**Step 8.1**
- Record: All arm64 users of this kernel (futex init is not optional).

**Step 8.2**
- Record: Every boot, `core_initcall(futex_init)`. Not userspace-
  triggered; it is a boot breaker.

**Step 8.3**
- Record: Kernel fault writing RO text → boot failure. **CRITICAL**.

**Step 8.4**
- Record: Benefit high (arm64 actually boots with the futex runtime-
  const code this tree already has). Risk low (~one-header, established
  poking API, arm64 maintainer Reviewed-by).

## Phase 9: Synthesis

**Evidence for YES**
- Documented oops: write to RO memory in `__runtime_fixup_shift()`.
- This tree has the late caller (`futex_init` / `core_initcall`) and
  `mark_linear_text_alias_ro()` in `smp_cpus_done()` before
  `do_basic_setup()` / initcalls.
- Small, local, uses the standard arm64 patching API.
- Reviewed by Catalin Marinas; tested by Charlie Jenkins; signed off by
  Peter Zijlstra.
- No new userspace API.

**Evidence against**
- Lives in a feature series (futex hash optimization). On trees
  *without* a late `runtime_const_init()`, the old path never faulted.
- No Fixes:/Cc: stable (not a negative under these rules).
- Already in this 7.3-rc4 history, so a second apply is unnecessary —
  that is not used as a NO (pipeline “already selected” is ignored).

**Unresolved**
- No stable@ thread readable (lore 403). Does not change the local
  technical picture.

**Stable-rules checklist**
1. Obviously correct and tested — **PASS** (Catalin + Tested-by + QEMU
   boot)
2. Real user-visible bug — **PASS** (arm64 boot oops with this tree’s
   futex init)
3. Important (crash) — **PASS** (CRITICAL)
4. Small/contained — **PASS** (one header, ~17 lines)
5. No new features/APIs — **PASS**
6. Applies to this tree — **PASS** (code and helper are here; commit
   already merged in 7.3-rc1)

**Exception category:** none (not an ID/quirk/DT/docs/build-only
change).

This tree ships both the late `runtime_const_init()` and arm64
`STRICT_KERNEL_RWX` linear-alias RO. The old `lm_alias()` store is a
boot crash. Replacing it with `aarch64_insn_patch_text_nosync()` is the
correct, minimal fix and belongs in this series.

### Verification
- [Phase 1] Parsed tags: Reviewed-by Catalin Marinas, Tested-by Charlie
  Jenkins, Link to v6 2/8; no Fixes:/syzbot
- [Phase 2] Diff: one file; direct `*p` store + `lm_alias` +
  `__runtime_fixup_caches` replaced by `aarch64_insn_patch_text_nosync`
- [Phase 2] Confirmed helper: `arch/arm64/kernel/patching.c`
  `aarch64_insn_patch_text_nosync()` → write via `patch_map` +
  `caches_clean_inval_pou`
- [Phase 3] `git describe HEAD` / Makefile: **v7.3-rc4**, `7.3.0-rc4`
- [Phase 3] `git merge-base --is-ancestor a6690350 HEAD`: yes; also in
  v7.3-rc1; not in v7.2
- [Phase 3] Blame: buggy writes from `94a2bc0f611cd` (2024); late caller
  `b78b0b6582527` in this tree
- [Phase 3] Parent file shown: `*p = cpu_to_le32(insn)` + `lm_alias`
- [Phase 4] `b4 dig -c a6690350`: lore match v6 2/8; mbox saved; no NAK;
  Catalin R-b on the patch
- [Phase 4] Cover letter: feature series for futex runtime const; this
  patch is the arm64 poking prerequisite
- [Phase 4] UNVERIFIED: stable@ mailing-list search (lore 403)
- [Phase 5] Callers: futex `core_initcall` (late); VFS caches in
  `start_kernel` (early)
- [Phase 5] `mark_linear_text_alias_ro()` called from `smp_cpus_done()`;
  `do_basic_setup()`/`do_initcalls()` after `smp_init()`
- [Phase 6] Current `runtime-const.h` already uses the helper; `text-
  patching.h` exists at parent
- [Phase 8] Failure mode: RO-text write → boot oops on all arm64,
  CRITICAL
- UNVERIFIED: Catalin’s original review mail text (only R-b + commit-
  message paraphrase in v6 mbox)

The patch is small, uses the existing arm64 text-poking path, and
prevents a boot crash on this tree’s futex `runtime_const_init()`.

**YES**

 arch/arm64/include/asm/runtime-const.h | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
index be5915669d239..31a6f94e57955 100644
--- a/arch/arm64/include/asm/runtime-const.h
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -3,6 +3,7 @@
 #define _ASM_RUNTIME_CONST_H
 
 #include <asm/cacheflush.h>
+#include <asm/text-patching.h>
 
 /* Sigh. You can still run arm64 in BE mode */
 #include <asm/byteorder.h>
@@ -46,34 +47,26 @@ static inline void __runtime_fixup_16(__le32 *p, unsigned int val)
 	u32 insn = le32_to_cpu(*p);
 	insn &= 0xffe0001f;
 	insn |= (val & 0xffff) << 5;
-	*p = cpu_to_le32(insn);
-}
-
-static inline void __runtime_fixup_caches(void *where, unsigned int insns)
-{
-	unsigned long va = (unsigned long)where;
-	caches_clean_inval_pou(va, va + 4*insns);
+	aarch64_insn_patch_text_nosync(p, insn);
 }
 
 static inline void __runtime_fixup_ptr(void *where, unsigned long val)
 {
-	__le32 *p = lm_alias(where);
+	__le32 *p = where;
 	__runtime_fixup_16(p, val);
 	__runtime_fixup_16(p+1, val >> 16);
 	__runtime_fixup_16(p+2, val >> 32);
 	__runtime_fixup_16(p+3, val >> 48);
-	__runtime_fixup_caches(where, 4);
 }
 
 /* Immediate value is 6 bits starting at bit #16 */
 static inline void __runtime_fixup_shift(void *where, unsigned long val)
 {
-	__le32 *p = lm_alias(where);
+	__le32 *p = where;
 	u32 insn = le32_to_cpu(*p);
 	insn &= 0xffc0ffff;
 	insn |= (val & 63) << 16;
-	*p = cpu_to_le32(insn);
-	__runtime_fixup_caches(where, 1);
+	aarch64_insn_patch_text_nosync(p, insn);
 }
 
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Publish pgtbl_ops before releasing init_mutex
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (5 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
                   ` (41 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Mukesh Ojha, Konrad Dybcio, Will Deacon, Sasha Levin, robin.clark,
	joro, iommu, linux-arm-msm, linux-arm-kernel, linux-kernel

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit a05b67cd45ad09a19f41b2d37255da714512e0ca ]

qcom_domain->pgtbl_ops was assigned after mutex_unlock(). Another thread
calling qcom_iommu_init_domain() would see qcom_domain->iommu already set
(domain fully initialized) and skip re-initialization under the mutex.
If it then called qcom_iommu_map() before the first thread set pgtbl_ops,
it would observe a NULL ops pointer and return -ENODEV for valid mappings.

Move the assignment to before mutex_unlock() so that once the mutex is
released the domain is fully visible to concurrent operations.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3-rc4** (mainline). The driver is present, the
race is real, and the fix is a five-line lock-ordering correction. Below
is the full nine-phase review.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[iommu/qcom] [Publish] Publish pgtbl_ops before releasing
init_mutex`
Subsystem: Qualcomm IOMMU (`drivers/iommu/arm/arm-smmu/qcom_iommu.c`).
Verb “Publish … before” is a visibility/ordering fix (equivalent to
“ensure” / “prevent”).

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>`
- `Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>` (author)
- `Signed-off-by: Will Deacon <will@kernel.org>` (IOMMU/SMMU maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Link:`, or `Cc: stable`
  (absence expected; not a negative)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `qcom_domain->pgtbl_ops` was stored after
  `mutex_unlock(&init_mutex)`.
- **Symptom:** A concurrent `qcom_iommu_init_domain()` sees
  `qcom_domain->iommu` already set, skips init, then `qcom_iommu_map()`
  reads a NULL ops pointer and returns `-ENODEV` for valid mappings.
- **Root cause:** The “domain initialized” flag (`iommu`) is published
  under the mutex; page-table ops are published after the mutex is
  dropped, so the domain is only half-visible.
- **Version info:** None in the message. Blame shows the unlock-then-
  assign pattern dates to the original driver (2017).

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. Explicit race with a concrete failure (`-ENODEV`
on map). Not cleanup/refactor.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/iommu/arm/arm-smmu/qcom_iommu.c` — 2 insertions, 3
  deletions
- Function: `qcom_iommu_init_domain()`
- Scope: single-file surgical reorder of three statements

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
**Before:** program context banks → `mutex_unlock(init_mutex)` →
`pgtbl_ops = …` → `return 0`.
**After:** program context banks → `pgtbl_ops = …` →
`mutex_unlock(init_mutex)` → `return 0`.
Error paths (`out_clear_iommu` / `out_unlock`) are unchanged. This is
the success-path publication of domain state.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Synchronization / race]**.
`qcom_domain->iommu` is set near the start of init (under the mutex) and
is the “already initialized” flag:

```227:229:drivers/iommu/arm/arm-smmu/qcom_iommu.c
        mutex_lock(&qcom_domain->init_mutex);
        if (qcom_domain->iommu)
                goto out_unlock;
```

`qcom_iommu_map()` does not take `init_mutex`; it only checks
`pgtbl_ops`:

```436:439:drivers/iommu/arm/arm-smmu/qcom_iommu.c
        struct io_pgtable_ops *ops = qcom_domain->pgtbl_ops;

        if (!ops)
                return -ENODEV;
```

Unlocking before the store lets another attach skip init and then map
with a NULL ops pointer. The fix publishes ops while still holding the
mutex so that once waiters proceed, the domain is fully usable.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct publish-under-lock. Minimal. No new locks,
APIs, or control flow besides statement order. Regression risk is very
low: the assignment is a plain pointer store of a fully constructed
object; holding the mutex a few extra instructions does not create
deadlock (map/unmap use `pgtbl_lock`, not `init_mutex`).

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record: Unlock-then-assign was introduced in `0ae349a0f33fb`
(“iommu/qcom: Add qcom_iommu”, Rob Clark, 2017-08-09), first in
**v4.14-rc1**. The bug is ~9 years old in this driver, not a recent
regression.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Buggy code is the original 2017 driver, which
is an ancestor of this tree.

**Step 3.3: CHECK FILE HISTORY**
Record: Same-day series from Mukesh Ojha (applied 2026-07-22 by Will
Deacon):
- `3c748a5554f96` — leak of `pgtbl_ops` on error (patch 4/6)
- `a05b67cd45ad0` — this commit (patch 5/6)
- `cb776a03a5342` — clocks before ctx probe (patch 6/6)

This patch only reorders unlock vs assignment. It does **not** depend on
the leak fix.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Mukesh Ojha (Qualcomm) submitted a “Misc Fixes” series for the
legacy qcom_iommu driver. Not the IOMMU subsystem maintainer; Will
Deacon applied it. Konrad Dybcio (Qualcomm) reviewed.

**Step 3.5: DEPENDENT/PREREQUISITE COMMITS**
Record: Standalone. v2 series is 6 patches; this one has no code
dependency on the others. Can apply alone.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore (from `b4 dig -c a05b67cd45ad0`): https://patch.msgid.link/202607
  17144608.3216274-6-mukesh.ojha@oss.qualcomm.com
- **v1:** `[PATCH 5/8]` 2026-06-23 — https://patch.msgid.link/2026062312
  2034.1166295-6-mukesh.ojha@oss.qualcomm.com
- **v2:** `[PATCH v2 5/6]` 2026-07-17 (applied version; same diff as v1
  for this patch)
- Konrad on v1: `Reviewed-by` plus a non-blocking note that a
  `guard(mutex)` wrapper would also work. No NAK.
- Will Deacon applied the whole v2 series to `iommu (arm/smmu/updates)`
  on 2026-07-22. No stable nomination, no risk flags.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Mukesh Ojha, Rob Clark, Will Deacon, Joerg Roedel,
Alex Williamson, Robin Murphy, Konrad Dybcio; lists
`iommu@lists.linux.dev`, `linux-arm-msm`, `linux-arm-kernel`.
Appropriate maintainers were on Cc. Konrad reviewed; Will applied.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by`, syzbot, or bugzilla. Author analysis only.
UNVERIFIED whether anyone hit this in the field.

**Step 4.4: RELATED PATCHES AND SERIES**
Record: Part of “iommu/qcom: Misc Fixes”. Other patches (fault-log
polarity, pm_runtime, leak, clocks) are independent. v1 patches 6/8 and
8/8 were dropped after review; this patch was unchanged.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search for `pgtbl_ops qcom` did not show
this patch. Hits were unrelated (`arm-smmu-qcom` power-up). No evidence
it was rejected for stable.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `qcom_iommu_init_domain()` (modified). Related:
`qcom_iommu_attach_dev()`, `qcom_iommu_map()`, `qcom_iommu_unmap()`,
`qcom_iommu_iova_to_phys()`.

**Step 5.2: TRACE CALLERS**
Record:
- `qcom_iommu_init_domain()` is only called from
  `qcom_iommu_attach_dev()`.
- `attach_dev` is the IOMMU `.attach_dev` op
  (`qcom_iommu_ops.default_domain_ops`).
- Core path: `__iommu_attach_device()` → `domain->ops->attach_dev()`.
- This driver `select ARM_DMA_USE_IOMMU`. `arm_iommu_attach_device()`
  documents that more than one client may share a mapping, and calls
  `iommu_attach_device()`. Parallel probe of two devices sharing a
  mapping is a realistic concurrent `init_domain` on the same
  `qcom_domain`. Group mutex serializes attach **within** a group;
  `generic_device_group` means one device per group, so two devices are
  two groups and are **not** serialized against each other.

**Step 5.3: TRACE CALLEES**
Record: `alloc_io_pgtable_ops()`, `qcom_scm_restore_sec_cfg()`, context-
bank MMIO, `mutex_lock/unlock`. SCM and register programming make the
critical section long; waiters pile up on `init_mutex` and then race the
post-unlock store.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable from device probe / DMA attach on Qualcomm “B family”
SMMU platforms (MSM8916/8937/8939/8953/8976, etc.). Not a syscall fuzzer
path; it is a normal boot/probe path. Userspace-triggered concurrent
attach is also possible via the ARM DMA mapping API / VFIO-style attach
of separate groups to one domain.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: `init_mutex` comment is “Protects iommu pointer” — the original
code treated `iommu` as the publication point and left `pgtbl_ops`
outside the lock. No sibling qcom function has the same bug.
`map`/`unmap`/`iova_to_phys` all NULL-check `pgtbl_ops` and return
`-ENODEV`/0 rather than crashing — so the race fails mappings instead of
oopsing.

semcode MCP: not available; used git grep and reads.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- Tree: `v7.3-rc4-27-gf0100363d8c37`, `make kernelversion` =
  **7.3.0-rc4**.
- File exists at `drivers/iommu/arm/arm-smmu/qcom_iommu.c`.
- `git merge-base --is-ancestor a05b67cd45ad0 HEAD` succeeds: this
  commit is already in this checkout (landed as
  `v7.2-rc2-7-ga05b67cd45ad0`).
- Pre-fix code existed here from v4.14 until that commit. The race is in
  this driver’s design, not in code added after this tree branched.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Five-line reorder around a pattern present since 2017. File
moved in `e86d1aa8b60f7` (v5.8) from `drivers/iommu/qcom_iommu.c`; this
tree already uses the new path. Expected apply: **clean**. No
conflicting churn around the unlock.

**Step 6.3: RELATED FIXES ALREADY HERE**
Record: The leak fix `3c748a5554f96` is also here and is independent. No
alternate fix for this race.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: `[iommu / Qualcomm legacy SMMU] [IMPORTANT]`
Not mm/core, but IOMMU DMA for a family of Qualcomm SoCs still in DT
(phones, Dragonboard-class boards, embedded). Mapping failures break DMA
for those devices.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Legacy driver (“Misc Fixes” cover letter). Recent Qualcomm
fixes; not a new subsystem. Mature code, long-present bug.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **driver-specific / config-specific** — `CONFIG_QCOM_IOMMU` on
`ARCH_QCOM` (MSM8916, MSM8937, MSM8939, MSM8953, MSM8976, …). Not
universal.

**Step 8.2: TRIGGER CONDITIONS**
Record: Two threads attaching the same `qcom_iommu_domain` (shared ARM
DMA mapping, or two groups attached to one domain). After the first
drops `init_mutex` and before it stores `pgtbl_ops`, the second skips
init and maps. Window is a few instructions, but **preemption after
unlock** makes it realistic; SCM-held init also means waiters are ready
to run immediately. Not triggerable by an unprivileged syscall alone in
the usual case; it is a probe/attach race. No field `Reported-by`
(UNVERIFIED in production).

**Step 8.3: FAILURE MODE SEVERITY**
Record: **Failed IOMMU map (`-ENODEV`) for valid mappings** → DMA setup
failure / device non-functional. Not a KASAN UAF or panic (`map` NULL-
checks). **Severity: HIGH** (device DMA broken), not CRITICAL (no
oops/corruption).

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** Prevents a real attach/map race on Qualcomm IOMMU;
  devices keep working under concurrent attach.
- **Risk:** Very low (3-statement reorder, no API/locking change).
- **Ratio:** Favorable.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real race: initialized flag published under lock, ops pointer
  published after unlock.
- User-visible failure: valid maps return `-ENODEV` (DMA/device
  failure).
- Bug in the driver since v4.14; this tree’s driver still has that
  design.
- 5-line, obviously correct publish-under-lock.
- Reviewed by Konrad Dybcio; applied by Will Deacon.
- Self-contained; not a new feature.
- Used on real Qualcomm SoCs that still ship on LTS-class kernels.

**AGAINST:**
- No `Reported-by` / syzbot / crash log.
- Window is small; needs concurrent attach to the **same** domain.
- Failure is `-ENODEV`, not oops/UAF/corruption.
- Cover letter calls the series “Misc Fixes”; nobody Cc’d stable.
- Peripheral vs core (legacy qcom_iommu, not arm-smmu-v3).

**UNRESOLVED:**
- No confirmed production hit.
- lore.kernel.org HTML fetch returned 403; discussion recovered via `b4
  dig`/`b4 mbox`.
- How often qcom platforms share one `dma_iommu_mapping` across devices
  is not fully quantified; the ARM DMA API and `init_mutex` exist
  specifically for that case.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — reorder is locally
   checkable; Konrad R-b; Will applied; in mainline since v7.2-rc2.
2. Fixes a real bug that affects users? **PASS** — concurrent attach can
   fail valid DMA maps.
3. Important issue? **PASS** — DMA map failure can take devices out; not
   a panic, but not cosmetic.
4. Small and contained? **PASS** — 5 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — same file/function; already
   the current code here.

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not a device-ID/quirk/DT/build/doc exception). It is a
normal small race fix.

**Step 9.4: DECISION**

This tree is **7.3-rc4**. The Qualcomm IOMMU driver is here, and the
race is in the original 2017 init/map split, not in later architecture.
The patch is a correct, tiny publication-order fix: once `init_mutex` is
dropped, `pgtbl_ops` must already be visible so a concurrent attach
cannot skip init and then fail `qcom_iommu_map()`.

It meets stable rules: real bug, user-visible DMA failure, surgical
change, no new API, no prerequisites. Benefit outweighs the tiny race
window and lack of a field report.

---

## Verification
- [Phase 1] Parsed tags: Reviewed-by Konrad Dybcio; SOB Mukesh Ojha +
  Will Deacon; no Fixes/Reported-by/Cc-stable
- [Phase 2] Diff: 2+/3- in `qcom_iommu_init_domain()`; move `pgtbl_ops`
  store before `mutex_unlock`
- [Phase 2] Confirmed `map()` NULL-checks ops and returns `-ENODEV`;
  `init_domain` early-outs on `qcom_domain->iommu`
- [Phase 3] `git blame`: unlock-then-assign from `0ae349a0f33fb`
  (v4.14-rc1, Rob Clark)
- [Phase 3] No Fixes tag; leak fix `3c748a5554f96` is independent
- [Phase 3] `git merge-base --is-ancestor a05b67cd45ad0 HEAD` → yes
  (already in this 7.3-rc4 checkout)
- [Phase 3] `git describe a05b67cd45ad0` → `v7.2-rc2-7-ga05b67cd45ad0`
- [Phase 4] `b4 dig -c a05b67cd45ad0`: v2 5/6 at
  patch.msgid.link/20260717144608.3216274-6-…
- [Phase 4] `b4 dig -a`: v1 5/8 (2026-06-23) → v2 5/6 (2026-07-17); this
  hunk unchanged
- [Phase 4] `b4 dig -w`: iommu maintainers + linux-arm-msm Cc’d
- [Phase 4] Konrad v1 review: R-b; optional `guard(mutex)` suggestion
  only; Will applied v2
- [Phase 4] lore.kernel.org WebFetch 403; used b4 mbox instead
- [Phase 4] stable@ search: this commit not discussed; unrelated arm-
  smmu-qcom hits
- [Phase 5] Callers: only `qcom_iommu_attach_dev` ← IOMMU `.attach_dev`
  ← `__iommu_attach_device`
- [Phase 5] `ARM_DMA_USE_IOMMU` / `arm_iommu_attach_device()` allows
  shared mappings across devices
- [Phase 5] semcode unavailable; used git grep + file reads
- [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`; `make
  kernelversion` = 7.3.0-rc4
- [Phase 6] Current file already has assignment before unlock (this
  commit)
- [Phase 7] DT: msm8916/8937/8939/8953/8976 use `qcom,msm-iommu-v1/v2`
- [Phase 8] Failure: `-ENODEV` on valid map, severity HIGH; not oops
- UNVERIFIED: production reproduction; exact share-mapping frequency on
  qcom boards

The fix is small, surgical, and meets the stable criteria for this
tree’s Qualcomm IOMMU driver.

**YES**

 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 792585321bd11..1a046122fca0d 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -306,13 +306,12 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 		ctx->domain = domain;
 	}
 
-	mutex_unlock(&qcom_domain->init_mutex);
-
 	/* Publish page table ops for map/unmap */
 	qcom_domain->pgtbl_ops = pgtbl_ops;
 
-	return 0;
+	mutex_unlock(&qcom_domain->init_mutex);
 
+	return 0;
 out_clear_iommu:
 	qcom_domain->iommu = NULL;
 out_unlock:
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (6 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
                   ` (40 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Prashant Rahul, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Prashant Rahul <prashantrahul23@gmail.com>

[ Upstream commit 4361f1660101270611eb5dc39799f620b35f2e4d ]

The ownership of sk_buff skb is passed to mt7921_queue_rx_skb, each
path inside it under the switch case handles cleaning of skb and it
is true for mt7921_mcu_rx_event as well.

mt7921_mcu_rx_event, on a success path, either queues skb via
mt76_mcu_rx_event or cleans it immediately inside
mt7921_mcu_uni_rx_unsolicited_event.

However inside mt7921_mcu_rx_event, if skb_linearize fails, the function
returns immediately and never bothers cleaning skb which leaks skb.

Since skb is fully owned at this point, it is safe to call
dev_kfree_skb which fixes the leak.

Granted, the skb_linearize failure is rare as it can only fail under
heavy memory usage, but at the same time, leaking memory under heavy
memory usage can worsen the OOM condition.

Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>
Link: https://patch.msgid.link/20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

# Stable backport analysis: mt7921 MCU RX skb leak

**Tree decided:** `pending-6.6` (6.6.157), SHA `04810563abb71`.
At the start of this evaluation `git describe`/`make kernelversion`
reported **6.6.157**. The working copy later moved to v7.3-rc4; every
presence/absence claim below was rechecked against **`pending-6.6`**,
not that later checkout.

The candidate is mainline `4361f16601012` (`wifi: mt76: mt7921: fix
memory leak when skb_linearize fails in mcu rx event`).

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1 — Subject**
Record: **[wifi: mt76: mt7921]** **[fix]** memory leak when
`skb_linearize` fails in MCU RX event.

**Step 1.2 — Tags**
- `Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>` (author)
- `Link: https://patch.msgid.link/20260716-mt7921-mem-
  leak-v1-1-6e9c0ea19f63@gmail.com`
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer;
  applied the patch)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence of Fixes/Cc-stable is expected for this
  review).
Record: Maintainer SOB; msgid shows **v1 patch 1/1** (standalone).

**Step 1.3 — Body**
Record:
- **Bug:** `mt7921_queue_rx_skb` transfers skb ownership into
  `mt7921_mcu_rx_event`. Success paths free or queue the skb. If
  `skb_linearize()` fails, the function returns without freeing.
- **Symptom:** skb leak. Author notes failure is rare (ENOMEM) but
  leaking under memory pressure can worsen OOM.
- **Root cause:** missing `dev_kfree_skb` on the linearize error path.
- **Version info in message:** none.

**Step 1.4 — Hidden bug fix?**
Record: **No disguise.** This is an explicit leak fix, not cleanup-as-
fix.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1 — Inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7921/mcu.c` (**+3 / −1**)
- Function: `mt7921_mcu_rx_event`
- Scope: **single-file surgical fix**

**Step 2.2 — Flow**
Before (pending-6.6 `mcu.c:312-313`):

```
if (skb_linearize(skb))
    return;
```

After:

```
if (skb_linearize(skb)) {
    dev_kfree_skb(skb);
    return;
}
```

Record: **error path only.** Success paths unchanged.

**Step 2.3 — Bug mechanism**
Record: **[resource leak]** On `skb_linearize` failure (`-ENOMEM` for
nonlinear skbs), the still-owned skb is dropped. Caller
`mt7921_queue_rx_skb` does not free after `PKT_TYPE_RX_EVENT`. Other
switch arms in the same caller (`dev_kfree_skb` / `napi_consume_skb`)
and other arms of `mt7921_mcu_rx_event` (`dev_kfree_skb`,
`mt76_mcu_rx_event` queue) already consume the skb.

**Step 2.4 — Fix quality**
Record: **Obviously correct.** Matches established kernel pattern (`if
(skb_linearize(skb)) { dev_kfree_skb(_any)(skb); return; }`). Same free
helper already used in this MCU event path. No API/lock/data-structure
change. Regression risk: **very low** (could only be a double-free if
linearize already freed; it does not — see Phase 5).

---

## PHASE 3: GIT HISTORY

**Step 3.1 — Blame**
Record: Leak introduced by **`f0ff5d3aa64812`** (`mt76: mt7921: make all
event parser reusable between mt7921s and mt7921e`, Sean Wang,
2021-10-19). That commit added `skb_linearize` + early return and never
freed on failure. Present since ~5.16-era; **`git merge-base --is-
ancestor f0ff5d3aa64812 pending-6.6` succeeds.**

**Step 3.2 — Fixes: tag**
Record: **None.** Introducer identified by blame: `f0ff5d3aa64812`,
which **is** in this 6.6 tree.

**Step 3.3 — File history (pending-6.6)**
Recent 6.6 work on this file is CLC firmware validation, not MCU RX. No
competing leak fix. Record: **standalone**; not part of a multi-patch
series.

**Step 3.4 — Author**
Prashant Rahul has **no other commits** in this tree’s mt76 history.
Applied by **Felix Fietkau**, listed maintainer of MEDIATEK MT76 in
`MAINTAINERS`. Record: one-off contributor; **maintainer-applied**.

**Step 3.5 — Dependencies**
The hunk only needs `mt7921_mcu_rx_event` + `skb_linearize` +
`dev_kfree_skb`, all present. Mailing-list patch context matches 6.6
(the extra `MCU_EVENT_RSSI_NOTIFY` in later mainline is **below** the
change). Record: **applies standalone**.

---

## PHASE 4: MAILING LIST / EXTERNAL

**Step 4.1 — Original discussion**
- `b4 dig -c <msgid>` / `b4 mbox`: no match (404).
- lore.kernel.org: **403**.
- Recovered from Openwall and Ratatoskr:
  https://lists.openwall.net/linux-kernel/2026/07/16/1707
  msgid `20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com`
Record: **v1, single patch**, applied as submitted (`4361f16601012`
matches that diff). No v2/v3.

**Step 4.2 — Recipients (`b4 dig -w` unavailable; headers from
Openwall)**
To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang
(mt76 maintainers/reviewers), plus MediaTek ARM contacts. Cc: linux-
wireless, linux-kernel, linux-mediatek, linux-arm-kernel. Record:
**correct maintainer set**.

**Step 4.3 — Bug report**
Record: **No syzbot/bugzilla.** Static ownership analysis; author states
the leak is rare.

**Step 4.4 — Series**
Record: **1/1 standalone.** No sibling mt7925/mt7915 patches required
for this tree (only mt7921 has this `skb_linearize` in pending-6.6).

**Step 4.5 — Stable list**
Search for this subject on lore stable returned unrelated hits. Record:
**no prior stable NAK found** (lore 403 limited this).

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1 — Functions**
Record: `mt7921_mcu_rx_event` only.

**Step 5.2 — Callers**
`mt7921_queue_rx_skb()` (`mac.c`) `case PKT_TYPE_RX_EVENT:` calls it and
does **not** free afterwards.

That `rx_skb` hook is registered for **PCIe, USB, and SDIO**:
- `mt7921/pci.c`, `usb.c`, `sdio.c` → `.rx_skb = mt7921_queue_rx_skb`
- Invoked from `mt76_dma_rx_process` (NAPI), `mt76u` USB RX,
  `mt76s_process_rx_queue` (SDIO)

Record: **hot RX path** for MT7921E/S/U.

**Step 5.3 — Callees**
`skb_linearize` → `__skb_linearize` → `__pskb_pull_tail`; returns
`-ENOMEM` on failure and **does not free** the skb
(`include/linux/skbuff.h`: “If there is no free memory -ENOMEM is
returned”). Success continues to `mt7921_mcu_uni_rx_unsolicited_event` /
`mt76_mcu_rx_event` / `mt7921_mcu_rx_unsolicited_event`.

**Step 5.4 — Reachability**
Nonlinear MCU events are real:
- SDIO `mt76s_build_rx_skb` uses `skb_add_rx_frag` when payload >
  `MT_SKB_HEAD_LEN` — this is **why** `f0ff5d3aa64812` added linearize
  (“paged fragment skb for the SDIO device”).
- USB `mt76u_build_rx_skb` same pattern.
- DMA `mt76_add_fragment` builds fraglists for multi-buffer RX.

Record: reachable from normal firmware MCU events; unprivileged users
can generate MCU traffic by using WiFi. Failure needs **ENOMEM during
linearize**.

**Step 5.5 — Similar patterns**
In pending-6.6, `skb_linearize` appears **only here** under mt76. No
duplicate site left unfixed in this tree.

---

## PHASE 6: LOCAL TREE (pending-6.6 / 6.6.157)

**Step 6.1 — Buggy code present?**
Record: **Yes.**
`pending-6.6:drivers/net/wireless/mediatek/mt76/mt7921/mcu.c:312-313`:

```
if (skb_linearize(skb))
    return;
```

`git merge-base --is-ancestor 4361f16601012 pending-6.6` → **false**
(fix not here).
`git merge-base --is-ancestor f0ff5d3aa64812 pending-6.6` → **true**
(bug intro is here).
Bug age: **2021**, well before 6.6.

**Step 6.2 — Backport difficulty**
Submitted hunk is 4 lines around `skb_linearize` with context that
matches 6.6 (`struct mt76_connac2_mcu_rxd *rxd` then the if).
`MCU_EVENT_RSSI_NOTIFY` is later mainline-only context **below** the
edit. Record: **clean apply / trivial**.

**Step 6.3 — Related fixes already here?**
`git log --grep=skb_linearize` on mt76 in this tree: **empty**. No
alternate fix. Record: **none**.

---

## PHASE 7: SUBSYSTEM CONTEXT

**Step 7.1**
Record: **wifi / mt76 / mt7921**. Criticality: **IMPORTANT** — MT7921E
is a common laptop WiFi 6 adapter (PCIe); USB/SDIO variants exist
(`MT7921E/S/U` in Kconfig). Not core mm/net, not staging.

**Step 7.2**
Record: Mature driver (MCU support from `1c099ab44727c8`, 2021). 6.6
still receives mt76 bugfixes (CLC, etc.).

---

## PHASE 8: IMPACT AND RISK

**Step 8.1 — Who is affected**
Record: **driver-specific**, users with MediaTek MT7921 (very common on
laptops). Config: `CONFIG_MT7921E/S/U`.

**Step 8.2 — Trigger**
Record: Firmware MCU RX event whose skb is nonlinear, **and**
`skb_linearize` fails (GFP/ENOMEM). Unprivileged WiFi use can generate
events; the failure itself is **uncommon**. SDIO long events are the
originally cited nonlinear case; USB/DMA can also fragment.

**Step 8.3 — Failure mode**
Record: **skb leak under memory pressure**, which can deepen OOM. Not a
panic/UAF. Severity: **MEDIUM–HIGH** (hot-path leak, not a one-time
probe leak).

**Step 8.4 — Risk/benefit**
- Benefit: **medium** — stops a real leak on a widely shipped chip; most
  valuable when the system is already under memory pressure.
- Risk: **very low** — 3 lines, error path, same free as sibling paths.
- Ratio: **favor backport**.

---

## PHASE 9: SYNTHESIS

**Step 9.1 — Evidence**

**For:**
- Real leak with verified ownership (caller does not free).
- Code and introducer are in 6.6.157; fix is not.
- Tiny, obviously correct, maintainer-applied.
- MT7921 is production hardware, not staging.
- Leak on an RX path under OOM is a stability issue, not a style
  cleanup.

**Against:**
- Trigger is rare (`skb_linearize` ENOMEM).
- No crash/syzbot/CVE.
- No explicit `Cc: stable` (not a negative per the review rules).

**Unresolved:** Full lore thread (403/404); no reviewer comments beyond
maintainer merge. Does not change the technical verdict.

**Step 9.2 — Stable rules**
1. Obviously correct and tested — **PASS** (3-line ownership fix; in
   mainline via Felix).
2. Real bug affecting users — **PASS** (skb leak on MT7921 MCU RX).
3. Important (crash/security/corruption/deadlock) — **PASS** as an RX-
   path leak that can worsen OOM; not a panic, but in the leak class
   stable regularly takes.
4. Small and contained — **PASS** (4 lines, one function).
5. No new features/APIs — **PASS**.
6. Can apply to this tree — **PASS** (hunk matches 6.6).

**Step 9.3 — Exceptions**
Record: none needed (not an ID/quirk/DT/build/doc exception). Ordinary
small leak fix.

**Step 9.4 — Decision**
Backport to **this** 6.6.157 tree. The bug exists here, the fix is
surgical, and regression risk is negligible.

---

## What the commit solves for stable users

On MT7921, firmware MCU events are handed to `mt7921_mcu_rx_event` with
full skb ownership. Nonlinear events (especially SDIO, also USB/DMA
fragments) are linearized first. If that allocation fails, 6.6 returns
and leaks the skb. Under memory pressure that leak makes OOM worse.
Adding `dev_kfree_skb(skb)` on that path closes the leak without
changing success behavior.

## Risk vs benefit

Benefit is a real leak fix on a common WiFi chip; risk is a three-line
error-path free that matches existing code in the same function.

## Concerns

None material: no prerequisites, no API change, no locking, expected
clean apply. Trigger rarity is the only weak point and is not enough to
reject a contained leak fix.

---

## Verification

- **[Phase 1]** Parsed tags: author SOB, Link msgid, Felix Fietkau SOB;
  no Fixes/Reported-by/Cc-stable.
- **[Phase 2]** Diff: +3/−1 in `mt7921_mcu_rx_event`; adds
  `dev_kfree_skb` on `skb_linearize` failure.
- **[Phase 3]** `git blame` on pending-6.6: leak from `f0ff5d3aa64812`
  (2021-10-19); `git merge-base --is-ancestor f0ff5d3aa64812
  pending-6.6` true.
- **[Phase 3]** `git show f0ff5d3aa64812`: added `if
  (skb_linearize(skb)) return;` with no free.
- **[Phase 3]** `git log --author=Prashant Rahul`: no other mt76 commits
  in this history.
- **[Phase 4]** Openwall/Ratatoskr: v1 1/1, same diff as
  `4361f16601012`; mt76 maintainers on To:.
- **[Phase 4]** `b4 mbox` msgid: 404; lore.kernel.org: 403.
  **UNVERIFIED:** full review replies / explicit stable nomination.
- **[Phase 5]** Callers: `mt7921_queue_rx_skb` (no free on
  `PKT_TYPE_RX_EVENT`); hooked from pci/usb/sdio `.rx_skb`.
- **[Phase 5]** `skb_linearize` documented to return `-ENOMEM` and not
  free; USB/SDIO `skb_add_rx_frag` makes nonlinear skbs.
- **[Phase 6]** `git describe` at start: `p-6.6-3-g04810563abb71`, `make
  kernelversion` 6.6.157.
- **[Phase 6]** `git grep` on `pending-6.6`: leak at `mcu.c:312-313`.
- **[Phase 6]** `git merge-base --is-ancestor 4361f16601012 pending-6.6`
  false.
- **[Phase 8]** Failure mode: skb leak under ENOMEM on MCU RX; severity
  MEDIUM–HIGH.
- **UNVERIFIED:** complete lore thread text after 403.

The fix is small, matches stable leak-fix practice, and the buggy code
is in this 6.6 tree.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 8c8b35cba856c..f63ef02542387 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -354,8 +354,10 @@ void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb)
 {
 	struct mt76_connac2_mcu_rxd *rxd;
 
-	if (skb_linearize(skb))
+	if (skb_linearize(skb)) {
+		dev_kfree_skb(skb);
 		return;
+	}
 
 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (7 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
                   ` (39 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 0b8d2524716099ea4743fa65bc364f94b3106a31 ]

When the driver implements .release_buffered_frames, mac80211 leaves the
U-APSD signalling entirely to the driver: "In this case it is also
responsible for setting the EOSP flag in the QoS header of the frames"
(include/net/mac80211.h). Only IEEE80211_TX_STATUS_EOSP was being set,
which merely ends the service period inside mac80211, so on air the
service period was never terminated. Clients that wait for EOSP before
going back to doze keep the SP open and stop triggering, which stalls all
downlink traffic for that station.

Set the wire EOSP bit on the last frame of a U-APSD service period.
EOSP has no meaning for a PS-Poll response, so pass the release reason
down and leave those frames alone.

Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a real U-APSD protocol bug in mt76 that already exists in this
5.15.221 tree. The fix is small, applies here, and is independent of the
rest of the series.

## Phase 1: Commit message forensics

**Step 1.1 — subject**
Record: `[wifi: mt76:]` `[set]` set the EOSP bit in the QoS header of
the last released frame. “Set” here is a protocol-correctness fix, not a
feature add.

**Step 1.2 — tags**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name`
  (linux-wireless, series 04/10)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer; Sasha
  Levin SOB ignored per instructions)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
  stable` (absence is expected)

Mainline SHA (from `origin/master`, path-limited log):
`0b8d2524716099ea4743fa65bc364f94b3106a31`. First containing tag:
`v7.3-rc1`. Not an ancestor of this HEAD.

**Step 1.3 — body**
Record:
- **Bug:** `.release_buffered_frames` means mac80211 does not set the
  on-air EOSP bit; the driver must. mt76 only set
  `IEEE80211_TX_STATUS_EOSP` (ends the SP inside mac80211).
- **Symptom:** U-APSD clients that wait for EOSP never see it, keep the
  service period open, stop triggering, **all downlink for that STA
  stalls**.
- **Root cause:** missing `IEEE80211_QOS_CTL_EOSP` on the last QoS frame
  of a U-APSD SP. PS-Poll must not get EOSP.
- **Version info:** none in the message. Buggy code dates to 2017.

**Step 1.4 — hidden fix?**
Record: Not hidden. Explicit protocol/connectivity fix.

## Phase 2: Diff analysis

**Step 2.1 — inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/tx.c` (`+12 / -4`)
- Functions: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`
- Scope: single-file surgical change. `mt76_queue_ps_skb` is static;
  exported `mt76_release_buffered_frames` signature already has
  `reason`.

**Step 2.2 — flow**
Record:
- Before: last PS-release frame gets `IEEE80211_TX_STATUS_EOSP |
  IEEE80211_TX_CTL_REQ_TX_STATUS` and More Data cleared. QoS Control on
  the wire is untouched.
- After: same flags, plus if `reason == IEEE80211_FRAME_RELEASE_UAPSD`
  and the frame is QoS data, OR `IEEE80211_QOS_CTL_EOSP` into the QoS
  control field. `reason` is passed through both call sites.
- Path: U-APSD/PS-Poll release via `.release_buffered_frames`, not the
  normal TX burst path.

**Step 2.3 — bug mechanism**
Record: **Logic / protocol correctness.** mac80211’s own release path
(`net/mac80211/sta_info.c`) does `*qoshdr |= IEEE80211_QOS_CTL_EOSP` for
U-APSD. Drivers that implement `.release_buffered_frames` must do the
same (`include/net/mac80211.h`). mt76 did not.

**Step 2.4 — quality**
Record: Obviously correct and aligned with mac80211. Guards match the
docs (U-APSD only; QoS data only). skb is exclusively owned after
`ieee80211_tx_dequeue`. Header at `skb->data` matches existing
`mt76_skb_set_moredata()`. Regression risk is low: PS-Poll unchanged;
non-QoS last frames still lack wire EOSP (mac80211 already assumes
drivers mostly buffer QoS-data, or add a QoS-Null themselves). Pre-
existing unused `more_data` parameter is not changed.

## Phase 3: Git history

**Step 3.1 — blame**
Record: `mt76_queue_ps_skb` / `mt76_release_buffered_frames` introduced
in `17f1de56df0512` (“mt76: add common code…”, 2017-12-07,
**v4.16-rc1**). `IEEE80211_TX_STATUS_EOSP` added in `7267a7965dd7b`
(2018). Present for the entire 5.15 lifetime.

**Step 3.2 — Fixes: tag**
Record: None. Introducer is `17f1de56df0512`, which **is** in this tree.

**Step 3.3 — related file history**
Record: Recent 5.15 `tx.c` work is unrelated (locking, UAF, queue id).
This tree already has U-APSD AP support: `b807b368c4f9b` (mt76 AP
U-APSD), `4bf04d33f5b7e` (mt7915). No earlier EOSP-on-wire fix.

**Step 3.4 — author**
Record: Felix Fietkau is listed in `MAINTAINERS` as mt76 maintainer.
Sibling series patch 05 (`697badc27a9b3`, mt7603 U-APSD termination) is
a separate chip-specific fix, not a prerequisite.

**Step 3.5 — prerequisites**
Record: Series is **01–10**, but 04 does **not** depend on 01–03. Patch
01 (`a547b414bf7ea`) changes `mt76_txq_send_burst` / HW TIM buffering
and does not touch `mt76_queue_ps_skb`. 02/03/09/10 are
mt7915/mt7996/MLO (mt7996 is not in 5.15). 05–08 are mt7603-only. 04 is
standalone. All helpers used (`ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `IEEE80211_QOS_CTL_EOSP`,
`IEEE80211_FRAME_RELEASE_UAPSD`) exist in this tree via `mt76.h` →
`<net/mac80211.h>` / `ieee80211.h`.

## Phase 4: Mailing list / external

**Step 4.1 — original discussion**
Record: `b4 dig -c 0b8d252471609` →
https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
`b4 dig -a`: single **v1** series, 2026-08-01. Applied version is that
v1. Thread has the 10 patches plus a kernel-test-robot build error on
**10/10** (`ieee80211_txq_aql_pending` / patch 01), **not** on 04. No
NAK, no reviewer concern about EOSP. Merged via `wireless-
next-2026-08-06` into `v7.3-rc1`.

**Step 4.2 — recipients (`b4 dig -w`)**
Record: Felix Fietkau, `linux-wireless@vger.kernel.org`. Maintainer-
authored self-merge; no extra Reviewed-by. Normal for mt76.

**Step 4.3 — bug report**
Record: No syzbot/bugzilla. The series commit messages describe a
concrete on-air failure (clients waiting for EOSP). Unverified: no
public user stack trace beyond the author’s analysis.

**Step 4.4 — series context**
Record: 04 is the common-path EOSP fix. 05 is the mt7603 driver-PS-queue
analogue. Taking 04 without 05 still fixes mac80211-buffered frames on
**all** chips that use `mt76_release_buffered_frames` (mt76x0/x2,
mt7615, mt7915, mt7921, and mt7603’s fallback).

**Step 4.5 — stable list**
Record: `lore.kernel.org/stable/?q=mt76+EOSP+QoS` → **No results
found**. No recorded reason to skip it.

## Phase 5: Semantic / call graph

**Step 5.1 — functions**
Record: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`.

**Step 5.2 — callers**
Record: `mt76_queue_ps_skb` only from `mt76_release_buffered_frames`.
That is `.release_buffered_frames` for mt76x0, mt76x2, mt7615, mt7915,
mt7921; mt7603 wraps it after draining `msta->psq`. mac80211 calls it
from `ieee80211_sta_ps_deliver_response()` →
`drv_release_buffered_frames()`.

**Step 5.3 — callees**
Record: `IEEE80211_SKB_CB`, `ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `mt76_skb_set_moredata`, `__mt76_tx_queue_skb`.
No new locks/allocs.

**Step 5.4 — reachability**
Record: Yes, from the air. AP RX of a U-APSD trigger
(`ieee80211_sta_uapsd_trigger` in `mac80211.c` / `rx.c`) →
`ieee80211_sta_ps_deliver_uapsd` → driver release. This tree sets
`WIPHY_FLAG_AP_UAPSD`. Typical trigger: a phone associated to an mt76
AP.

**Step 5.5 — similar patterns**
Record: mac80211 `sta_info.c` uses the same `*qoshdr |=
IEEE80211_QOS_CTL_EOSP`. Sibling mt7603 patch 05 does the same for TXD-
prefixed PS-queue frames (`skb->data[MT_TXD_SIZE]`). Common-path frames
from `ieee80211_tx_dequeue` have the 802.11 header at `skb->data` (same
as `mt76_skb_set_moredata`).

## Phase 6: This tree (5.15.221)

**Step 6.1 — buggy code present?**
Record: **Yes.** `drivers/net/wireless/mediatek/mt76/tx.c`
`mt76_queue_ps_skb()` (lines 344–358) sets only
`IEEE80211_TX_STATUS_EOSP`, not the QoS EOSP bit. Introduced v4.16;
U-APSD AP enabled here since 2020.

`git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`. `make kernelversion`:
**5.15.221**. `git merge-base --is-ancestor 0b8d252471609 HEAD` → **not
present**.

**Step 6.2 — backport difficulty**
Record: **Clean apply.** `git apply --check` succeeded; hunks applied at
offset −69 only because `mt76_txq_dequeue` still uses
`MT_TX_HW_QUEUE_EXT_PHY` here vs `FIELD_PREP(MT_TX_HW_QUEUE_PHY, …)`
upstream. That function is context, not part of the change.

**Step 6.3 — related fixes already here?**
Record: No. Only `7267a7965dd7b` (TX status for the software EOSP flag),
which is exactly the incomplete behavior this commit finishes.

## Phase 7: Subsystem

**Step 7.1**
Record: `drivers/net/wireless/mediatek/mt76` — Wi-Fi driver.
**IMPORTANT** (not core kernel, but widely used: OpenWrt/home routers,
mt76x0/x2/7603/7615/7915/7921).

**Step 7.2**
Record: Mature driver; this PS-release path has been stable since 2017.
Not a bug in brand-new code.

## Phase 8: Impact and risk

**Step 8.1 — who**
Record: Driver/config-specific: `CONFIG_MT76*` AP mode with U-APSD
clients. Large real-world set (MediaTek AP SoCs).

**Step 8.2 — trigger**
Record: Associated STA in power-save using U-APSD (typical phones) sends
a trigger; AP releases buffered QoS data. Not a rare error path.
Unprivileged on the air (associated client). PS-Poll-only clients are
unaffected by the new bit.

**Step 8.3 — failure mode**
Record: **Station downlink stall** until the client gives up the SP. Not
a kernel oops. Severity: **HIGH** (loss of connectivity for that STA),
not CRITICAL (no panic/corruption).

**Step 8.4 — risk/benefit**
Record: Benefit high for mt76 AP + U-APSD clients. Risk very low: ~12
lines, QoS bit only on last U-APSD QoS-data frame, same pattern as
mac80211, clean apply, no API/struct change. Patch 01’s
`ieee80211_txq_aql_pending` is **not** required.

## Phase 9: Synthesis

**Step 9.1 — evidence**

For:
- Real, documented 802.11 bug: missing on-air EOSP → downlink stall
- Code and AP U-APSD flag exist in 5.15.221
- Bug since v4.16
- Maintainer-authored, merged to mainline (`v7.3-rc1`), no revert, no
  later rewrite of this function
- 12 insertions / 4 deletions, clean apply
- Matches mac80211
- Standalone despite 04/10 numbering

Against:
- Not crash/security/corruption
- No `Reported-by` / syzbot
- No extra reviewer
- mt7603 hardware PS-queue still wrong without patch 05 (does not make
  04 incorrect or unusable)

Unresolved: no independent end-user report found beyond the maintainer’s
analysis.

**Step 9.2 — stable rules**
1. Obviously correct and tested? **PASS** — same as mac80211; in
   mainline since v7.3-rc1
2. Real bug affecting users? **PASS** — U-APSD clients on mt76 APs
3. Important? **PASS** — full downlink stall for the STA (HIGH)
4. Small/contained? **PASS** — one file, ~12 lines
5. No new features/APIs? **PASS** — sets a standard 802.11 bit the
   driver was already required to set
6. Applies to this tree? **PASS** — `git apply --check` clean

**Step 9.3 — exceptions**
Record: None (not an ID/quirk/DT/build/doc exception). Qualifies as a
normal bugfix.

**Step 9.4 — decision**
This 5.15.221 tree has the buggy path, U-APSD AP support, and every API
the patch needs. The change is a small, self-contained protocol fix for
a serious AP-mode connectivity failure. It should be backported here.

---

### What it solves for 5.15 users
On MediaTek mt76 APs, U-APSD service periods never get the EOSP bit on
the last released QoS frame. mac80211 thinks the SP ended
(`IEEE80211_TX_STATUS_EOSP`), but the client never sees EOSP on the air,
stops triggering, and **downlink to that station stalls**. Setting
`IEEE80211_QOS_CTL_EOSP` on the last U-APSD QoS-data frame is what
mac80211 already documents and implements when the driver does not take
`.release_buffered_frames`.

### Stable rules / risk
Meets all six criteria. Benefit is restoring buffered downlink for
U-APSD clients; risk is a one-bit header update on a path that already
rewrites More Data. No series dependencies for this hunk. mt7603’s
separate PS-queue EOSP bug is a sibling, not a blocker.

### Verification
- [Phase 1] Parsed tags: Link to 04/10, author SOB only; no
  Fixes/Reported-by/Cc:stable
- [Phase 1] `git log origin/master --grep='set the EOSP bit' --
  drivers/net/wireless/mediatek/mt76/`: `0b8d252471609`
- [Phase 1] `git describe --contains --match 'v*' 0b8d252471609`:
  `v7.3-rc1~133^2~99^2~15^2~8`
- [Phase 2] Diff: `mt76_queue_ps_skb` + `reason`; EOSP OR on last U-APSD
  QoS-data frame; two call sites
- [Phase 2] Compared to `net/mac80211/sta_info.c:1708` (`*qoshdr |=
  IEEE80211_QOS_CTL_EOSP`) — same mechanism
- [Phase 2] Confirmed `include/net/mac80211.h` requires the driver to
  set EOSP when `.release_buffered_frames` is implemented
- [Phase 3] `git blame` on `tx.c` 345–403: introduced `17f1de56df0512`
  (v4.16-rc1)
- [Phase 3] `git log --grep='EOSP' --
  drivers/net/wireless/mediatek/mt76/`: only TX-status EOSP
  (`7267a7965dd7b`) in this tree
- [Phase 3] Patch 01 `a547b414bf7ea` does not touch `mt76_queue_ps_skb`
  (not a prerequisite)
- [Phase 4] `b4 dig -c 0b8d252471609`: lore URL above; `b4 dig -a`: v1
  only; `b4 dig -w`: linux-wireless + author
- [Phase 4] 11-message mbox: no NAK on 04; kbuild error is on 10/10 /
  patch 01
- [Phase 4] `curl` stable lore for `mt76 EOSP QoS`: no results
- [Phase 5] Callers: mt76x0/x2, mt7615, mt7915, mt7921 ops; mt7603
  wrapper; mac80211 `drv_release_buffered_frames`
- [Phase 5] This tree: `WIPHY_FLAG_AP_UAPSD` and
  `ieee80211_sta_uapsd_trigger` in `mt76/mac80211.c`
- [Phase 6] `git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`; `make
  kernelversion`: 5.15.221
- [Phase 6] `git merge-base --is-ancestor 0b8d252471609 HEAD`: not in
  tree
- [Phase 6] `git apply --check` of 04/10: success, offset −69
- [Phase 6] APIs present: `IEEE80211_QOS_CTL_EOSP` `0x0010`,
  `ieee80211_get_qos_ctl`, `ieee80211_is_data_qos`,
  `IEEE80211_FRAME_RELEASE_UAPSD`
- [Phase 8] Failure mode: STA downlink stall (HIGH), not oops
- UNVERIFIED: no independent user bugzilla/syzbot report; impact
  inferred from protocol + maintainer description

**YES**

 drivers/net/wireless/mediatek/mt76/tx.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 731caeda72b52..93275bb692fa5 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -415,16 +415,23 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
 
 static void
 mt76_queue_ps_skb(struct mt76_phy *phy, struct ieee80211_sta *sta,
-		  struct sk_buff *skb, bool last)
+		  struct sk_buff *skb, bool last,
+		  enum ieee80211_frame_release_type reason)
 {
 	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
-	if (last)
+	if (last) {
 		info->flags |= IEEE80211_TX_STATUS_EOSP |
 			       IEEE80211_TX_CTL_REQ_TX_STATUS;
 
+		if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
+		    ieee80211_is_data_qos(hdr->frame_control))
+			*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+	}
+
 	mt76_skb_set_moredata(skb, !last);
 	__mt76_tx_queue_skb(phy, MT_TXQ_PSD, skb, wcid, sta, NULL);
 }
@@ -457,14 +464,15 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
 
 			nframes--;
 			if (last_skb)
-				mt76_queue_ps_skb(phy, sta, last_skb, false);
+				mt76_queue_ps_skb(phy, sta, last_skb, false,
+						  reason);
 
 			last_skb = skb;
 		} while (nframes);
 	}
 
 	if (last_skb) {
-		mt76_queue_ps_skb(phy, sta, last_skb, true);
+		mt76_queue_ps_skb(phy, sta, last_skb, true, reason);
 		dev->queue_ops->kick(dev, hwq);
 	} else {
 		ieee80211_sta_eosp(sta);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (8 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
                   ` (38 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Vladimir Murzin, Paul E. McKenney, Mark Rutland, Steven Rostedt,
	Sasha Levin, chunfeng.yun, gregkh, linux-usb, linux-arm-kernel,
	linux-mediatek, linux-kernel

From: Vladimir Murzin <vladimir.murzin@arm.com>

[ Upstream commit cfb3293c4573289f11f913611f530ea6b1926d67 ]

Paul reported kernel splat:

[    0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_set_halt has double dereference in TP_printk: &REC->gpd_ring->dma
[    0.000000] ------------[ cut here ]------------
[    0.000000] Event mtu3_gadget_ep_set_halt has double dereference in TP_printk: &REC->gpd_ring->dma
[    0.000000] WARNING: kernel/trace/trace_events.c:420 at test_double_dereference+0x144/0x14c, CPU#0: swapper/0/0
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc1 #15247 PREEMPT
[    0.000000] Hardware name: linux,dummy-virt (DT)
[    0.000000] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    0.000000] pc : test_double_dereference+0x144/0x14c
[    0.000000] lr : test_double_dereference+0x144/0x14c
[    0.000000] sp : ffffc80aa7633bf0
[    0.000000] x29: ffffc80aa7633bf0 x28: ffffc80aa7c0f047 x27: 000508b58019388f
[    0.000000] x26: 0000000000000003 x25: 0000000000000007 x24: ffffc80aa5fceff8
[    0.000000] x23: ffffc80aa7c0f05a x22: ffffc80aa64edfe8 x21: ffffc80aa7c0fce8
[    0.000000] x20: ffffc80aa7c0f047 x19: 0000000000000013 x18: 0000000000000001
[    0.000000] x17: 6572656420656c62 x16: 756f642073616820 x15: 746c61685f746573
[    0.000000] x14: 0000000000000000 x13: ffff000139d90000 x12: 0000000000000045
[    0.000000] x11: 00000000000000cf x10: ffff00013f546428 x9 : ffff000139d90000
[    0.000000] x8 : 3fffffffffffc000 x7 : 0000000000000001 x6 : 0000000000000001
[    0.000000] x5 : ffff00013f4e6440 x4 : 0000000000000000 x3 : 0000000000000000
[    0.000000] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffc80aa764a700
[    0.000000] Call trace:
[    0.000000]  test_double_dereference+0x144/0x14c (P)
[    0.000000]  trace_event_raw_init+0x37c/0x5d8
[    0.000000]  event_init+0x34/0xc0
[    0.000000]  trace_event_init+0xec/0x588
[    0.000000]  trace_init+0x24/0x6e0
[    0.000000]  start_kernel+0x4a0/0x8ec
[    0.000000]  __primary_switched+0x88/0x90
[    0.000000] irq event stamp: 0
[    0.000000] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[    0.000000] hardirqs last disabled at (0): [<0000000000000000>] 0x0
[    0.000000] softirqs last  enabled at (0): [<0000000000000000>] 0x0
[    0.000000] softirqs last disabled at (0): [<0000000000000000>] 0x0
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_disable has double dereference in TP_printk: &REC->gpd_ring->dma
[    0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_enable has double dereference in TP_printk: &REC->gpd_ring->dma

Which also observed by Mark and myself.

The splat it result of new check introduced by b5cc230af5e5 ("tracing:
Warn when an event dereferences a pointer in TP_printk()") which
correctly catches issue with %pad dereferencing the address saved in
the ring buffer. TP_fast_assign() logic gets executed when the
tracepoint is triggered, however the TP_printk() is executed when the
user reads the trace buffer which could be seconds, minutes, hours,
days, even months later and nothing guarantee that __entry->gpd_ring
pointer will still be pointing to what it was when it was recorded.

Fix the issue by capturing immediate value of gpd_ring.dma when trace
point is triggered.

Reported-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[usb/mtu3]** **[Fix]** Double dereference in `TP_printk` for
the `mtu3_log_ep` trace class
(`mtu3_gadget_ep_enable/disable/set_halt`).

**Step 1.2: Tags**
Record:
- **Reported-by:** Paul E. McKenney
- **Tested-by:** Mark Rutland
- **Reviewed-by:** Steven Rostedt (tracing maintainer)
- **Signed-off-by:** Vladimir Murzin (author); Paul E. McKenney (merged
  via his tree)
- **No Fixes:** tag (expected for this review)
- **No Cc: stable** (expected)
- No syzbot, no CVE, no bugzilla Link
- Ignore pipeline “Upstream commit” / Sasha Levin SOB

Notable: three independent observers (Paul, Mark, the author). Rostedt
reviewed it.

**Step 1.3: Body**
Record:
- **Bug:** `TP_printk` uses `%pad` with `&REC->gpd_ring->dma`, i.e. it
  follows a pointer stored in the ring buffer when the trace is printed,
  not when it is recorded.
- **Symptom that motivated the patch:** boot `WARNING` in
  `test_double_dereference()` on 7.3.0-rc1 (`linux,dummy-virt`), events
  `mtu3_gadget_ep_set_halt/disable/enable`.
- **Root cause (author):** check added by `b5cc230af5e5` (“tracing: Warn
  when an event dereferences a pointer in TP_printk()”).
  `TP_fast_assign()` runs at the tracepoint; `TP_printk()` can run much
  later, when `__entry->gpd_ring` may be stale.
- **Fix:** snapshot `mep->gpd_ring.dma` into a `dma_addr_t` field at
  assign time and print `&__entry->gpd_ring_dma`.
- **Versions in the message:** 7.3.0-rc1 only. Mailing list later says
  the splat was still present in 7.3-rc5/rc6.

Linus’s merge of `8fc6e594884a` describes the same bug as pre-existing:
it can dump garbage traces because `TP_printk()` may run after the
pointed-to memory is gone. Extra tracing checks only **exposed** it.

**Step 1.4: Hidden bug fix?**
Record: Not hidden. It is an explicit tracing UAF/stale-pointer fix. The
boot WARN is how it was found; the real defect is delayed dereference of
a saved kernel pointer.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/usb/mtu3/mtu3_trace.h` only (+3 / −1; 4-line class)
- Function/class: `DECLARE_EVENT_CLASS(mtu3_log_ep)` (shared by
  `mtu3_gadget_ep_enable`, `mtu3_gadget_ep_disable`,
  `mtu3_gadget_ep_set_halt`)
- Scope: single-file surgical tracing fix

**Step 2.2: Code flow**
Record: **Before:** `TP_fast_assign` stores `__entry->gpd_ring =
&mep->gpd_ring`. `TP_printk` prints `%p/%pad` with `__entry->gpd_ring,
&__entry->gpd_ring->dma`. **After:** also stores `__entry->gpd_ring_dma
= mep->gpd_ring.dma` and prints `&__entry->gpd_ring_dma`. Affected path
is trace **print**, not gadget I/O.

Verified in this tree’s `lib/vsprintf.c` `address_val()`: `%pad` does
`*(const dma_addr_t *)addr`. The old argument therefore both follows
`gpd_ring` and then dereferences `.dma`.

**Step 2.3: Bug mechanism**
Record: **Memory safety / delayed pointer dereference in tracing (UAF or
garbage).** `%p` of the saved pointer is safe; `%pad` is not. `gpd_ring`
is embedded in `struct mtu3_ep` (`mtu3.h`). `mtu3_gpd_ring_free()`
`memset`s the ring on disable; the `mtu3_ep` itself is freed on unbind.
Reading traces after unbind is a use-after-free. Reading after disable
but before unbind can print a later (zeroed) DMA address instead of the
recorded one.

**Step 2.4: Fix quality**
Record: Obviously correct and minimal. `%pad` still gets a `dma_addr_t
*`, now into the ring-buffer entry. The missing semicolon on the new
assign is harmless: `TP_fast_assign` is expanded with a trailing `;`. No
API/locking/hot-path change. Regression risk is very low. The leftover
`__field(struct mtu3_gpd_ring *, gpd_ring)` is still only printed with
`%p`.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: Buggy `mtu3_log_ep` pattern comes from `83374e035b628` (“usb:
mtu3: add tracepoints to help debug”, Chunfeng Yun, 2019-03-21). Present
in this tree (`git merge-base --is-ancestor 83374e035b628 HEAD`
succeeded). Long-lived, not recent code.

**Step 3.2: Fixes: tag**
Record: None on the merged commit. An earlier unused submission
(Shixiong Ou, 2026-08-28) tagged `Fixes: 83374e035b62`. That introducing
commit **is** in this tree.

**Step 3.3: File history**
Record (path-limited log):
- `83374e035b628` add tracepoints
- later style/`__vstring`/`__assign_str` churn
- this fix

Standalone; not patch X/Y. No prerequisite refactor in this file beyond
what 6.18 already has (`__assign_str(name)` without a second argument is
already here).

**Step 3.4: Author**
Record: Vladimir Murzin is not the mtu3 maintainer (that is Chunfeng
Yun, CC’d). He is an ARM engineer fixing a splat he, Paul, and Mark hit.
Rostedt reviewed. Paul merged it when USB maintainers were slow (splat
still in 7.3-rc6).

**Step 3.5: Dependencies**
Record: None. Uses existing `dma_addr_t`, `TP_*`, and
`mep->gpd_ring.dma`. No new tracing helpers. `b5cc230af5e5` is the
detector, **not** a prerequisite for the fix.

---

## Phase 4: Mailing list / external

**Step 4.1: Original discussion**
Record:
- `b4 dig -c cfb3293c4573289f11f913611f530ea6b1926d67` → https://patch.m
  sgid.link/20260922103756.104846-1-vladimir.murzin@arm.com
- `b4 dig -a`: single revision (v1 only)
- Thread: ping for 7.3-rc5/rc6 splat; Paul offered to merge because the
  WARN broke his tests; later merged and Linus pulled it
- No NAK. No reviewer asked for `Cc: stable`
- lore.kernel.org fetch returned 403; thread recovered via `b4 dig -m`

**Step 4.2: Recipients (`b4 dig -w`)**
Record: linux-usb, linux-arm-kernel, linux-mediatek, linux-kernel,
Chunfeng Yun, Greg KH, Steven Rostedt, Paul McKenney, Mark Rutland.
Right lists and maintainers.

**Step 4.3: Bug report**
Record: Reproduced by Paul, Mark, and Vladimir on 7.3-rc1+ (dummy-virt).
Independent earlier patch from Shixiong Ou describes the same WARN and
the same stale-pointer/UAF. Severity for **those** kernels is a boot
WARN whenever `CONFIG_USB_MTU3` is built. That WARN is **not** in
6.18.y.

**Step 4.4: Series**
Record: Standalone. Duplicate independently submitted by Shixiong Ou
(same approach, field named `gpd_dma`). Murzin’s version is what merged.

**Step 4.5: Stable list**
Record: No useful hit on lore stable for this subject. Not a documented
“do not backport.”

---

## Phase 5: Semantic / call graph

**Step 5.1: Functions**
Record: `mtu3_log_ep` class; events `mtu3_gadget_ep_enable`,
`mtu3_gadget_ep_disable`, `mtu3_gadget_ep_set_halt`.

**Step 5.2: Callers**
Record (this tree):
- `mtu3_gadget_ep_enable()` — `drivers/usb/mtu3/mtu3_gadget.c:202`
- `mtu3_gadget_ep_disable()` — line 214 (before `mtu3_ep_disable()` /
  `mtu3_gpd_ring_free()`)
- `mtu3_gadget_ep_set_halt()` — line 404

These are USB gadget ep ops: enable/disable/halt from gadget drivers /
configfs. Common on MediaTek gadget/OTG, not a syscall of its own.

**Step 5.3: Callees**
Record: TRACE_EVENT assign/print only. No alloc/lock/I/O in the changed
code. `%pad` → `address_val()` → dereference `dma_addr_t *`.

**Step 5.4: Reachability**
Record: Recording: gadget ep enable/disable/halt with these events on.
Printing: reading the trace buffer. UAF: print after `mtu3_ep` is freed
(driver unbind). Boot WARN: only if `test_double_dereference()` exists
(it does not here). Unprivileged users normally cannot enable tracefs.

**Step 5.5: Similar patterns**
Record: Other mtu3 events print saved pointers with `%p` only (safe).
Same class already in this 6.18.y tree: `0b0d2f9db2406` (“eth: ice:
don't dereference pointers from TP_printk()”), also written against
`b5cc230af5e5`, and it **is** an ancestor of `v6.18.57`.

---

## Phase 6: This checkout only

**Step 6.1: Does the buggy code exist?**
Record: **Yes, in v6.18.57.** `git describe HEAD` →
`v6.18.57-155-gcdf239ca885b2`; `make kernelversion` → **6.18.57**.
v6.18.57 `mtu3_trace.h` still has `__entry->gpd_ring,
&__entry->gpd_ring->dma`. Introduced 2019. `git merge-base --is-ancestor
dff6c93cf7131 v6.18.57` failed (fix not in 6.18.57).
`test_double_dereference` is **absent** from `kernel/trace/`
(`b5cc230af5e5` is not an ancestor of HEAD).

**Step 6.2: Backport difficulty**
Record: **Clean apply.** `git diff v6.18.57 dff6c93cf7131 --
drivers/usb/mtu3/mtu3_trace.h` is exactly this 4-line change. Context
matches 6.18 (`__assign_str(name)` already present).

**Step 6.3: Related fix already here?**
Record: No other mtu3 `TP_printk` fix in `v6.18..v6.18.57`. The ice
analogue **is** already in 6.18.57. That does not replace this mtu3 bug.

---

## Phase 7: Subsystem context

**Step 7.1**
Record: **drivers/usb/mtu3** — MediaTek USB3 dual-role. Criticality:
**PERIPHERAL/IMPORTANT for MTK** (`CONFIG_USB_MTU3`, `depends on
ARCH_MEDIATEK || COMPILE_TEST`). Tracepoints compiled with the driver
when `CONFIG_TRACEPOINTS` is on.

**Step 7.2**
Record: Mature driver (tracepoints since 2019). Recent 6.18.y mtu3 fixes
include DMA unmap on queue failure and suspend-with-gadget. Not staging.

---

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
Record: MediaTek USB3 gadget users who enable these ftrace events and
later print the buffer. Distro kernels that build mtu3 for
`COMPILE_TEST` do **not** get the 7.3 boot WARN here, because that check
is missing.

**Step 8.2: Trigger**
Record: Not every boot on 6.18.y. Needs `CONFIG_USB_MTU3` + tracepoints
+ enable these events + later print. UAF additionally needs the
endpoint/device object to have been freed. Not unprivileged. The 7.3
boot WARN fires even on dummy-virt; **that path does not exist in this
tree**.

**Step 8.3: Failure mode**
Record:
- On 7.3+: boot `WARNING` — **does not apply to 6.18.57**
- On this tree: delayed deref → **garbage DMA address in traces**, or
  **UAF/oops** if `mtu3_ep` was freed — severity **HIGH** when hit,
  **MEDIUM** overall because the trigger is a debug path

**Step 8.4: Risk vs benefit**
Record: **Benefit:** closes a real stale-pointer/UAF in mtu3 gadget
traces; same class already taken for ice on this series. **Risk:** very
low (3 insertions, print-time only). Ratio favors backport.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**

For:
- Real delayed dereference of a kernel pointer from the trace buffer
  (`%pad` confirmed to dereference)
- Buggy code present in this 6.18.y tree since 2019
- Small, obviously correct, applies cleanly
- Reviewed by Rostedt; reported/tested by McKenney and Rutland
- Same class (`TP_printk` must not follow saved pointers) already in
  v6.18.57 for ice
- No new API/feature; no series dependency

Against:
- The boot splat that drove the patch **cannot happen here**
  (`test_double_dereference` / `b5cc230af5e5` not in 6.18.y)
- Debug/tracing path, MediaTek-specific, needs events enabled
- Failure is often wrong trace text rather than a production USB failure
- No `Cc: stable` in review (not a negative per the rules)

Unresolved: lore.kernel.org HTTP 403 (thread read from `b4` mbox
instead).

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** (Rostedt Reviewed-by, Mark
   Tested-by, logic is local)
2. Real bug that affects users? **PASS** (stale pointer / UAF when
   traces are printed)
3. Important (crash/security/corruption/deadlock)? **PASS** (UAF/oops
   possible on print after free; garbage traces otherwise). The 7.3 boot
   WARN is not the important part **for this tree**.
4. Small and contained? **PASS** (one header, 4 lines)
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** (clean vs v6.18.57)

**Step 9.3: Exception category**
Record: None (not a device ID/quirk/DT/build/docs exception). It is a
normal small bugfix.

**Step 9.4: Decision**
The 7.3 boot WARN is not a reason to take this on 6.18.y. The reason to
take it is the pre-existing `TP_printk` dereference, which **is** in
this tree, is a real UAF/garbage-print bug, is a 4-line no-brainer, and
matches a fix this series already accepted for ice.

---

## What this means for 6.18.y users

`mtu3_log_ep` stores `&mep->gpd_ring` and later does `%pad` on
`&gpd_ring->dma`. Print can happen long after disable/unbind. That is a
real bug in this tree. The patch only snapshots `gpd_ring.dma` at event
time. It does not change gadget behavior.

## Verification

- **[Phase 1]** Parsed tags: Reported-by Paul McKenney, Tested-by Mark
  Rutland, Reviewed-by Steven Rostedt; no Fixes/Cc-stable
- **[Phase 2]** Diff: +`gpd_ring_dma` field, assign `mep->gpd_ring.dma`,
  print `&__entry->gpd_ring_dma`
- **[Phase 2]** `%pad` in `lib/vsprintf.c` `address_val()`: `num =
  *(const dma_addr_t *)addr`
- **[Phase 2]** `struct mtu3_ep` has embedded `struct mtu3_gpd_ring
  gpd_ring`; `mtu3_gpd_ring_free()` memsets it
- **[Phase 3]** Blame: `83374e035b628` (2019) introduced the pattern;
  ancestor of HEAD
- **[Phase 3]** `git merge-base --is-ancestor b5cc230af5e5 HEAD` failed;
  no `test_double_dereference` in this tree
- **[Phase 3]** Author log on `drivers/usb/`: this commit plus unrelated
  xhci work
- **[Phase 4]** `b4 dig -c cfb3293c4573`: msgid
  `20260922103756.104846-1-vladimir.murzin@arm.com`; v1 only
- **[Phase 4]** `b4 dig -w`: USB/Mediatek lists, Greg KH, Chunfeng Yun,
  Rostedt
- **[Phase 4]** mbox: Paul merged after 7.3-rc5/rc6 pings; no NAK; no
  stable nomination
- **[Phase 4]** UNVERIFIED: live lore.kernel.org page (403)
- **[Phase 5]** Callers: `mtu3_gadget_ep_enable/disable/set_halt` in
  `mtu3_gadget.c`
- **[Phase 6]** `git describe HEAD` = v6.18.57-155-gcdf239ca885b2;
  kernelversion 6.18.57
- **[Phase 6]** v6.18.57 still has `&__entry->gpd_ring->dma`; fix not an
  ancestor of v6.18.57
- **[Phase 6]** File diff vs v6.18.57 is exactly this patch (clean)
- **[Phase 6]** ice TP_printk analogue `0b0d2f9db2406` **is** in
  v6.18.57
- **[Phase 8]** Boot WARN not reachable here; UAF/garbage on delayed
  print is

The fix is small, correct, already matches this tree’s context, and
closes a real tracing UAF, not a 7.3-only WARN.

**YES**

 drivers/usb/mtu3/mtu3_trace.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_trace.h b/drivers/usb/mtu3/mtu3_trace.h
index 89870175d6356..9aaa167d69c13 100644
--- a/drivers/usb/mtu3/mtu3_trace.h
+++ b/drivers/usb/mtu3/mtu3_trace.h
@@ -224,6 +224,7 @@ DECLARE_EVENT_CLASS(mtu3_log_ep,
 		__field(unsigned int, flags)
 		__field(unsigned int, direction)
 		__field(struct mtu3_gpd_ring *, gpd_ring)
+		__field(dma_addr_t, gpd_ring_dma)
 	),
 	TP_fast_assign(
 		__assign_str(name);
@@ -235,12 +236,13 @@ DECLARE_EVENT_CLASS(mtu3_log_ep,
 		__entry->flags = mep->flags;
 		__entry->direction = mep->is_in;
 		__entry->gpd_ring = &mep->gpd_ring;
+		__entry->gpd_ring_dma = mep->gpd_ring.dma
 	),
 	TP_printk("%s: type %s maxp %d slot %d mult %d burst %d ring %p/%pad flags %c:%c%c%c:%c",
 		__get_str(name), usb_ep_type_string(__entry->type),
 		__entry->maxp, __entry->slot,
 		__entry->mult, __entry->maxburst,
-		__entry->gpd_ring, &__entry->gpd_ring->dma,
+		__entry->gpd_ring, &__entry->gpd_ring_dma,
 		__entry->flags & MTU3_EP_ENABLED ? 'E' : 'e',
 		__entry->flags & MTU3_EP_STALL ? 'S' : 's',
 		__entry->flags & MTU3_EP_WEDGE ? 'W' : 'w',
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (9 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] arm64: mm: fix accidental linear mapping of no-map reserved memory Sasha Levin
                   ` (37 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Zhi-Jun You, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Zhi-Jun You <hujy652@gmail.com>

[ Upstream commit 8a177dabeeead47dda4d4f91331282790eed0097 ]

In mt76_wed_init_rx_buf, it's hardcoded to use MT_RXQ_MAIN.
But for non-DBDC MT7986 MT_RXQ_BAND1 is used for RX data queue which
leads to kernel panic when attaching WED.

Use the correct RX queue by checking WED version and band_idx.

v2 and band 1 -> MT_RXQ_BAND1
Others -> MT_RXQ_MAIN

Kernel panic:

Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
Mem abort info:
  ESR = 0x0000000096000005
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x05: level 1 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
Internal error: Oops: 0000000096000005 [#1]  SMP
CPU: 1 UID: 0 PID: 925 Comm: kmodloader Tainted: G           O        6.18.26 #0 NONE
Tainted: [O]=OOT_MODULE
Hardware name: Acer Connect Vero W6m (DT)
pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : page_pool_alloc_frag_netmem+0x1c/0x1bc
lr : page_pool_alloc_frag+0xc/0x34
sp : ffffffc081dab660
x29: ffffffc081dab660 x28: ffffffc081dabc60 x27: ffffff80091af040
x26: 0000008000000000 x25: ffffff80091a8898 x24: ffffff80091a5440
x23: 0000000000001000 x22: 0000000140000000 x21: ffffff80091a2040
x20: ffffff8003f1d780 x19: 0000000000000000 x18: 0000000000000020
x17: ffffffbfbf0ac000 x16: ffffffc080ee0000 x15: ffffff80049d47ca
x14: 000000000000037b x13: 000000000000037b x12: 0000000000000001
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffffff8003f1d7c0 x7 : 0000000000000000 x6 : ffffff8003f1d780
x5 : 0000000000000680 x4 : 0000000000000000 x3 : 0000000000002824
x2 : 0000000000000000 x1 : ffffffc081dab71c x0 : 0000000000000000
Call trace:
 page_pool_alloc_frag_netmem+0x1c/0x1bc (P)
 page_pool_alloc_frag+0xc/0x34
 mt76_wed_init_rx_buf+0xf8/0x2ac [mt76]
 mtk_wed_start+0x79c/0x12ac
 mt7915_dma_start+0x274/0x63c [mt7915e]
 mt7915_dma_start+0x5b4/0x63c [mt7915e]
 mt7915_dma_init+0x49c/0x81c [mt7915e]
 mt7915_register_device+0x24c/0x530 [mt7915e]
 mt7915_mmio_probe+0x91c/0x1980 [mt7915e]
 platform_probe+0x58/0xa0
 really_probe+0xb8/0x2a8
 __driver_probe_device+0x74/0x118
 driver_probe_device+0x3c/0xe0
 __driver_attach+0x88/0x154
 bus_for_each_dev+0x60/0xb0
 driver_attach+0x20/0x28
 bus_add_driver+0xdc/0x200
 driver_register+0x64/0x118
 __platform_driver_register+0x20/0x30
 init_module+0x74/0x1000 [mt7915e]
 do_one_initcall+0x4c/0x1f8
 do_init_module+0x50/0x210
 load_module+0x15f8/0x1b10
 __do_sys_init_module+0x1a8/0x260
 __arm64_sys_init_module+0x18/0x20
 invoke_syscall.constprop.0+0x4c/0xd0
 do_el0_svc+0x3c/0xd0
 el0_svc+0x18/0x60
 el0t_64_sync_handler+0x98/0xdc
 el0t_64_sync+0x158/0x15c
Code: aa0003f3 a9025bf5 a90363f7 d2820017 (b9400000)

Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
Link: https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.6.157** (`pending-6.6`). The panic is real here, but
the mainline patch has to be rewritten onto `mt7915/mmio.c` because
`wed.c` does not exist yet.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[wifi: mt76: wed:] [fix] [kernel panic on non-DBDC MT7986 when
attaching WED because RX buf init used the wrong queue]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Signed-off-by: Zhi-Jun You <hujy652@gmail.com>` (author)
- `Link:
  https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com` (v2
  1/2 of a 2-patch series)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:` tag (expected for this review)
- No `Cc: stable@vger.kernel.org` (expected)
- No `Reported-by:` / `Tested-by:` / `Reviewed-by:` / `Acked-by:`
- Sibling patch 2/2 has the same msgid stem `20260715152113.553-2` and
  **is already in this 6.6 tree** as `8eae5e5aa09da` (`wifi: mt76:
  mt7915: fix net_fill_forward_path for non-DBDC mt7986`)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `mt76_wed_init_rx_buf` always uses `MT_RXQ_MAIN`. Non-DBDC
  MT7986 uses `MT_RXQ_BAND1` for the RX data queue.
- **Symptom:** NULL deref oops while attaching WED, in
  `page_pool_alloc_frag_netmem`. Full oops from **Acer Connect Vero
  W6m**, kernel 6.18.26, PID `kmodloader` during `mt7915e` probe.
- **Root cause:** wrong RX queue → uninitialized `page_pool` (NULL) →
  fault at `page_pool_alloc_frag*`.
- **Fix:** `wed->version == 2 && dev->phy.band_idx` → `MT_RXQ_BAND1`,
  else `MT_RXQ_MAIN`.
- Crash taint includes `O` (OOT module), but the call trace is in-tree
  `mt76` / `mt7915e` / `mtk_wed_start`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. Explicit panic fix with a stack trace. Not
cleanup/refactor.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/wed.c` (+6 / −1)
- Function: `mt76_wed_init_rx_buf`
- Scope: single-file, surgical (~5 lines of logic)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `q = &dev->q_rx[MT_RXQ_MAIN]` always, then
  `mt76_get_page_pool_buf(q, ...)`.
- **After:** pick `MT_RXQ_BAND1` for WED v2 + band 1; otherwise
  `MT_RXQ_MAIN`.
- Path: WED RX buffer init during `mtk_wed_start` from
  `mt7915_dma_start` (probe / DMA start), not a rare error path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- Category: **NULL pointer dereference** (memory safety) from **wrong-
  queue logic**.
- Mechanism: for non-DBDC MT7986, `mt7915_band_config` sets `band_idx =
  1` and DMA only allocates `q_rx[MT_RXQ_BAND1]`. `MT_RXQ_MAIN` is left
  with `page_pool == NULL`. `mt76_get_page_pool_buf` →
  `page_pool_dev_alloc_frag(NULL)` → oops.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct given DMA queue allocation in `mt7915/dma.c`.
- Minimal; no API/locking/refcount changes.
- Regression risk low: DBDC and band-0 devices still use `MT_RXQ_MAIN`.
- Backport caveat: in 6.6 the same logic lives in
  `mt7915_mmio_wed_init_rx_buf` (`dev` is `struct mt7915_dev *`), so the
  condition must use `dev->mt76.phy.band_idx` (or
  `dev->phy.mt76->band_idx`), not `dev->phy.band_idx`.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Hardcoded `MT_RXQ_MAIN` in 6.6: `mt7915/mmio.c:635`, from
  `2f5c3c77fc9b6` (`wifi: mt76: switch to page_pool allocator`,
  2023-02-03). Present in this tree.
- WED RX itself: `4f831d18d12da` (`wifi: mt76: mt7915: enable WED RX
  support`, 2022-12-01). Present.
- MT7986 one-A-die `band_idx = 1`: `mt7915_band_config` in `init.c`.
  Present.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug is the hardcoded MAIN queue vs MT7986
band-1 mapping, present since WED RX + page_pool.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- `wed.c` added later by `8a7386e787ef4` (`wifi: mt76: move wed common
  utilities in wed.c`, 2024-02-22). **Not in pending-6.6** (`git merge-
  base --is-ancestor` → not ancestor).
- Related 6.6 history: WED enable for MT7986, WED RX, page_pool switch,
  several WED robustness fixes.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record:
- Author is not the mt76 maintainer; maintainer Felix Fietkau signed
  off.
- Same author, same series date: `8eae5e5aa09da` already on pending-6.6
  (patch 2/2).
- Felix has many mt7915/WED fixes on this branch.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Standalone logic; does **not** need the `wed.c` move.
- Needed in 6.6: `wed->version` (exists, `u8 version` in
  `mtk_wed_device`), `phy.band_idx`, `MT_RXQ_BAND1`, page_pool RX — all
  present.
- Series 1/2; 2/2 is independent (forward-path queue) and already
  applied.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig` on sibling `8eae5e5aa09da` matched msgid
  `20260715152113.553-*`.
- RFC (2026-06-13): “single band MT7986”
- v1 (2026-06-30):
  https://patch.msgid.link/20260630150649.1629-1-hujy652@gmail.com (and
  1629-2)
- v2 (2026-07-15, applied):
  https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
- v2 1/2 is the committed version. Change vs RFC: “single band” → “non-
  DBDC”.
- lore.kernel.org fetches returned 403; thread text confirmed via
  ratatoskr mirrors.
- No NAK found. Merged by Felix Fietkau (2026-07-31) as `8a177dabeeead`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w` on sibling): Zhi-Jun You; Felix Fietkau
(`nbd@nbd.name`); Lorenzo Bianconi; Ryder Lee / Shayne Chen / Sean Wang
(MediaTek); `linux-wireless`; `linux-mediatek`; Benjamin Larsson
(Suggested-by on 2/2). Maintainer merged it.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Concrete oops from Acer Connect Vero W6m
(MT7986). Real hardware, probe-time crash with WED.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 2-patch v2 series. 1/2 = this panic. 2/2 =
`net_fill_forward_path` wrong WDMA queue; already in 6.6. Independent;
1/2 is the crash fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable returned 403. **UNVERIFIED** whether
anyone mailed stable@. 2/2 of the same series is already in this 6.6
tree, so the series is treated as 6.6-relevant.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: Mainline `mt76_wed_init_rx_buf`. In this tree:
`mt7915_mmio_wed_init_rx_buf`.

**Step 5.2: TRACE CALLERS**
Record:
- Assigned as `wed->wlan.init_rx_buf` in `mt7915_mmio_wed_init`.
- Called from `mtk_wed_rx_buffer_alloc` → `dev->wlan.init_rx_buf(dev,
  dev->wlan.rx_npkt)` (`mtk_wed.c`).
- That runs from `mtk_wed_start` ← `mt7915_dma_start` ←
  `mt7915_dma_init` ← `mt7915_register_device` ← probe.
- Reachable on device probe when WED is attached (`wed_enable` module
  param).

**Step 5.3: TRACE CALLEES**
Record: `mt76_get_rxwi`, `mt76_get_page_pool_buf` →
`page_pool_dev_alloc_frag(q->page_pool)`, `mt76_rx_token_consume`. First
page_pool alloc is the crash site.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record:
```
module load mt7915e
  → mt7915_mmio_probe / register_device
  → mt7915_dma_init → mt7915_dma_start
  → mtk_wed_device_start → mtk_wed_rx_buffer_alloc
  → mt7915_mmio_wed_init_rx_buf
  → mt76_get_page_pool_buf(uninitialized MT_RXQ_MAIN)
  → oops
```
Userspace-reachable via loading the driver (typically root). Not a
syscall fuzz path; it is a boot/probe crash on affected hardware.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: `mt7915/testmode.c` already uses `q = phy->mt76->band_idx ?
MT_RXQ_BAND1 : MT_RXQ_MAIN`. DMA init uses the same band_idx split. Same
author’s 2/2 fixes the matching forward-path mistake.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is 6.6.157 (`pending-6.6`). `wed.c` is absent.
Equivalent bug:

```
mt7915_mmio_wed_init_rx_buf:
    q = &dev->mt76.q_rx[MT_RXQ_MAIN];   /* mmio.c:635 */
```

`mt7915_dma.c`: allocate `MT_RXQ_MAIN` only if
`!dev->phy.mt76->band_idx`; allocate `MT_RXQ_BAND1` if `dbdc_support ||
band_idx`. `mt7915_band_config` sets `band_idx = 1` for MT7986 one-A-die
(non-DBDC). Introduced with WED RX + page_pool (2022–2023), well before
6.6.

`git merge-base --is-ancestor 8a177dabeeead pending-6.6` → **not
present**.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Needs a small backport**, not a clean apply. Same if/else in
`mt7915/mmio.c`, with `dev->mt76.phy.band_idx` /
`dev->phy.mt76->band_idx`. `wed->version` exists and is set to 2 for
non-netsys-v1 (MT7986) in `mtk_wed.c`. Minor conflict, not a rewrite.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent RX-buf queue selection. 2/2 (`8eae5e5aa09da`) is
here and addresses the same hardware mapping, not this NULL deref.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/wireless/mediatek/mt76` + MediaTek WED.
**IMPORTANT** (common Filogic/MT7986 WiFi, OpenWrt/embedded), not core
mm/VFS.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature and actively fixed on 6.6 (WED null-ptr, register
mapping, MT7981, chainmask for non-DBDC band 1).

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific: MT7986 (and similar mt798x) **non-DBDC**
(single A-die) with `CONFIG_NET_MEDIATEK_SOC_WED` and `wed_enable`. Real
product: Acer Connect Vero W6m. Default `wed_enable` is false, but WED
is used on these SoCs.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Every probe with WED attached on that SKU. Not a race. Needs
privilege to load the module; typical as a platform driver at boot.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Kernel oops/panic on WiFi/WED attach. **CRITICAL** for those
devices (WiFi unusable; can panic the box).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7986 non-DBDC + WED (prevents probe oops).
- **Risk:** low (5-line queue index; other SKUs unchanged).
- **Ratio:** benefit ≫ risk. Backport must retarget `mmio.c`.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Documented oops: NULL `page_pool` in WED RX init.
- Same bug in this tree (`mt7915_mmio_wed_init_rx_buf` + DMA not
  allocating MAIN when `band_idx == 1`).
- Small, obviously correct queue selection.
- mt76 maintainer signed off; RFC → v1 → v2.
- Sibling 2/2 already on 6.6.
- MT7986 + WED RX + page_pool all exist here.
- `wed->version` and `band_idx` exist.

AGAINST:
- Patch file `wed.c` is not in 6.6 (moved in 6.8-era `8a7386e787ef4`).
- Needs a few-line context backport.
- WED off by default; subset of MT7986 boards.
- Crash log tainted OOT; still in-tree frames.

UNRESOLVED:
- Stable ML discussion (lore/stable 403).
- Whether every reviewer asked for Cc: stable (not seen on v2 1/2).

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — matches DMA allocation;
   maintainer merged; oops on real HW.
2. Fixes a real bug that affects users? **PASS** — probe oops on non-
   DBDC MT7986 + WED.
3. Important issue? **PASS** — kernel oops, severity CRITICAL for that
   hardware.
4. Small and contained? **PASS** — ~5 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** with a backport to
   `mt7915/mmio.c` (stable rule: apply cleanly **or come with a
   backport**). Not a missing-feature case.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc). Ordinary crash fix.

**Step 9.4: MAKE YOUR DECISION**
The 6.6 tree has the same panic path under a pre-`wed.c` name. Selecting
this for 6.6 is justified; apply the same `version == 2 && band_idx`
check in `mt7915_mmio_wed_init_rx_buf`.

---

**What the commit solves for this tree:** On non-DBDC MT7986, the main
phy is band 1, so only `MT_RXQ_BAND1` is allocated. WED RX init still
pulls from `MT_RXQ_MAIN`, whose `page_pool` is NULL, and the kernel
oopses in `page_pool_alloc_frag` during `mt7915e` probe. That mapping is
already in 6.6 `init.c`/`dma.c`; only the RX-buf picker is wrong.

**Stable rules:** Real, important crash; tiny logic fix; no new API.
File path changed after 6.6, so it needs a short backport, not a NAK.

**Risk vs benefit:** Low risk, high benefit on Filogic devices that
enable WED (including the reported Acer Vero W6m class).

**Concerns:** Must edit
`drivers/net/wireless/mediatek/mt76/mt7915/mmio.c` and use
`dev->mt76.phy.band_idx` (or `dev->phy.mt76->band_idx`) because `dev` is
`struct mt7915_dev *` here. Do not require `8a7386e787ef4`.

Verification:
- [Phase 1] Subject/tags: fix panic; SOB Zhi-Jun You + Felix Fietkau;
  Link `20260715152113.553-1`; no Fixes/Cc-stable
- [Phase 1] Series: v2 1/2; 2/2 already `8eae5e5aa09da` on pending-6.6
- [Phase 2] Diff: 6 insertions in `mt76_wed_init_rx_buf`; queue MAIN vs
  BAND1
- [Phase 3] Blame on 6.6: `q = &dev->mt76.q_rx[MT_RXQ_MAIN]` from
  `2f5c3c77fc9b6` (page_pool); present
- [Phase 3] `8a7386e787ef4` (wed.c split) **not** ancestor of
  pending-6.6
- [Phase 3] Fix `8a177dabeeead` **not** ancestor of pending-6.6
- [Phase 4] b4 dig: RFC → v1 → v2; applied v2; Felix merged 2026-07-31
- [Phase 4] Recipients: mt76 maintainers + linux-wireless/mediatek
- [Phase 4] UNVERIFIED: lore.kernel.org and lore.kernel.org/stable HTTP
  403; used ratatoskr mirrors
- [Phase 5] Caller: `mtk_wed_rx_buffer_alloc` → `wlan.init_rx_buf` from
  `mtk_wed_start` / probe
- [Phase 6] `git show pending-6.6:Makefile`: VERSION 6 / PATCHLEVEL 6 /
  SUBLEVEL 157
- [Phase 6] `git cat-file` pending-6.6 `wed.c`: path does not exist
- [Phase 6] pending-6.6 `mmio.c:635`: hardcoded `MT_RXQ_MAIN`; `init.c`
  sets `band_idx = 1` for one-A-die MT7986
- [Phase 6] DMA: MAIN allocated only if `!band_idx`; BAND1 if
  `dbdc_support || band_idx`
- [Phase 6] `wed->version` exists; set to 2 for MT7986-class WED
- [Phase 8] Failure: NULL page_pool deref → oops; CRITICAL for that
  SKU+WED
- UNVERIFIED: whether an out-of-tree module contributed besides in-tree
  frames (taint `O`)

**YES**

 drivers/net/wireless/mediatek/mt76/wed.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/wed.c b/drivers/net/wireless/mediatek/mt76/wed.c
index fbd7e59c73aaf..2ebf4edc689e9 100644
--- a/drivers/net/wireless/mediatek/mt76/wed.c
+++ b/drivers/net/wireless/mediatek/mt76/wed.c
@@ -33,10 +33,15 @@ u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
 {
 	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
 	struct mt76_dev *dev = mt76_wed_to_dev(wed);
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct mt76_txwi_cache *t = NULL;
+	struct mt76_queue *q;
 	int i;
 
+	if (wed->version == 2 && dev->phy.band_idx)
+		q = &dev->q_rx[MT_RXQ_BAND1];
+	else
+		q = &dev->q_rx[MT_RXQ_MAIN];
+
 	for (i = 0; i < size; i++) {
 		dma_addr_t addr;
 		u32 offset;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] arm64: mm: fix accidental linear mapping of no-map reserved memory
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (10 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] perf/arm-cmn: Add workarounds for CMN-S3 on Graviton5 Sasha Levin
                   ` (36 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: liulhong617, Will Deacon, Sasha Levin, catalin.marinas,
	linux-arm-kernel, linux-kernel

From: liulhong617 <liulhong617@gmail.com>

[ Upstream commit 7ace06a01efaba1ec585630aa4c98ac39b38452a ]

When reserved-memory regions with the "no-map" property are not
page-aligned, the kernel may accidentally map them into the linear
mapping, contradicting the no-map semantics.

The root cause is a mismatch between /proc/iomem's address boundaries
and the actual page table mapping boundaries:

1. /proc/iomem derives its ranges from memblock via
   memblock_region_reserved_base_pfn/memblock_region_reserved_end_pfn,
   which perform PFN rounding so the displayed boundaries are
   page-aligned. This gives the impression that the no-map region
   occupies whole pages.

2. However, memblock_mark_nomap() splits memblock.memory regions at
   exact byte boundaries (memblock_isolate_range preserves raw DT
   base/size with no alignment). When for_each_mem_range iterates the
   non-NOMAP regions adjacent to a no-map region, it returns start/end
   values that are NOT page-aligned — they are the precise byte
   boundaries from the memblock split.

3. These sub-page-aligned values are passed to
   __create_pgd_mapping_locked(), which does:
     phys &= PAGE_MASK;
     addr = virt & PAGE_MASK;
     end = PAGE_ALIGN(virt + size);
   The downward rounding of phys via PAGE_MASK extends the mapped
   range backward into the adjacent no-map region, effectively
   including no-map memory in the linear mapping.

For example, with 64K pages, reserved_region@A2000000 (base=0xA2000000,
size=0x8000, no-map) causes for_each_mem_range to return
start=0xA2008000 for the next mappable region. After phys &= PAGE_MASK,
the actual mapping starts at 0xA2000000 — the entire no-map region is
incorrectly mapped.

Fix this by rounding the mappable range inward to PAGE_SIZE boundaries
before passing it to __map_memblock: start is rounded UP and end is
rounded DOWN. This ensures the mapped area never overlaps with adjacent
no-map regions. The cost is at most one page of unmapped gap at each
boundary, which is preferable to violating no-map semantics.

Signed-off-by: liulhong617 <liulhong617@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.12.111** (`pending-6.12`). The candidate is
`7ace06a01efab` (“arm64: mm: fix accidental linear mapping of no-map
reserved memory”). It is not in this checkout. The buggy path is, and
the original patch was written against this `map_mem()` shape.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: `[arm64: mm:] [fix] [do not linearly map sub-page-aligned DT no-
map reserved memory]`

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- `Signed-off-by: liulhong617 <liulhong617@gmail.com>` (author)
- `Signed-off-by: Will Deacon <will@kernel.org>` (arm64 maintainer;
  applied to for-next/mm)
- No `Fixes:`
- No `Reported-by:` / `Tested-by:` / `Reviewed-by:` / `Acked-by:` /
  `Link:` / `Cc: stable`
- Absence of `Fixes:`/`Cc: stable` is expected for this review and is
  not a negative signal

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** `no-map` reserved-memory that is not page-aligned can still
  land in the arm64 linear map.
- **Symptom:** `/proc/iomem` looks page-aligned (PFN rounding), but page
  tables map the no-map bytes because `memblock_mark_nomap()` splits at
  byte precision and `__create_pgd_mapping_locked()` does `phys &=
  PAGE_MASK` (start rounded down into the hole).
- **Example:** 64K pages, `reserved_region@A2000000` size `0x8000`; next
  mappable start `0xA2008000` becomes mapping start `0xA2000000`.
- **Root cause:** byte-precise NOMAP split + PAGE_MASK downward
  rounding.
- **Fix:** round the mappable range inward (`PAGE_ALIGN(start)`, `end &
  PAGE_MASK`) before `__map_memblock`. Cost: at most one unmapped page
  per boundary.
- **Version info in message:** none. Mailing-list follow-up (verified)
  was on v6.1.177-rt, 64K pages.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not hidden. Explicit isolation/correctness fix, not cleanup.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `arch/arm64/mm/mmu.c` (+14 / −0)
- Function: `map_mem()` / `map_mem(pgd_t *pgdp)` in this tree
- Scope: single-file surgical change in the boot-time linear-map loop

Committed hunk (origin/master `map_mem(void)`):
```
for_each_mem_range(i, &start, &end) {
+       start = PAGE_ALIGN(start);
+       end = end & PAGE_MASK;
+       if (start >= end)
+               continue;
        __map_memblock(...);
}
```

The mailing-list v1 was against `map_mem(pgd_t *pgdp)` and kept this
tree’s existing `if (start >= end) break;` before the new inward
rounding — that is the 6.12 shape.

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** `for_each_mem_range` skips `MEMBLOCK_NOMAP` via
  `should_skip_region()`, but adjacent ranges keep raw byte boundaries.
  Those go to `__map_memblock` → `__create_pgd_mapping_locked()`, which
  rounds `phys` down and `end` up, pulling no-map bytes into
  `PAGE_KERNEL`.
- **After:** start rounded up, end rounded down; empty leftover skipped.
  Linear map never overlaps the no-map hole.
- Path: boot-time linear map only (`paging_init` → `map_mem`).

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- **Category:** logic/correctness + hardware isolation (linear-map over-
  coverage).
- **Mechanism:** unaligned NOMAP split + `phys &= PAGE_MASK` over-maps.
  Verified in this tree at `arch/arm64/mm/mmu.c:443-445`:
  `phys &= PAGE_MASK; addr = virt & PAGE_MASK; end = PAGE_ALIGN(virt +
  size);`
- DT `no-map` (this tree, `reserved-memory.yaml`): OS must not create a
  standard mapping **and** must not allow speculative access except
  under the owning driver.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct for the stated failure: inward rounding matches
  buddy `__free_memory_core()` (`PFN_UP(start)` / `PFN_DOWN(end)` in
  `mm/memblock.c` of this tree). Those slivers were never allocator RAM.
- Minimal; comment-only plus three functional lines.
- Regression risk: low. Worst case is one unmapped page at a no-map
  boundary (memory the buddy already does not own). Ard noted a
  theoretical firmware hazard if something like initramfs sat in that
  wasted page; Will still applied it after Ard confirmed
  `for_each_mem_range()` coalesces sub-page *mappable* pieces.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- `phys &= PAGE_MASK`: `9c4e08a3022b6` (Mark Rutland, 2015, “allow
  sections for unaligned bases”)
- Linear-map bank loop: `98d2e1539b84a` (2017) / `b10d6bca87204`
  (`for_each_mem_range`, 2020)
- This is old code, present long before 6.12.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` tag. Bug is the long-standing interaction of NOMAP
byte splits + page-table rounding, not a single recent commit.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- This tree: no commit on `arch/arm64/mm/mmu.c` already doing inward
  `PAGE_ALIGN` in `map_mem`.
- `7ace06a01efab` is **not** an ancestor of HEAD (`git merge-base --is-
  ancestor` exit 1).
- Upstream later dropped the `pgd_t *` argument (`2e527667a3b9b`,
  2026-06-02) — **not** in this tree, **not** required for the fix.
- Follow-up `fb0f3ef5601a6` (unmap data/bss from linear map) is
  independent.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Only this arm64 commit on `origin/master`. Applied by Will
Deacon (arm64 maintainer). Ard Biesheuvel reviewed on-list and called it
conceptually sound.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Standalone. Needs `for_each_mem_range`, `__map_memblock`,
`__create_pgd_mapping_locked` — all present. The committed diff does not
apply byte-for-byte (later `map_mem(void)` / no `if (start >= end)
break;`); the **original** patch context matches this tree. Backport is
a small context adaptation, not a missing-API rewrite.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c 7ace06a01efab` →
  https://patch.msgid.link/20260513010255.3764038-1-liulhong617@163.com
- Single revision (v1 only). `b4 dig -a`: only that v1.
- Thread saved to mbox and read in full.
- Will (16 Jul 2026): worried firmware with many tiny adjacent regions
  could leave pages unmapped; preferred warn-and-do-nothing; asked for
  practical symptoms.
- Author (27 Jul): 64K pages, debugger showed `phys` rounded from
  `0xa2008000` to `0xa2000000`.
- Will (4 Aug): not convinced by that reply.
- Ard (4 Aug): change is conceptually sound; `for_each_mem_range()`
  coalesces; only sane handling is to round no-map **outward** (i.e.
  linear map **inward**). Suggested maybe moving rounding into
  `__create_pgd_mapping_locked()` later.
- Will (6 Aug): “Aha, that's the part I was missing.” Applied v1: “I can
  take this patch for now.”
- Apply mail: https://git.kernel.org/arm64/c/7ace06a01efa (`for-
  next/mm`).
- Author (9 Aug, after apply): real platform is Cortex-A78AE,
  **v6.1.177-rt**, 64K pages; two sub-page no-map TEE regions; DStream
  showed them folded into one `PAGE_KERNEL` span; cache prefetcher hit
  TEE and firmware raised “REE accessed secure memory” faults.
- No NAK of the applied patch. No `Cc: stable` in review.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): To Catalin Marinas, Will Deacon; Cc linux-arm-
kernel, linux-kernel. Ard added later. Maintainer applied it.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla. Evidence is the author’s debugger dump and
firmware faults (mbox, 9 Aug 2026). Severity from reporter: isolation
break + spurious secure-memory faults.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone 1/1. Ard/Will mentioned a possible later rounding
cleanup in `__create_pgd_mapping_locked()`; `origin/master` still has
this loop-local fix only (no follow-up required).

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable WebFetch returned 403. UNVERIFIED whether
stable@ already discussed it. Not used as a NO reason.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `map_mem()` (this tree: `static void __init map_mem(pgd_t
*pgdp)` at `arch/arm64/mm/mmu.c:623`).

Step 5.2: TRACE CALLERS
Record: `paging_init()` → `map_mem(swapper_pg_dir)` (`mmu.c:812-814` in
this tree). Boot-time, all arm64 configs. Not a syscall path; result is
the linear map used by the whole kernel.

Step 5.3: TRACE CALLEES
Record: `for_each_mem_range` → `__next_mem_range` / `should_skip_region`
(skips NOMAP unless `MEMBLOCK_NOMAP` requested). Then `__map_memblock` →
`__create_pgd_mapping` → `__create_pgd_mapping_locked`.
`memblock_mark_nomap` → `memblock_isolate_range` (byte splits, no page
align) — verified in `mm/memblock.c`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Reachable on every arm64 boot. User/firmware trigger is a sub-
page `no-map` reserved-memory node (common with 16K/64K pages).
Unprivileged userspace does not need to do anything after boot; the bad
mapping already exists. Speculative CPU access of TEE pages is enough.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Second `for_each_mem_range` in this file is
`validate_bootmem_online()` under `CONFIG_DEBUG_VM` — not page-table
creation. No sibling fix already in this tree.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.**
- `map_mem()` loop: `mmu.c:660-670` passes raw `start`/`end` to
  `__map_memblock`.
- Rounding-down: `mmu.c:443-445`.
- NOMAP skip: `should_skip_region()` in `mm/memblock.c:1081-1083`.
- Byte isolate: `memblock_isolate_range()`.
- Introduced: rounding 2015, loop 2017/2020 — well before 6.12.
- `7ace06a01efab` not in HEAD.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Minor adaptation, not a rewrite.** Committed patch fails `git
apply --check` because this tree still has `if (start >= end) break;`
and `map_mem(pgd_t *pgdp)`. That is exactly v1’s context. Insert the
three rounding lines after the existing `break`. No need for
`2e527667a3b9b`.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: None. `git log --grep="accidental linear mapping"` /
`--grep="no-map"` on this file in HEAD does not contain this fix.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: `arch/arm64/mm` linear map. **CORE for arm64** (every arm64
boot). `no-map` is how firmware hides TEE/DSP/GPU carveouts.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature; this file still changes, but the bank-mapping loop has
been stable for years in 6.12. Bug is old, not a new-subsystem leftover.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: arm64 systems whose DT/firmware has **sub-page-aligned `no-map`
reserved-memory**. More likely with 16K/64K pages. Author hit it on
6.1.rt; 6.12 has the same mapping logic.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Boot + unaligned `no-map` region. No extra userspace trigger.
Cache prefetch can then touch TEE. Commonness: not every board, but real
on 64K TEE/embedded SoCs.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- Isolation break: `no-map` (including TEE) mapped `PAGE_KERNEL`.
- Speculative access / firmware “REE accessed secure memory” faults
  (verified report).
- DT forbids speculative access to `no-map`.
- Severity: **HIGH** (security isolation + platform faults). Not a
  universal oops, but it is an important real bug, not a nit.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for affected boards (TEE/firmware faults, linear-map
  leak of carveouts).
- **Risk:** low (≤1 unused page per boundary; matches buddy PFN
  rounding; maintainer-acked).
- Ratio favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

FOR:
- Real bug in this tree’s `map_mem()` / `__create_pgd_mapping_locked()`.
- Hardware report: Cortex-A78AE, 64K, TEE `no-map`, firmware faults;
  also seen conceptually on 6.1, so 6.12 is in range.
- DT `no-map` contract violated (must not map, must not speculate).
- 14-line, single-function, no new API.
- Will applied; Ard endorsed the approach.
- Original patch context matches 6.12 `map_mem(pgd_t *pgdp)`.
- Inward rounding matches `__free_memory_core()` so it does not unmap
  buddy-owned pages.

AGAINST:
- Trigger is firmware/DT-dependent (unaligned `no-map`), not every arm64
  box.
- Committed mainline hunk needs a trivial context tweak (`break` still
  present here).
- Will first preferred warn-only; that was withdrawn after Ard’s
  coalescing point, not a standing NAK.
- Theoretical firmware footgun if a needed image lived in the discarded
  page remainder (Ard); sliver is already not buddy memory.

UNRESOLVED:
- lore.kernel.org/stable search 403; whether stable@ already took it is
  UNVERIFIED.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — mechanism verified in-tree;
   debugger + maintainer apply.
2. Fixes a real bug that affects users? **PASS** — TEE/linear-map
   isolation break and firmware faults.
3. Important issue? **PASS** — security isolation / platform abort, not
   a log nit.
4. Small and contained? **PASS** — +14 lines, one loop.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — bug present; v1 context
   matches; committed diff needs only local `map_mem` context.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not ID/quirk/DT-board/build/docs. Ordinary important bugfix.

Step 9.4: MAKE YOUR DECISION
Backport to this 6.12 tree. The bug is here, the fix is small, and
leaving `no-map` (especially TEE) in the linear map is a real isolation
and stability failure on 64K systems.

------------------------------------------------
What the commit solves for stable users
------------------------------------------------
On this 6.12 tree, boot builds the linear map in `map_mem()` from
`for_each_mem_range()`. NOMAP regions are skipped, but neighbors keep
byte-accurate edges. `__create_pgd_mapping_locked()` then rounds
physical start **down** to `PAGE_MASK`, so a 32KiB `no-map` hole on a
64K page is mapped as normal RAM. That contradicts DT `no-map` and can
let the CPU speculate into firmware/TEE memory.

Rounding the mapped range inward before `__map_memblock` stops that
overlap. At most one page per boundary stays unmapped; those bytes were
already excluded from the buddy allocator.

------------------------------------------------
Stable rules / risk
------------------------------------------------
Surgical, no API, code is in 6.12, original submission matches this
`map_mem(pgd_t *)` loop. Benefit is isolation and avoiding firmware
aborts; risk is a conservative hole the allocator already does not use.

------------------------------------------------
Verification
------------------------------------------------
- [Phase 1] `git describe HEAD` / `make kernelversion`:
  `p-6.12-3-g88406e77611c6`, **6.12.111**. Tags: author SOB + Will
  Deacon SOB only.
- [Phase 2] `git show 7ace06a01efab`: +14 in `map_mem`; this tree
  `Read`/`Grep`: `phys &= PAGE_MASK` at `mmu.c:443`; loop at
  `mmu.c:660-670`.
- [Phase 2] `reserved-memory.yaml`: `no-map` forbids standard mapping
  and speculative access.
- [Phase 2] `__free_memory_core()`: `PFN_UP`/`PFN_DOWN` in
  `mm/memblock.c:2153-2158`.
- [Phase 3] blame: `9c4e08a3022b6` (2015) PAGE_MASK; `98d2e1539b84a`
  (2017) / `b10d6bca87204` (2020) loop.
- [Phase 3] `git merge-base --is-ancestor 7ace06a01efab HEAD` → not in
  tree (exit 1).
- [Phase 3] `2e527667a3b9b` (drop `pgd_t*`) not in HEAD; not a
  prerequisite.
- [Phase 3] `git log origin/master --grep="accidental linear mapping" --
  arch/arm64/mm/mmu.c`: `7ace06a01efab`; `git describe --contains
  --match 'v*'`: `v7.3-rc1~...`
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 only; lore msgid
  `20260513010255.3764038-1-liulhong617@163.com`; Will + Ard discussion;
  applied 6 Aug 2026; author follow-up on v6.1.177-rt TEE faults.
- [Phase 4] lore WebFetch 403 on lore.kernel.org/all and /stable —
  thread recovered via `b4 dig -m`.
- [Phase 5] `paging_init()` calls `map_mem(swapper_pg_dir)`;
  `should_skip_region()` skips NOMAP.
- [Phase 6] `git apply --check` of committed diff **fails** (context);
  6.12 loop still has `if (start >= end) break;` matching v1.
- [Phase 6] `origin/master` `map_mem` still has `PAGE_ALIGN(start)` /
  `end & PAGE_MASK`.
- [Phase 8] Failure mode from mbox + DT: TEE mapped, prefetcher,
  firmware abort — HIGH.
- UNVERIFIED: whether stable@ already queued it (HTTP 403).

**YES**

 arch/arm64/mm/mmu.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 71841b5c31928..7c3f560df6529 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1179,6 +1179,20 @@ static void __init map_mem(pgd_t *pgdp)
 	for_each_mem_range(i, &start, &end) {
 		if (start >= end)
 			break;
+		/*
+		 * for_each_mem_range may return sub-page-aligned boundaries
+		 * after memblock_mark_nomap() splits regions at byte precision.
+		 * __create_pgd_mapping_locked aligns phys down to PAGE_MASK,
+		 * which could accidentally map no-map memory on the boundary.
+		 * Round the mappable range inward: start UP, end DOWN, so
+		 * that the mapped area never overlaps with adjacent no-map
+		 * regions. The cost is at most one page of unmapped gap at
+		 * each boundary.
+		 */
+		start = PAGE_ALIGN(start);
+		end = end & PAGE_MASK;
+		if (start >= end)
+			continue;
 		/*
 		 * The linear map must allow allocation tags reading/writing
 		 * if MTE is present. Otherwise, it has the same attributes as
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] perf/arm-cmn: Add workarounds for CMN-S3 on Graviton5
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (11 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] arm64: mm: fix accidental linear mapping of no-map reserved memory Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (35 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Aviv Bakal, Robin Murphy, Ilkka Koskinen, Will Deacon,
	Sasha Levin, mark.rutland, linux-arm-kernel, linux-perf-users,
	linux-kernel

From: Aviv Bakal <avivb@amazon.com>

[ Upstream commit 9d0b1714e1af16622a2d0f7317ddaa9a4b27f353 ]

Graviton5 uses a customised CMN-S3 implementation where certain
discovery registers report zeroed fields. Add the following workarounds:

 - Introduce a dedicated ACPI HID to identify the Graviton5 CMN variant.
 - Derive the DTC domain from the XP node ID, since the unit info
   register reports it as zero.
 - Set the DTC logical ID from the XP's logical ID, since the node info
   register's logical ID field is also zeroed.

Signed-off-by: Aviv Bakal <avivb@amazon.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **v7.3-rc4** (kernel 7.3.0-rc4). The question is
whether `9d0b1714e1af1` (`perf/arm-cmn: Add workarounds for CMN-S3 on
Graviton5`) belongs in **this** tree on technical merit.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: `[perf/arm-cmn] [Add] [workarounds for a customised CMN-S3 on
Graviton5]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- `Fixes:` — none (expected)
- `Reported-by:` — none
- `Tested-by:` — none
- `Reviewed-by: Robin Murphy <robin.murphy@arm.com>` (arm-cmn
  maintainer)
- `Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>`
- `Link:` — none in the commit
- `Cc: stable@vger.kernel.org` — none (expected)
- `Signed-off-by: Aviv Bakal <avivb@amazon.com>` (author)
- `Signed-off-by: Robin Murphy <robin.murphy@arm.com>`
- `Signed-off-by: Will Deacon <will@kernel.org>`
- Ignored: any Sasha Levin SOB / Upstream-commit markers

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** Graviton5’s CMN-S3 zeros some discovery fields (DTC domain in
  unit info, logical ID in node info).
- **Symptom:** Standard discovery cannot identify DTC domains or DTC
  logical IDs; a 10×14 mesh also exceeds `CMN_MAX_DIMENSION` 12.
- **Version info:** none in the message.
- **Root cause:** custom silicon, not a kernel logic regression.
  Identified via ACPI HID `AMZN0070`.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not a disguised cleanup. It is an explicit hardware workaround
plus ACPI ID. Cover letter language is “adds support”; the mechanism is
a quirk for broken discovery registers.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/perf/arm-cmn.c` (+31 / −1)
- Functions: `arm_cmn_graviton5_dtc_domain` (new), `arm_cmn_discover`
  (workaround + DTC logid), `arm_cmn_acpi_match[]` (HID)
- Also: `CMN_MAX_DIMENSION` 12→14, `PART_GRAVITON5`
- Scope: single-file, surgical, driver-local

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:
- Dimension cap 12→14 so a 10×14 mesh is not rejected.
- ACPI `AMZN0070` → synthetic `PART_GRAVITON5`, then treated as
  `PART_CMN_S3`.
- DTC domain: from unit-info register → from XP node ID `(x/5)+(y/7)*2`
  on the 10×14 mesh (domains 0–3).
- DTC `logid`: from node info → XP `logid` so sort order matches
  firmware IRQ order.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record: **Hardware workaround + ACPI device ID.** Zeroed discovery
fields would map every XP to DTC domain 0 and every DTC logid to 0. Mesh
10×14 fails `max(mesh_x,mesh_y) > CMN_MAX_DIMENSION` (`36c0de02575ce`,
already in this tree).

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Quality: small, gated on `AMZN0070` except the dimension bump.
  Maintainer R-b’d after review (v1 used `xp->logid`; v2 used `xp->dtc`;
  Robin required `xp->logid` because `cmn->dtc[]` is sorted by logid to
  match firmware IRQ order). Committed code matches that.
- Regression risk: low. Workaround is HID-gated. `CMN_MAX_DIMENSION` 14
  only grows per-event bitmaps (`CMN_MAX_XPS` 144→196). Domain formula
  is Graviton5-specific; x,y are 4-bit so theoretical max domain is 7,
  but 10×14 yields 0–3 (`CMN_MAX_DTCS` is 4).

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Workaround and dimension bump introduced by `9d0b1714e1af1` itself
  (Aviv Bakal, 2026-06-30; merged 2026-07-21).
- Driver: long-standing. CMN-S3: `0dc2f4963f7ef` (2024-09-04). ACPI
  `ARMHC003`: `8c138a189f6db` (2025-05-19). Mesh reject: `36c0de02575ce`
  (2026-02-03, `Cc: stable`).

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No `Fixes:` tag. Not a regression from a specific kernel commit;
hardware does not implement discovery as the driver expects.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record:
- This is **v6 2/2**. Patch 1 is `56603c28d9169` (`Move DTM index data
  out of hw_perf_event`) — **already an ancestor of HEAD**. Needed
  because embedded `dtm_idx`/`wp_idx` in `hw_perf_event` were size-
  capped; growing `CMN_MAX_DIMENSION` without that move would fail
  `static_assert(sizeof(struct arm_cmn_hw_event) <= offsetof(struct
  hw_perf_event, target))`.
- Later 7.3 work (filter refactor, CMN S3 r2) does not revert the
  workaround. No graviton-specific follow-up.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Aviv Bakal (Amazon) — this is their only arm-cmn commit here.
Robin Murphy is the driver author/maintainer and both reviewed and re-
posted v6.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: Needs CMN-S3, ACPI table, mesh-size check, and the DTM-index
move. **All are in this 7.3-rc4 tree.** Standalone on this tree.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c 9d0b1714e1af1` → https://patch.msgid.link/e9340d3a4385e6f1a
  6e80bda944a3ba6435472b6.1782824005.git.robin.murphy@arm.com
- Revisions: v1 (2026-05-03) → v2 → v3 (added DTM move) → v4 → v5 → **v6
  applied** (Robin re-post, 2026-06-30)
- Robin on v2: use `xp->logid` not `xp->dtc`; “surprisingly pleasant and
  unobtrusive given that it's a pretty horrible hardware issue”
- No NAK. Applied version is latest.
- A sashiko-bot note about unbounded DTC domain / sort order is the
  opposite of Robin’s requested `xp->logid` behaviour; not a NAK from
  maintainers.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): Robin Murphy, Will Deacon, Mark Rutland, linux-
arm-kernel, linux-perf-users, Amazon (zeev, blakgeof), Ilkka Koskinen.
Right maintainers.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No syzbot/bugzilla. Amazon submitted from silicon bring-up.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Series is DTM-index move + this workaround. Patch 1 is in this
tree. No extra ACPI docs/HID patch required (`AMZN0070` is only in `arm-
cmn.c`).

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable search returned 403. **UNVERIFIED:** no
confirmed stable-list nomination or rejection.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**

Record: `arm_cmn_graviton5_dtc_domain`, `arm_cmn_discover`,
`arm_cmn_acpi_match`, `arm_cmn_init_node_info` (unchanged, still source
of zeroed logid).

**Step 5.2: TRACE CALLERS**

Record: `arm_cmn_discover()` ← `arm_cmn_probe()` only. Probe runs when
ACPI matches (including `AMZN0070`). Not IRQ/syscall hot path;
boot/device-init.

**Step 5.3: TRACE CALLEES**

Record: `arm_cmn_init_node_info`, `arm_cmn_dtc_domain` / graviton5
variant, `arm_cmn_init_dtm`, then `arm_cmn_init_dtcs` (sort by
type+logid, `platform_get_irq` by sort index).

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: ACPI `AMZN0070` → probe → discover (workaround) → init DTCs/IRQs
→ register PMU. Userspace `perf` then uses the interconnect PMU.
Reachable on Graviton5 with `CONFIG_ARM_CMN`.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Same file already has AmpereOneX bogus-child-pointer handling
and CMN-600AE aliasing. Same “quirks for broken discovery” pattern.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: Yes. `drivers/perf/arm-cmn.c` has CMN-S3, ACPI match, mesh-size
reject. Without this commit, `AMZN0070` would not bind; a 10×14 mesh
would `-ENODEV`; zeroed DTC fields would mis-program the PMU. Introduced
as hardware behaviour, not a post-7.3 commit.

`git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`. Commit is in
v7.3-rc1 (not in v7.2). That is **not** used as “already selected”; it
only shows 7.3 has the prerequisites.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: Clean on this tree. Context still matches (graviton5 flag, ACPI
HID, dimension 14). Later S3 r2/filter refactors left the workaround in
place.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No alternate Graviton5 fix. No later graviton-specific patch in
`9d0b1714e1af1..HEAD`.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: `drivers/perf/` — Arm CMN uncore PMU. **PERIPHERAL/IMPORTANT:**
ARM64 servers with CMN; Graviton5-specific for the HID path. Not
mm/sched/VFS.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Active in 7.3 (S3 r2, filters, DTM layout). Driver itself is
mature (~CMN-600 era).

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: ACPI `AMZN0070` / Graviton5 only, plus a small extra bitmap size
for all `CONFIG_ARM_CMN` users.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record: Probe on Graviton5. Not unprivileged-triggerable beyond normal
perf. Not a race. Common on that platform at boot.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: Missing/wrong CMN PMU (no bind, `-ENODEV`, or events on the
wrong DTC). Not panic/corruption/deadlock. **MEDIUM** for that hardware;
still the documented quirk/ID exception.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- Benefit: Graviton5 CMN perf actually works (HID + discovery + 10×14
  mesh).
- Risk: low (~31 lines, HID-gated, maintainer-reviewed). Dimension bump
  is small and already paired with the DTM-index move in this tree.
- Ratio: favorable.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- ACPI ID + hardware quirk on an existing driver (stable exception).
- Real silicon: zeroed CMN-S3 discovery, 10×14 mesh.
- Small, single-file, obviously correct after maintainer review.
- Prerequisites present in 7.3-rc4.
- Robin Murphy: use `xp->logid`; workaround is unobtrusive.

**AGAINST:**
- Enablement/quirk, not a crash/security/corruption fix.
- Cover letter is “add support”.
- `CMN_MAX_DIMENSION` affects all CMN bitmap sizes (small).
- Series 2/2 (patch 1 already here).
- No `Reported-by` from production crashes.

**UNRESOLVED:**
- Stable list discussion (lore 403).
- No public Tested-by (author is Amazon; hardware access is plausible
  but unverified).

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — maintainer R-b after v1–v6;
   IRQ/logid issue addressed as Robin specified.
2. Fixes a real bug that affects users? **PASS** — Graviton5 CMN PMU
   cannot enumerate correctly without it.
3. Important issue? **PASS** via quirk/ID exception (severity MEDIUM as
   a PMU, not a panic).
4. Small and contained? **PASS** — +31/−1, one file.
5. No new features or APIs? **PASS** — no new uAPI; HID + discovery
   workaround on existing PMU.
6. Can apply to the local tree? **PASS** — driver, CMN-S3, DTM-index
   move, mesh check all present.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: **ACPI device ID** (`AMZN0070`) **and hardware quirk** for
customised CMN-S3.

**Step 9.4: MAKE YOUR DECISION**

This tree is 7.3-rc4, which already contains CMN-S3 and the series
prerequisite. The patch is the standard stable shape: ID + quirk so
existing `arm-cmn` works on shipping Graviton5. Benefit is real for that
platform; risk is low and mostly HID-gated.

---

## What the commit solves and why it matters here

Graviton5 implements CMN-S3 with discovery registers that read as zero
and a 10×14 mesh. In this tree, `arm_cmn_discover()` would then put
every XP in DTC domain 0, leave DTC logids at 0 (breaking IRQ sort
order), and reject the mesh as larger than 12. Adding `AMZN0070` and the
three workarounds makes the existing CMN PMU usable on that hardware
without new APIs.

It meets stable rules as a quirk/ID exception: small, reviewed, no uAPI,
applies cleanly here because `56603c28d9169` already moved DTM arrays
out of `hw_perf_event`.

Risk vs benefit: extra bitmap bytes for all CMN users vs a working
interconnect PMU on Graviton5. Favorable.

Concerns: not a panic-class bug; depends on the DTM-index move (already
in this tree). No stable-list confirmation (fetch failed).

---

## Verification

- [Phase 1] Parsed tags: R-b Robin Murphy + Ilkka Koskinen; SOB Aviv
  Bakal, Robin Murphy, Will Deacon; no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: `drivers/perf/arm-cmn.c` +31/−1; HID `AMZN0070`,
  `CMN_MAX_DIMENSION` 14, DTC domain/logid workarounds
- [Phase 2] Current tree still has graviton5 paths at `arm_cmn_discover`
  / `arm_cmn_graviton5_dtc_domain` / ACPI table
- [Phase 3] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` = 7.3.0-rc4
- [Phase 3] `git merge-base --is-ancestor 9d0b1714e1af1 HEAD` — yes; in
  v7.3-rc1, not v7.2
- [Phase 3] CMN-S3 `0dc2f4963f7ef` (2024-09-04) in tree; ACPI S3
  `8c138a189f6db` in tree
- [Phase 3] Mesh reject `36c0de02575ce` in tree; DTM move
  `56603c28d9169` in tree (series 1/2)
- [Phase 3] `git blame` on workaround lines → `9d0b1714e1af1`
- [Phase 3] No graviton follow-ups in `9d0b1714e1af1..HEAD`
- [Phase 4] `b4 dig -c 9d0b1714e1af1` → v6 2/2 msgid `e9340d3a4385e6f1a6
  e80bda944a3ba6435472b6.1782824005.git.robin.murphy@arm.com`
- [Phase 4] `b4 dig -a`: v1–v6; applied is v6
- [Phase 4] `b4 dig -w`: Will/Mark/Robin, linux-arm-kernel, linux-perf-
  users
- [Phase 4] Robin v2 review: must use `xp->logid` for firmware IRQ order
  (committed code does)
- [Phase 4] UNVERIFIED: lore.kernel.org/stable (403)
- [Phase 5] `arm_cmn_discover` only from `arm_cmn_probe`; ACPI match
  includes `AMZN0070`
- [Phase 6] Buggy discovery path and mesh check exist in this checkout;
  apply is clean
- [Phase 7] `CONFIG_ARM_CMN` depends on ARM64 || COMPILE_TEST
- [Phase 8] Failure: missing/wrong CMN PMU on Graviton5, not
  oops/deadlock; severity MEDIUM + quirk exception
- UNVERIFIED: Amazon Tested-by on silicon (not in tags)

**YES**

 drivers/perf/arm-cmn.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 527a953bf4744..688a94ef81c22 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -31,7 +31,8 @@
 #define CMN_CHILD_NODE_ADDR		GENMASK(29, 0)
 #define CMN_CHILD_NODE_EXTERNAL		BIT(31)
 
-#define CMN_MAX_DIMENSION		12
+/* Some implementations use a mesh larger than the architectural max of 12 */
+#define CMN_MAX_DIMENSION		14
 #define CMN_MAX_XPS			(CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
 #define CMN_MAX_DTMS			(CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4)
 
@@ -215,6 +216,8 @@ enum cmn_part {
 	PART_CMN700 = 0x43c,
 	PART_CI700 = 0x43a,
 	PART_CMN_S3 = 0x43e,
+	/* Synthetic part number, overridden to PART_CMN_S3 during discovery */
+	PART_GRAVITON5 = 0xa5,
 };
 
 /* CMN-600 r0px shouldn't exist in silicon, thankfully */
@@ -2217,6 +2220,18 @@ static unsigned int arm_cmn_dtc_domain(struct arm_cmn *cmn, void __iomem *xp_reg
 	return FIELD_GET(CMN_DTM_UNIT_INFO_DTC_DOMAIN, readl_relaxed(xp_region + offset));
 }
 
+static unsigned int arm_cmn_graviton5_dtc_domain(u16 xp_id)
+{
+	unsigned int x = (xp_id >> 7) & 0xf;
+	unsigned int y = (xp_id >> 3) & 0xf;
+
+	/*
+	 * The unit info register reads as zero; derive the DTC domain from
+	 * the XP's mesh coordinates over the 10x14 mesh.
+	 */
+	return (x / 5) + (y / 7) * 2;
+}
+
 static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node)
 {
 	int level;
@@ -2262,6 +2277,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 	u64 reg;
 	int i, j;
 	size_t sz;
+	bool graviton5_workaround = false;
 
 	arm_cmn_init_node_info(cmn, rgn_offset, &cfg);
 	if (cfg.type != CMN_TYPE_CFG)
@@ -2272,6 +2288,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 	reg = readq_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_01);
 	part = FIELD_GET(CMN_CFGM_PID0_PART_0, reg);
 	part |= FIELD_GET(CMN_CFGM_PID1_PART_1, reg) << 8;
+
+	/* Graviton5 has a customised CMN-S3 which needs some fixups */
+	if (cmn->part == PART_GRAVITON5) {
+		cmn->part = PART_CMN_S3;
+		graviton5_workaround = true;
+	}
+
 	/* 600AE is close enough that it's not really worth more complexity */
 	if (part == PART_CMN600AE)
 		part = PART_CMN600;
@@ -2361,6 +2384,8 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 
 		if (cmn->part == PART_CMN600)
 			xp->dtc = -1;
+		else if (graviton5_workaround)
+			xp->dtc = arm_cmn_graviton5_dtc_domain(xp->id);
 		else
 			xp->dtc = arm_cmn_dtc_domain(cmn, xp_region);
 
@@ -2439,6 +2464,10 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 
 			switch (dn->type) {
 			case CMN_TYPE_DTC:
+				if (graviton5_workaround) {
+					/* Node info logical ID is zeroed; use the XP's */
+					dn->logid = xp->logid;
+				}
 				cmn->num_dtcs++;
 				dn++;
 				break;
@@ -2671,6 +2700,7 @@ static const struct acpi_device_id arm_cmn_acpi_match[] = {
 	{ "ARMHC650" },
 	{ "ARMHC700" },
 	{ "ARMHC003" },
+	{ "AMZN0070", PART_GRAVITON5 },
 	{}
 };
 MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (12 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] perf/arm-cmn: Add workarounds for CMN-S3 on Graviton5 Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
                   ` (34 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, AngeloGioacchino Del Regno, Sasha Levin,
	matthias.bgg, linux-kernel, linux-arm-kernel, linux-mediatek

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit ec762057868d70d474a9816e9c293c2ef801c3c9 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local checkout is **7.3-rc4**. The DVFSRC driver is modular, had an
OF match table, and did not publish aliases, so autoload is broken for
`CONFIG_MTK_DVFSRC=m`. That is a real, one-line hardware-enablement bug.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[soc: mediatek] [add] [missing MODULE_DEVICE_TABLE() for OF
module autoload]**
- Subsystem: `soc: mediatek`
- Verb: **add** (missing export; the body is a fix, not a feature)
- Intent: publish the existing OF match table as module aliases

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Verified from `git show ec762057868d70`:
- Signed-off-by: Pengpeng Hou \<pengpeng@iscas.ac.cn\> (author)
- Signed-off-by: AngeloGioacchino Del Regno
  \<angelogioacchino.delregno@collabora.com\> (MediaTek SoC maintainer;
  applied the patch)
- No Fixes:, Reported-by, Tested-by, Reviewed-by, Acked-by, Link:, or
  Cc: stable
- Absence of Fixes:/Cc: stable is expected for this review and is not a
  negative

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** OF match table is wired to `.of_match_table` but not exported
  via `MODULE_DEVICE_TABLE(of, ...)`
- **Symptom:** `depmod`/`file2alias` never emit
  `of:N*T*Cmediatek,mtXXXX-dvfsrc` aliases, so udev/kmod will not
  autoload `mtk-dvfsrc.ko`
- **Version info:** none in the message. Driver landed in v6.13; this
  fix is in v7.3-rc4
- **Root cause:** forgotten alias publication on a tristate
  `module_platform_driver`

The extra “source-level fix / no dynamic hardware reproduction”
paragraph is in the original lore submission as well (not a stable-
pipeline marker).

Step 1.4: DETECT HIDDEN BUG FIXES
Record: **Not hidden.** It is an explicit autoload/modalias bug fix
disguised only by the verb “add”. Same class as a missing device-ID
table export.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/soc/mediatek/mtk-dvfsrc.c` (**+1 / −0**)
- One line after `mtk_dvfsrc_of_match[]`
- Scope: **single-file surgical fix**

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** match table exists and is used for platform binding, but
  no `__mod_of__mtk_dvfsrc_of_match` alias is generated
- **After:** `MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match)` creates that
  alias for `scripts/mod/file2alias.c`
- Affected path: **module build / autoload**, not probe logic. Built-in
  (`=y`) is unchanged at runtime

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- **Category:** hardware enablement / missing module alias (OF
  equivalent of a missing device ID table)
- **Mechanism:** without `MODULE_DEVICE_TABLE`, kmod cannot map DT
  `compatible` to `mtk-dvfsrc.ko`. Probe never runs unless the module is
  loaded by hand
- Not UAF, leak, race, or locking

Step 2.4: ASSESS THE FIX QUALITY
Record:
- **Obviously correct:** one standard macro next to the table, same
  pattern as `mtk-mmsys.c`, `mtk-svs.c`, `mtk-mutex.c` in this tree
- **Regression risk: negligible.** No runtime code, locking, or API
  change; only `.modinfo` aliases when built as a module

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Match table introduced in **192514ae05687** (“Add MediaTek DVFS
  Resource Collector (DVFSRC) driver”, AngeloGioacchino Del Regno, 2024)
- Present in **v6.13-rc1**; **not** in v6.12 or v6.6
- Original file already had `.of_match_table` and
  `module_platform_driver` and **never** had `MODULE_DEVICE_TABLE` (`git
  show 192514ae05687a:drivers/soc/mediatek/mtk-dvfsrc.c`)
- The one-line fix is **ec762057868d70** (Pengpeng Hou, 2026-07-04;
  applied 2026-07-30)

Step 3.2: FOLLOW THE FIXES: TAG
Record: **No Fixes: tag.** Bug is the original omission in
192514ae05687, which **is** an ancestor of this tree.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: later DVFSRC work (MT6893, MT8196, bandwidth rework) only grew
the match table. No prerequisite refactor is required for this one line.
**Standalone.**

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Pengpeng Hou has a series of the same “add missing
MODULE_DEVICE_TABLE()” fixes (rtc, vdpa, watchdog, hwmon, aspeed,
ixp4xx). This is a systematic audit, not a one-off. The applying
maintainer is the MediaTek SoC co-maintainer.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: **None.** Needs only `mtk_dvfsrc_of_match` and `module.h`, both
present since the driver was added. Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c ec762057868d70` →
  https://patch.msgid.link/20260704124308.6241-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only** (no v2/v3)
- Thread (saved via `b4 dig -m`): maintainer reply “Applied to
  v7.2-next/soc, thanks!” (commit 0ef07f74aff2 while in the MTK tree)
- No NAKs, no requested changes, no Cc: stable in review

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): To/Cc included both MediaTek SoC maintainers
(Matthias Brugger, AngeloGioacchino Del Regno) and linux-mediatek /
linux-arm-kernel / linux-kernel. Applied by the subsystem maintainer.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: **No Reported-by / bugzilla / syzbot.** Evidence is the source
mismatch (match table vs missing export), which is deterministic for
`=m` builds.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: not a numbered series. Sibling same-cycle fixes exist (`soc:
aspeed`, `soc: ixp4xx: npe/qmgr`). Each is self-contained. Historical
MediaTek analogs: `6f42f5e73bb43` (mtk-svs), `10687632307c0` (mtk-
mmsys).

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: **UNVERIFIED.** lore.kernel.org returned HTTP 403 for WebFetch
and curl. No local evidence of a stable NAK.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: **No function body changed.** The new line is
`MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match)` beside the existing
table. Related runtime entry is `mtk_dvfsrc_probe`.

Step 5.2: TRACE CALLERS
Record:
- `module_platform_driver(mtk_dvfsrc_driver)` → OF platform probe
- Exported `mtk_dvfsrc_send_request` / `mtk_dvfsrc_query_info` used by:
  - `drivers/interconnect/mediatek/icc-emi.c`
    (`INTERCONNECT_MTK_DVFSRC_EMI` depends on `MTK_DVFSRC`)
  - `drivers/regulator/mtk-dvfsrc-regulator.c` (`REGULATOR_MTK_DVFSRC`
    depends on `MTK_DVFSRC`)
- Probe also `devm_of_platform_populate()`, so child
  interconnect/regulator nodes never appear if this module never loads

Step 5.3: TRACE CALLEES
Record: probe does SMC init/start of the DVFSRC IP, clock enable, child
populate. Autoload failure means that entire stack never starts.

Step 5.4: FOLLOW THE CALL CHAIN
Record: **Userspace-reachable via normal boot on MediaTek DT platforms**
(kmod/udev matching `compatible`). Unprivileged users do not need a
special syscall; they just boot. Trigger requires `CONFIG_MTK_DVFSRC=m`
and a matching DT node.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: other `drivers/soc/mediatek/` drivers already have
`MODULE_DEVICE_TABLE(of, ...)`. This was the omission.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- `git describe HEAD` → **v7.3-rc4-27-gf0100363d8c37**; `make
  kernelversion` → **7.3.0-rc4**
- File and match table exist. Before ec762057868d70 there was **no**
  `MODULE_DEVICE_TABLE` (`git show ec762057868d70^:...`)
- Bug introduced with the driver in **v6.13** (192514ae05687)
- `git merge-base --is-ancestor ec762057868d70 HEAD` → yes (this
  checkout already contains the fix as mainline, which does not change
  whether the bug class is real)

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **clean apply.** One line after the sentinel entry. Compatible
strings may differ on older stables, but the macro is independent of
table contents.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: this is the fix. No earlier equivalent. Sibling SoC drivers
already had the macro.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record:
- **Subsystem:** `drivers/soc/mediatek` (MediaTek SoC DVFS resource
  collector)
- **Criticality: IMPORTANT** on ARCH_MEDIATEK (Chromebooks/boards with
  MT8183/MT8195/MT8196/MT6893), **PERIPHERAL** globally
- Kconfig: `config MTK_DVFSRC` **tristate**, `depends on ARCH_MEDIATEK`

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: actively maintained (MT8196/DVFSRCv4, bandwidth rework,
mmsys/cmdq work). DVFSRC itself is a few years old (6.13), not brand-new
staging code.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **platform-specific / config-specific** — `ARCH_MEDIATEK` +
`CONFIG_MTK_DVFSRC=m` + DT `compatible` in the match table. Built-in
configs are unaffected.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: boot (or DT overlay) with the module not already loaded
- Common on distro-style `=m` kernels; Chromebook/embedded images often
  use `=y` (then a no-op)
- Not a race; **100%** for modular builds
- Unprivileged user is not required beyond using the machine

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- **Failure:** DVFSRC module does not autoload → probe skipped → child
  devices not populated → interconnect EMI bandwidth votes and DVFSRC
  regulators return failure/`-ENODEV`
- Not an oops/UAF/corruption
- **Severity: MEDIUM** (device/stack does not come up; power/bandwidth
  management broken on those SoCs). For users who ship this as a module,
  it is a real “hardware doesn’t work” bug, in the same bucket as
  missing device IDs

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for modular MediaTek kernels; zero elsewhere
- **Risk:** very low (1 line, `.modinfo` only)
- **Ratio:** strongly favors including it

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

FOR:
- Real, deterministic autoload bug on a **tristate** driver that already
  has an OF table
- DVFSRC is the parent of interconnect and regulator children; missing
  autoload takes down that DVFS/bandwidth stack
- 1-line, standard `MODULE_DEVICE_TABLE(of, ...)` pattern already used
  by sibling MediaTek SoC drivers
- Applied by the MediaTek SoC maintainer; v1 accepted unchanged
- Same class as device-ID additions (explicit stable exception):
  existing driver, existing hardware, missing match publication
- Driver has been in this lineage since v6.13; the omission is old, not
  a just-landed feature

AGAINST:
- No user/syzbot report; author describes it as source-level
- Not a crash, deadlock, or data-corruption fix
- `=y` builds are unaffected; no in-tree defconfig sets
  `CONFIG_MTK_DVFSRC`
- No Cc: stable (expected here; not used as a negative)

UNRESOLVED:
- lore.kernel.org stable-list search (HTTP 403)
- Whether a given distro actually builds this as `=m` (unverified)

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — one established macro;
   maintainer applied v1
2. Fixes a real bug that affects users? **PASS** — module will not
   autoload for OF devices (`stable-kernel-rules.rst`: “real bug that
   bothers people **or** just add a device ID”)
3. Important issue? **PASS** as hardware-does-not-bind / missing ID-
   table export, not as a panic. Severity MEDIUM but in the device-ID
   exception class
4. Small and contained? **PASS** — +1 line, one file
5. No new features or APIs? **PASS** — only publishes an existing table
6. Can apply to the local tree? **PASS** — file and table exist; the
   line is already the correct form here

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: **Device ID / match-table publication for an existing driver.**
Closest documented exception: “just add a device ID.”

Step 9.4: MAKE YOUR DECISION
This is a one-line, obviously correct fix for a real modular-boot
failure on MediaTek SoCs that already have this driver. Risk is
negligible. It belongs in this tree’s stable lineage.

### What it solves for stable users
If `mtk-dvfsrc` is built as a module, kmod never gets `of:` aliases for
`mediatek,mt8183-dvfsrc` and the other compatibles. The driver never
probes, so DVFSRC children (EMI interconnect, DVFSRC regulators) never
appear. Adding `MODULE_DEVICE_TABLE` is the supported way to generate
those aliases (`include/linux/module.h` + `scripts/mod/file2alias.c`).

### Risk vs benefit
Benefit is restoring autoload for a SoC DVFS block; risk is a `.modinfo`
addition with no runtime logic change.

### Concerns
Needs no extra commits. Older stables without `mtk-dvfsrc.c` (pre-6.13)
would not apply; **this** checkout has the driver. Lore stable
discussion could not be fetched (403).

Verification:
- [Phase 1] `git show ec762057868d70`: subject/tags/body as above; no
  Fixes/Cc stable/Reported-by
- [Phase 2] Diff is exactly `+MODULE_DEVICE_TABLE(of,
  mtk_dvfsrc_of_match);` in `mtk-dvfsrc.c`
- [Phase 3] Blame: table from 192514ae05687; MODULE_DEVICE_TABLE line
  from ec762057868d70
- [Phase 3] `git show 192514ae05687a:drivers/soc/mediatek/mtk-dvfsrc.c`:
  of_match_table + module_platform_driver, no MODULE_DEVICE_TABLE
- [Phase 3] `git merge-base --is-ancestor 192514ae05687 v6.13-rc1` yes;
  not in v6.12
- [Phase 3] `git merge-base --is-ancestor ec762057868d70 HEAD` yes
- [Phase 4] `b4 dig -c/-a/-w/-m`: lore msgid
  20260704124308.6241-1-pengpeng@iscas.ac.cn; v1 only; maintainers CC’d;
  Angelo applied to v7.2-next/soc
- [Phase 4] lore.kernel.org HTTP 403 — stable-list discussion UNVERIFIED
- [Phase 5] Callers: `icc-emi.c`, `mtk-dvfsrc-regulator.c`; Kconfig
  `depends on MTK_DVFSRC`; probe uses `devm_of_platform_populate`
- [Phase 5] `CONFIG_MTK_DVFSRC` is tristate in
  `drivers/soc/mediatek/Kconfig`
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37;
  kernelversion 7.3.0-rc4
- [Phase 6] Pre-commit file has match table and no MODULE_DEVICE_TABLE
- [Phase 7] MAINTAINERS: ARM/Mediatek SoC support → AngeloGioacchino Del
  Regno (applier)
- [Phase 8] Failure mode: module not autoloaded → DVFSRC/DVFS stack
  down; not an oops
- UNVERIFIED: distro `=m` vs `=y` defaults; stable@ lore thread

**YES**

 drivers/soc/mediatek/mtk-dvfsrc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 41add5636b03c..af35d71615baf 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -562,6 +562,7 @@ static const struct of_device_id mtk_dvfsrc_of_match[] = {
 	{ .compatible = "mediatek,mt8195-dvfsrc", .data = &mt8195_data },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match);
 
 static struct platform_driver mtk_dvfsrc_driver = {
 	.probe	= mtk_dvfsrc_probe,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (13 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
                   ` (33 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin,
	chester.a.unal, olteanv, davem, edumazet, pabeni, matthias.bgg,
	angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
	linux-mediatek

From: Daniel Golle <daniel@makrotopia.org>

[ Upstream commit 1c95dcb7e923beebccdc79adc3dc1ec8c52295d0 ]

MT7531_PHY_ACS_ST is only ever set by the command write that precedes
each poll in the MT7531 indirect PHY access functions, and that
write's return value is discarded. A failed write leaves ACS_ST at 0
from the previous access, so the poll succeeds on its first iteration
and the functions return stale IAC contents as if they were fresh PHY
data. Check the writes and bail out before polling.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/c34602e63a20ebbfb97babd145c82832d7a0b523.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[net/dsa/mt7530] [error out] Check PHY_IAC command writes and
abort on failure instead of polling stale IAC contents.**

**Step 1.2: Tags**
Record (candidate message, ignoring pipeline SOBs):
- **Reviewed-by:** Andrew Lunn `<andrew@lunn.ch>` (DSA reviewer)
- **Link:** `https://patch.msgid.link/c34602e63a20ebbfb97babd145c82832d7
  a0b523.1785811140.git.daniel@makrotopia.org`
- **Signed-off-by:** Daniel Golle (author; MediaTek switch co-
  maintainer)
- **Signed-off-by:** Jakub Kicinski (netdev)
- No Reported-by / Tested-by / syzbot / Cc: stable in the candidate text

Independent of the candidate text, the original LKML submission also had
**`Fixes: c288575f7810 ("net: dsa: mt7530: Add the support of MT7531
switch")`**. That tag is not used as a “already selected” signal; it
only identifies the introducing commit.

**Step 1.3: Body**
Record:
- **Bug:** `MT7531_PHY_ACS_ST` is set only by the command write before
  each poll. The write return is discarded.
- **Failure mode:** A failed write leaves ACS_ST at 0 from the previous
  access. The poll condition `!(val & MT7531_PHY_ACS_ST)` is already
  true, so the poll returns immediately and the helpers treat leftover
  IAC contents as a completed PHY access.
- **Symptom:** Reads return stale IAC data as PHY register values;
  writes return poll-success (`0`) even though the PHY was not written.
- **Root cause:** Missing error check on `mt7530_mii_write()` of
  `MT7531_PHY_IAC`.
- **Version info in body:** none. Introducing commit is from 2020.

**Step 1.4: Hidden bug fix?**
Record: **Not hidden.** This is an explicit error-propagation fix, not a
cleanup.

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- **File:** `drivers/net/dsa/mt7530.c` only
- **Scope:** ~+12 / −6 (six identical two-line checks)
- **Functions:** `mt7531_ind_c45_phy_read`, `mt7531_ind_c45_phy_write`,
  `mt7531_ind_c22_phy_read`, `mt7531_ind_c22_phy_write`
- **Classification:** single-file surgical error-path fix

**Step 2.2: Code flow**
Record: each helper already polls until ACS_ST is clear, writes a
command with ACS_ST set, then polls again. **Before:**
`mt7530_mii_write()` result is ignored; polling always runs. **After:**
a negative write return jumps to `out`, which already unlocks the MDIO
mutex and returns `ret`.

**Step 2.3: Bug mechanism**
Record: **logic / error-path correctness.** ACS_ST is `BIT(31)` of
`MT7531_PHY_IAC` (`0x701C`). Poll success is “bit clear.” A failed
command write never sets that bit, so the poll succeeds on the first
iteration.

Verified on the write helpers: after a successful poll, `ret` is `0`
from `regmap_read_poll_timeout()`, so a failed PHY write is currently
reported as **success**. On reads, `ret = val &
MT7531_MDIO_RW_DATA_MASK` returns leftover IAC data as a 16-bit PHY
value.

**Step 2.4: Fix quality**
Record: **obviously correct.** Same `goto out` path already used for
poll failures. No new locks, APIs, or data structures. Regression risk
is low: only failed bus writes change behavior, and they now return the
real errno instead of fake success / stale data.

## Phase 3: Git history

**Step 3.1: Blame**
Record: the unchecked `mt7530_mii_write(..., MT7531_PHY_IAC, ...)` lines
were introduced in **`c288575f7810` (Landen Chao, 2020-09-11), “Add the
support of MT7531 switch”**. `mt7530_mii_write()` has returned `int`
since **`a08c045580e060` (2023-04-03, regmap conversion)**. Both are in
this tree.

**Step 3.2: Fixes: target**
Record: `git merge-base --is-ancestor c288575f7810 HEAD` succeeded. The
bug is in this 6.12 tree. No later local commit already checks these
writes (`ret = mt7530_mii_write(priv, MT7531_PHY_IAC` count is 0).

**Step 3.3: File history / related commits**
Record: this tree already contains the sibling **`96e0f5184af69`**
(`v6.12.103~217`), “error out on failed reads in MT7531 PHY polling”
(upstream `77a9ebe8818cf6`). That converted the polls to
`regmap_read_poll_timeout()` but left command writes unchecked. Also
present: **`93d46870c5440`**, “check bus->read() errors in the MDIO
regmap backend” — same author, same class of swallowed MDIO errors.

**Step 3.4: Author**
Record: Daniel Golle is listed as a **MEDIATEK SWITCH DRIVER**
maintainer. Other mt7530 error-propagation fixes by him are already in
this tree.

**Step 3.5: Dependencies**
Record: **standalone.** Needs `mt7530_mii_write()` returning `int` and
the existing `goto out` + mutex unlock — all present. It does **not**
need the rest of the later 6-patch series (`core_rmw`, CORE_PLL_GROUP4,
FDB/VLAN writes, IRQ serialization).

## Phase 4: Mailing list

**Step 4.1:** Candidate is not a local commit, so `b4 dig -c` on this
SHA was not possible. `b4 dig -c 96e0f5184af69` found the earlier poll-
timeout series. This patch was submitted as **`[PATCH net 3/4]`** then
**`[PATCH net v2 3/6]`** in “fix remaining swallowed MDIO access
errors.”
Record: lore/msgid `c34602e63a20ebbfb97babd145c82832d7a0b523.1785811140.
git.daniel@makrotopia.org`; LKML copy at
https://lkml.iu.edu/hypermail/linux/kernel/2608.0/04802.html. **v2: no
changes** to this patch. Cover letter: this write check was a companion
that had been folded into the already-applied PHY-polling patch and was
split out. No NAKs found.

**Step 4.2:** Recipients included DSA/netdev maintainers (Lunn, Oltean,
Kicinski, netdev). Andrew Lunn replied **Reviewed-by** with no requested
changes (https://www.spinics.net/lists/kernel/msg6350713.html).

**Step 4.3:** No syzbot or bugzilla. Mechanism is from code review
(cover letter: Sashiko AI review of the earlier series).

**Step 4.4:** Series mates are independent swallowed-error checks. This
hunk set does not depend on them.

**Step 4.5:** Search of lore.kernel.org/stable for this subject found
**no** prior stable discussion or rejection.

## Phase 5: Semantic / call graph

semcode MCP is not available; callers were found with grep.

**Step 5.1:** Functions listed in 2.1.

**Step 5.2: Callers**
- Wired as `phy_read/write_c22/c45` for **ID_MT7531, ID_MT7988,
  ID_EN7581** in `mt753x_table`.
- MDIO bus ops: `mt7530_setup_mdio()` sets
  `bus->read/write/read_c45/write_c45` to wrappers that call these
  helpers. That is the phylib/phylink path (link polling, PHY config).
- Direct: `mt7531_setup()` uses `mt7531_ind_c45_phy_read/write` for
  CORE_PLL_GROUP4 / EEE (those call sites still ignore the return; a
  later series patch addresses that and is **not** required for this
  MDIO-bus fix).

**Step 5.3: Callees**
`mt7530_mutex_lock/unlock`, `mt7530_mii_write` → `regmap_write`,
`regmap_read_poll_timeout`.

**Step 5.4: Reachability**
Yes, from userspace-visible networking: phylib MDIO reads/writes on
MT7531/MT7988/EN7581 switch PHYs. Trigger is a failed switch register
write (MDIO/MMIO/regmap error), not a rare debug ioctl.

**Step 5.5:** Same swallowed-error pattern already fixed for MDIO
backend reads and PHY_IAC **polls** in this tree. This is the remaining
write side of that PHY_IAC path.

## Phase 6: This tree (6.12.y)

**Step 6.1:** Local tree is **`pending-6.12` / 6.12.111**. All six
PHY_IAC command writes are still unchecked. Bug exists here.

**Step 6.2:** Current source matches the patch “before” context
(including `regmap_read_poll_timeout` from `96e0f5184af69`). **Expected
apply: clean.**

**Step 6.3:** No other local commit already checks these writes. The
poll-timeout backport left this hole open; this is the companion.

## Phase 7: Subsystem

**Step 7.1:** `drivers/net/dsa/mt7530.c` — MediaTek DSA switch.
**IMPORTANT** (not core mm/VFS, but common on MT7988/MT7531 routers,
OpenWrt, embedded). Config: `NET_DSA_MT7530`.

**Step 7.2:** File is actively maintained; several mt7530 fixes already
landed in this 6.12 branch.

## Phase 8: Impact and risk

**Step 8.1:** Users of MT7531, MT7988, and EN7581 switches (not
MT7530/MT7621, which use nested `mdiobus_*` instead of these indirect
helpers).

**Step 8.2:** Triggers on failed `regmap_write` of PHY_IAC. Unprivileged
users do not need a special exploit; phylib link/config traffic hits
this path. Frequency is error-path, but MDIO/MMIO glitches on these
boards are real.

**Step 8.3:** Failure mode: **silent wrong PHY data / false write
success**, not an oops. Phylib can see a live link or apply settings
that never reached the PHY. Severity: **HIGH** for networking
correctness on error; not a panic.

**Step 8.4:**
- **Benefit:** Completes the already-backported PHY_IAC poll hardening;
  stops fake-success writes and stale reads.
- **Risk:** Very low (12 lines, error path only).
- **Ratio:** Favorable.

## Phase 9: Synthesis

**For backporting**
- Real bug with a verified mechanism (ACS_ST only set by the discarded
  write).
- Write helpers currently return **0 on a failed PHY write**.
- Small, obviously correct, maintainer-authored, Reviewed-by Andrew
  Lunn.
- Buggy code and `Fixes:` target are in this 6.12 tree.
- Sibling poll-timeout fix is already here; this closes the remaining
  hole that series called out.
- Applies cleanly; no new API.

**Against**
- Error-path only (healthy bus never hits it).
- Driver-specific, not a universal crash/UAF.
- No user crash report; found by review.

**Unresolved**
- Could not `b4 dig` this exact SHA (not in the checkout); lore/LKML
  used instead.
- lore.kernel.org WebFetch returned 403; discussion taken from
  LKML/spinics.

**Stable rules**
1. Obviously correct and tested? **PASS** (Reviewed-by Lunn; merged via
   netdev)
2. Real user-visible bug? **PASS** (false MDIO success / stale PHY data)
3. Important? **PASS** (silent PHY misconfiguration; same class as
   already-backported mt7530 MDIO error fixes)
4. Small/contained? **PASS** (~12 lines, one file)
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS**

Not an ID/quirk/DT/docs exception; it qualifies as a normal contained
bugfix.

This should be backported to this 6.12 tree: the bug is present, the fix
is surgical, and it finishes error handling that 6.12 already took for
the same helpers.

Verification:
- [Phase 1] Parsed candidate tags: Reviewed-by Andrew Lunn, msgid link,
  Golle/Kicinski SOBs; original LKML also had Fixes: c288575f7810
- [Phase 2] Diff: six `ret = mt7530_mii_write(); if (ret < 0) goto out;`
  in four PHY_IAC helpers
- [Phase 2] Header: ACS_ST is BIT(31); poll waits for it clear —
  confirmed in mt7530.h
- [Phase 2] Write helpers return poll `ret` (0 on success) — failed
  write currently looks successful
- [Phase 3] Blame: writes from c288575f7810 (2020); ancestor of HEAD
- [Phase 3] Sibling 96e0f5184af69 already in tree (v6.12.103~217);
  93d46870c5440 MDIO read-error fix also in tree
- [Phase 3] `git log --grep='PHY_IAC command writes'` on this file:
  empty
- [Phase 4] LKML v2 3/6: “v2: no changes”; Lunn Reviewed-by, no NAK
- [Phase 4] Cover letter: companion to already-applied PHY polling patch
- [Phase 4] stable@ search: no hits
- [Phase 5] Callers: mt753x_table ID_MT7531/MT7988/EN7581;
  bus->read/write in mt7530_setup_mdio
- [Phase 6] `git describe HEAD` / Makefile: 6.12.111 pending-6.12; six
  unchecked PHY_IAC writes remain
- [Phase 6] Current lines match the patch context (including
  regmap_read_poll_timeout)
- [Phase 7] MAINTAINERS: Daniel Golle is MediaTek switch co-maintainer
- [Phase 8] Failure: stale PHY data / false write success, not oops
- UNVERIFIED: b4 dig of this exact mainline SHA (commit not in
  checkout); lore.kernel.org 403

**YES**

 drivers/net/dsa/mt7530.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index bd0a37ead0dec..24c7cb225da1a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -557,7 +557,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
 
 	reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_DEV_ADDR(devad) | regnum;
-	mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
 				       !(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -568,7 +570,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
 
 	reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_DEV_ADDR(devad);
-	mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
 				       !(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -602,7 +606,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
 
 	reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_DEV_ADDR(devad) | regnum;
-	mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
 				       !(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -613,7 +619,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
 
 	reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_DEV_ADDR(devad) | data;
-	mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
 				       !(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -646,7 +654,9 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
 	val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_REG_ADDR(regnum);
 
-	mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
 				       !(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -681,7 +691,9 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
 	reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
 	      MT7531_MDIO_REG_ADDR(regnum) | data;
 
-	mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+	if (ret < 0)
+		goto out;
 
 	ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, reg,
 				       !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (14 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
                   ` (32 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin,
	chester.a.unal, olteanv, davem, edumazet, pabeni, matthias.bgg,
	angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
	linux-mediatek

From: Daniel Golle <daniel@makrotopia.org>

[ Upstream commit 573d6e3afe3d01e34dc82c77bf22ca96a74d805e ]

core_rmw() accesses the MMD core registers directly rather than
through the regmap and has the same unchecked bus->read() as the
one just fixed in the MDIO regmap backend: a negative errno is
consumed as register data, modified and written back to the switch.
Check the read and bail out like the surrounding bus accesses do.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/48bb9f0b311a9efeda2a6b24a7e05d4792393a3b.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: `[net: dsa: mt7530]` [`check`] [detect `bus->read()` failure in
`core_rmw()` instead of treating errno as register data]

**Step 1.2: Tags**
Record:
- `Signed-off-by: Daniel Golle <daniel@makrotopia.org>` (author)
- `Reviewed-by: Andrew Lunn <andrew@lunn.ch>` (DSA co-maintainer)
- `Link: https://patch.msgid.link/48bb9f0b311a9efeda2a6b24a7e05d4792393a
  3b.1785811140.git.daniel@makrotopia.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer)
- No `Fixes:` in the committed message
- Mailing-list submission **did** include `Fixes: b8f126a8d543 ("net-
  next: dsa: add dsa support for Mediatek MT7530 switch")` (verified in
  the saved mbox); it was dropped before mainline
- No `Reported-by:`, `Tested-by:`, `Cc: stable` in the committed message
  (absence is expected)

**Step 1.3: Body**
Record:
- **Bug:** `core_rmw()` talks to MMD core registers via raw
  `bus->read()`/`bus->write()`, not regmap. A failed `bus->read()`
  returns a negative errno, which is used as the current register value,
  masked/ORed, and written back.
- **Symptom:** garbage RMW into switch MMD registers (clock-gate bits on
  this path).
- **Root cause:** same unchecked-read pattern as the MDIO regmap
  backend, which this tree already has as `93d46870c5440`.
- **Version info:** none in the body. The inlined form is from
  `7c5e37d7ee78d` (v6.11 era, present here). The mailing-list `Fixes:`
  points at the 2017 driver introduction; the old
  `core_read_mmd_indirect()` had the same unchecked read.

**Step 1.4: Hidden bug fix?**
Record: Not hidden. Explicit error-path correctness fix: missing check →
errno treated as data → written to hardware.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/net/dsa/mt7530.c`
- Scope: ~5 insertions / 1 deletion in one function
- Function: `core_rmw()`
- Classification: single-file surgical fix

**Step 2.2: Code flow**
Record:
- **Before:** after three checked MMD address writes, `val =
  bus->read(...)`. No check. `val &= ~mask; val |= set;` then
  `bus->write(...)`.
- **After:** `ret = bus->read(...)`; if `ret < 0` goto the existing
  `err` path (log + unlock); else `val = ret` and continue the RMW.
- Path: error path of an MDIO read during RMW. Normal success path
  unchanged.

**Step 2.3: Bug mechanism**
Record:
- Category: logic / correctness on an error path (errno consumed as
  register data, then written back). Same class as the already-present
  MDIO regmap fix.
- `mii_bus->read` returns a 16-bit value or a negative errno
  (`include/linux/mdio.h`: “returns value or negative error code”).
  `val` is `u32`, so `-ETIMEDOUT` (-110) becomes `0xffffff92`.
  `bus->write()` takes `u16`, so the switch sees `0xff92` with the
  intended bit tweaks, not the real register contents.
- Mechanism: check `ret < 0` and skip the write, matching the
  surrounding writes.

**Step 2.4: Fix quality**
Record:
- Obviously correct; copies the existing write-error pattern in the same
  function.
- Minimal; no unrelated edits, no API change.
- Regression risk: very low. On read failure it no longer writes.
  `core_rmw()` is still `void` and still only logs (pre-existing); this
  patch does not invent a new return convention.
- `val = ret` after the check is safe: success values are 0..0xffff.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record:
- Unchecked read at lines 155–156: `7c5e37d7ee78d` (“simplify core
  operations”, Arınç ÜNAL, 2024-04-18).
- That commit inlined `core_read_mmd_indirect()`, which already returned
  `bus->read()` without checking. The defect dates to `b8f126a8d543`
  (2017), driver introduction.
- Inlined form is in this tree (`git merge-base --is-ancestor
  7c5e37d7ee78d HEAD` succeeded). `git describe --contains` places it
  around v6.11-rc1, so it is in 6.12.

**Step 3.2: Fixes: tag**
Record: No `Fixes:` on the committed patch. Submission tagged
`b8f126a8d543`, which **is** an ancestor of this tree. Intermediate:
`7c5e37d7ee78d` inlined the helper and kept the bug.

**Step 3.3: File history**
Record:
- This tree already has the sibling: `93d46870c5440` “check bus->read()
  errors in the MDIO regmap backend”.
- Also: `96e0f5184af69` “error out on failed reads in MT7531 PHY
  polling”.
- Candidate `573d6e3afe3d0` is **not** an ancestor of HEAD.
- Standalone vs series: mailing-list subject is `[PATCH net v2 2/6]`.
  Diff does not depend on 1/6 or 3–6/6.

**Step 3.4: Author**
Record: Daniel Golle is a regular MT7530 contributor (OpenWrt/MediaTek).
Nearby commits by him in this tree are the other MDIO-error fixes.
Reviewed by Andrew Lunn.

**Step 3.5: Dependencies**
Record: None for this hunk. It uses existing `ret`, `goto err`, and
`bus->read`/`bus->write`. `git apply --check` succeeded (hunk offset 28
lines only).

---

## Phase 4: Mailing list / external research

**Step 4.1: Original discussion**
Record:
- `b4 dig -c 573d6e3afe3d0` → https://patch.msgid.link/48bb9f0b311a9efed
  a2a6b24a7e05d4792393a3b.1785811140.git.daniel@makrotopia.org
- Series: `[PATCH net v2 0/6] net: dsa: mt7530: fix remaining swallowed
  MDIO access errors`
- v2: “no changes” for this patch; Andrew’s `Reviewed-by` kept.
- Cover letter: leftover companion of the first “swallowed MDIO read
  errors” series (already on `net`); this is the unchecked `bus->read()`
  in `core_rmw()`.
- Sent to `net` (fixes), not `net-next`.
- No NAK in the saved mbox. Applied by Jakub Kicinski (`0200d48477602`
  merge).

**Step 4.2: Recipients (`b4 dig -w`)**
Record: Andrew Lunn, Vladimir Oltean, netdev maintainers, MediaTek,
`netdev@`, `linux-mediatek@`. Right audience. Lunn reviewed.

**Step 4.3: Bug report**
Record: No syzbot/bugzilla. Found by review of the same MDIO-error class
(cover letter cites Sashiko AI review of the parent series).

**Step 4.4: Series**
Record: 6 patches. This is 2/6 and is self-contained. 3–5/6 are other
swallowed-error sites; 1/6 is `pcs-mtk-lynxi`; 6/6 is IRQ-chip
serialization. Not required for this hunk.

**Step 4.5: Stable list**
Record: **UNVERIFIED** — lore.kernel.org returned 403/503 to
WebFetch/curl. No local evidence this was rejected for stable.

---

## Phase 5: Code semantics

**Step 5.1: Functions**
Record: `core_rmw()` only.

**Step 5.2: Callers**
Record:
- `core_set()` / `core_clear()` → `core_rmw()`
- `mt7530_pll_setup()`: clear/set `REG_GSWCK_EN` on
  `CORE_TRGMII_GSW_CLK_CG` (switch setup, 40 MHz XTAL)
- `mt7530_setup_port6()`: clear/set `REG_TRGMIICK_EN` (port 6 TRGMII
  clock)
- `mt7530_pll_setup()` from `mt7530_setup()` (~line 2422)
- `mt7530_setup_port6()` from `mt7530_mac_config()` when `port == 6`

**Step 5.3: Callees**
Record: `mt7530_mutex_lock/unlock`, `bus->write`, `bus->read`,
`dev_err`.

**Step 5.4: Reachability**
Record: Yes, from DSA probe/setup and phylink MAC config on MT7530
(common in MediaTek routers). Not a syscall hot path; hit on bring-up
and port-6 mode changes. Userspace/netlink can trigger `mac_config`.

**Step 5.5: Similar patterns**
Record: Same bug already fixed in `mt7530_regmap_read()` in this tree.
`core_write()` only writes (no analogous read). Remaining siblings
(PHY_IAC writes, CORE_PLL_GROUP4, FDB/VLAN cmd) are other series
patches, not prerequisites.

---

## Phase 6: This tree (6.12.y)

**Step 6.1: Buggy code present?**
Record: Yes. Tree is `pending-6.12` / `6.12.111`
(`p-6.12-4-gbf6fcdf761abd`). Current `core_rmw()` still does `val =
bus->read(...)` with no check (`drivers/net/dsa/mt7530.c:155-156`).
`573d6e3afe3d0` is not an ancestor of HEAD.

**Step 6.2: Backport difficulty**
Record: Clean apply (`git apply --check`: hunk succeeded at offset 28).
Surrounding `core_rmw()` matches the pre-image.

**Step 6.3: Related fixes already here?**
Record: Regmap-backend check is here; PHY polling check is here. This
leftover `core_rmw()` instance is not. No alternate fix of this
function.

---

## Phase 7: Subsystem context

**Step 7.1**
Record: `drivers/net/dsa/mt7530.c` — MediaTek MT7530 DSA. **IMPORTANT**
(common embedded/router switch), not core mm/VFS, not staging.

**Step 7.2**
Record: Actively maintained; recent 6.12 backports already include other
MT7530 MDIO-error and hardware fixes.

---

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
Record: Driver-specific: `CONFIG_NET_DSA_MT7530` (MDIO-attached
MT7530/MT7531, common on MT7621/MT798x-class boards).

**Step 8.2: Trigger**
Record: `bus->read()` failure during PLL/clock RMW (timeout, NACK, flaky
MDIO). Not every boot if the bus is healthy. Unprivileged users do not
trigger MDIO failure directly; they can hit the RMW via interface/port
config. Timing/hardware dependent.

**Step 8.3: Failure mode**
Record: On MDIO read failure, a truncated errno (e.g. `0xff92`) is
written to `CORE_TRGMII_GSW_CLK_CG` (core / TRGMII clock gates) instead
of toggling bit 0 or 1. That can leave clocks misconfigured (no link /
switch not forwarding) rather than failing closed. Severity: **HIGH** on
that error path (hardware misconfiguration), not a panic/UAF.

**Step 8.4: Risk-benefit**
Record:
- Benefit: stops garbage writes to switch clock-gate MMDs; completes the
  same class already backported via the regmap patch.
- Risk: very low (4–5 lines, existing `err` path, no locking/API
  change).
- Ratio: favorable.

---

## Phase 9: Synthesis

**For backporting**
- Real bug: negative MDIO errno used as register data and written back.
- Consequence: corrupt RMW of switch clock-gate registers.
- Small, obviously correct, reviewed by Andrew Lunn, taken into `net` as
  a fix.
- Buggy code is in this 6.12 tree; patch applies cleanly.
- Same class as `93d46870c5440`, already in this tree; this is the
  leftover `core_rmw()` site.

**Against**
- Error path only (MDIO must already be failing).
- Still `void`; errors are only logged (pre-existing).
- No syzbot/user crash report.
- Labelled 2/6, but this hunk does not need the rest.

**Unresolved**
- Stable-list discussion (lore 403/503). Does not change the technical
  case.

**Stable rules**
1. Obviously correct and tested? **PASS** — matches surrounding checks;
   Lunn `Reviewed-by`; in mainline `net`.
2. Real user-affecting bug? **PASS** — garbage written to MT7530 clock-
   gate MMDs on read failure.
3. Important (crash/security/corruption/deadlock)? **PASS** — hardware
   misconfiguration of switch clocks; same class already accepted in
   this tree.
4. Small and contained? **PASS** — ~5 lines, one function.
5. No new features/APIs? **PASS**.
6. Applies to this tree? **PASS** — `git apply --check` clean.

**Exception category:** none (not an ID/quirk/DT/build/doc exception).
Qualifies as a normal small driver bugfix.

---

### What the commit solves for this tree

In 6.12, `core_rmw()` still assigns `bus->read()` to `u32 val` without
checking. On timeout/NACK that errno is masked, OR’d, and written to
`CORE_TRGMII_GSW_CLK_CG` during PLL setup and port-6 TRGMII clock
enable. The fix bails out like the three preceding writes. It is the
companion to the regmap-backend check already present here.

Risk is negligible; benefit is avoiding a bad clock-gate RMW when MDIO
fails on a widely used MediaTek DSA switch.

Verification:
- [Phase 1] Parsed tags: Lunn `Reviewed-by`, msgid link; no committed
  `Fixes:`; mbox had `Fixes: b8f126a8d543`
- [Phase 2] Diff: 5 insertions in `core_rmw()`; check `ret < 0` before
  RMW write
- [Phase 3] Blame: inlined by `7c5e37d7ee78d` (v6.11, in this tree);
  original unchecked read in `b8f126a8d543` (2017)
- [Phase 3] `git merge-base --is-ancestor 573d6e3afe3d0 HEAD` → not in
  tree; `7c5e37d7ee78d` is in tree
- [Phase 3] Sibling `93d46870c5440` is in this tree
- [Phase 4] `b4 dig -c 573d6e3afe3d0`: v2 2/6 of “fix remaining
  swallowed MDIO access errors”; v2 no changes; Lunn review on 1–3 and 6
- [Phase 4] Cover letter: leftover `core_rmw()` companion of the first
  MDIO-error series
- [Phase 4] `b4 dig -w`: netdev + DSA + MediaTek CCs
- [Phase 4] lore WebFetch/curl 403/503; thread recovered via `b4 dig -m`
- [Phase 5] Callers: `mt7530_pll_setup`, `mt7530_setup_port6` → DSA
  setup / `mac_config`
- [Phase 5] `bus->read` contract: value or negative errno
  (`include/linux/mdio.h`)
- [Phase 6] `git describe HEAD`: `p-6.12-4-gbf6fcdf761abd`; `make
  kernelversion`: 6.12.111; buggy `val = bus->read` still at
  mt7530.c:155
- [Phase 6] `git apply --check` of `573d6e3afe3d0`: succeeded (offset
  28)
- [Phase 8] Failure mode: truncated errno written to
  `CORE_TRGMII_GSW_CLK_CG`; severity HIGH on that error path
- UNVERIFIED: whether stable@ discussed this commit (lore unreachable)

**YES**

 drivers/net/dsa/mt7530.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 24c7cb225da1a..d2dcc2f1522f4 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -124,8 +124,12 @@ core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
 		goto err;
 
 	/* Read the content of the MMD's selected register */
-	val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+	ret = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
 			MII_MMD_DATA);
+	if (ret < 0)
+		goto err;
+	val = ret;
+
 	val &= ~mask;
 	val |= set;
 	/* Write the data into MMD's selected register */
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (15 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] perf: marvell: Cancel CN10K DDR PMU hrtimer on device remove Sasha Levin
                   ` (31 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: David Bauer <mail@david-bauer.net>

[ Upstream commit 965cbdbdfbd37a659a05ff88e49c216975bd9d2e ]

The SKB containing the generated beacon is not freed when the beacon
queue is deected stuck and scheduled for recovery.

Fixes potential memory leaks in case the beacon queue is detected stuck.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.6.157** (`pending-6.6`). The two-line SKB leak is
present here, was introduced by a commit already in this tree, and
applies cleanly.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[wifi: mt76: mt7603]** **[free]** **[free the generated beacon
SKB when queue-stuck recovery bails out]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Fixes:** none (expected for this pipeline)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none
- **Acked-by:** none
- **Link:**
  `https://patch.msgid.link/20260611215658.259324-1-mail@david-
  bauer.net`
- **Cc: stable:** none (expected)
- **Signed-off-by:** David Bauer (author); Felix Fietkau (mt76
  maintainer). Ignore any Sasha Levin SOB if present in candidate
  wrapping.

Mainline SHA (from `origin/master`):
`965cbdbdfbd37a659a05ff88e49c216975bd9d2e`
AuthorDate: 2026-06-11; applied by Felix Fietkau 2026-07-31.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** After `ieee80211_beacon_get()`, if `mt76_poll()` times out on
  `MT_DMA_FQCR0` (beacon/BMC queue flush stuck), the function `goto out`
  without freeing the SKB.
- **Symptom:** SKB leak whenever the beacon queue is detected stuck and
  recovery is scheduled. Commit message typo: “deected”.
- **Version info:** none in the message.
- **Root cause (author):** beacon SKB not freed on the stuck-queue error
  path.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not a disguised cleanup. Explicit leak fix: two
`dev_kfree_skb(skb)` calls on error paths.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c` (**+2 /
  -0**)
- Function: `mt7603_update_beacon_iter()`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record (both hunks, same pattern):

Before: `ieee80211_beacon_get()` allocates `skb`. Flush BCN or BMC via
`MT_DMA_FQCR0`. If poll times out: set `dev->beacon_check =
MT7603_WATCHDOG_TIMEOUT` and `goto out`. Unlock. **SKB never queued and
never freed.**

After: same, but `dev_kfree_skb(skb)` before `goto out`.

Success path unchanged: `mt76_tx_queue_skb()` still takes ownership.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** error-path resource leak (SKB)
- **Mechanism:** mac80211 docs: *“The driver is responsible for freeing
  the returned skb.”* Error `goto` skipped both queueing and free. Fix
  adds the missing free.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Obviously correct; only the two error returns; no API/lock/structure
  change.
- **Regression risk:** very low. Success path still hands the SKB to
  DMA. `dev_kfree_skb` is `consume_skb` (stats slightly less precise
  than `kfree_skb` on a drop); maintainer accepted it. No double-free:
  frees only happen before queueing.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Leak `goto out` introduced by **`8caa9dd3d1a7c9`** “wifi: mt76:
  mt7603: improve stuck beacon handling” (Greg KH, 2023-11-20), stable
  rewrite of upstream **`3176205933494`** (Felix Fietkau, 2023-07-28).
- `ieee80211_beacon_get(..., 0)` from `6e8912a503759` (MLO 3-arg API);
  already in this tree.
- Driver added in `c8846e1015022` (2018). Pre-2023 code queued the SKB
  even if poll failed; the 2023 change moved queueing after the polls
  and added the leaky `goto`.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No Fixes: tag. Buggy commit in **this** tree is `8caa9dd3d1a7c9`
(`git merge-base --is-ancestor` = yes). Upstream `3176205933494` is not
an ancestor (stable SHA rewrite). No later origin/master commits touch
this file after `965cbdbdfbd37`.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record (this tree, path-limited): last functional change on this file is
the stuck-beacon commit itself. Standalone; not patch X/Y.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: David Bauer already has mt76 commits in this tree (including
mt7603 EEPROM ID). Felix Fietkau is listed maintainer and applied the
patch.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: None. Same function, same `ieee80211_beacon_get(hw, vif, 0)`,
same poll/`goto out`. `git apply --check` of `965cbdbdfbd37` succeeded.
Standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c 965cbdbdfbd37` →
  https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
- `b4 dig -a`: **v1 only**
- Thread mbox: patch only, **no replies**, no NAK, no reviewer Cc:
  stable
- lore.kernel.org WebFetch: **403** (used b4 + openwall/patchew mirrors)

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): To/Cc included Felix Fietkau, Lorenzo Bianconi,
MediaTek mt76 reviewers, linux-wireless. Applied by Felix with his SOB.
No Reviewed-by.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No Reported-by, syzbot, or bugzilla. Author-found leak on code
inspection. Openwall/Ratatoskr confirm the same v1 text, no discussion.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Standalone `[PATCH mt76]`. No series. No follow-up on
`origin/master` for this file.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable WebFetch **403**. No stable discussion in
the saved thread. UNVERIFIED whether anyone already asked stable@;
absence is not a negative signal.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

semcode MCP: **not available**. Used grep/read.

**Step 5.1: IDENTIFY KEY FUNCTIONS**

Record: `mt7603_update_beacon_iter()` only.

**Step 5.2: TRACE CALLERS**

Record:
- Called from `mt7603_pre_tbtt_tasklet()` via
  `ieee80211_iterate_active_interfaces_atomic()`.
- Tasklet scheduled from `mt7603_irq_handler()` on
  `MT_HW_INT3_PRE_TBTT0`.
- Reachable whenever the device is an AP with beacons enabled
  (`beacon_mask`).

**Step 5.3: TRACE CALLEES**

Record: `ieee80211_beacon_get` (driver owns SKB), `mt76_poll`/`mt76_wr`,
`mt76_tx_queue_skb` → `mt76_dma_tx_queue_skb` (takes SKB; error path
uses `ieee80211_tx_status_ext`).

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: userspace/AP stack enables beaconing → hardware pre-TBTT IRQ →
tasklet → iterator. Unprivileged clients do not trigger it directly;
**any AP/router using this chip in AP mode can**. Stuck DMA/FQCR0 is the
error trigger. `mac_work` runs every `MT7603_WATCHDOG_TIME` (100 ms) and
treats `beacon_check >= 10` as `RESET_CAUSE_BEACON_STUCK`.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Other mt76 chips use `ieee80211_beacon_get_template` /
`mt76x02_mac_set_beacon` and do not share this FQCR0 poll/`goto out`
pattern. mt76x02 has no equivalent leak.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes.** `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c`
lines 57–66: poll timeout → set watchdog → `goto out` with no free.
Local: `git describe` → `p-6.6-3-g04810563abb71`, `make kernelversion` →
**6.6.157**. Bug since 8caa9dd3d1a7c9 (stuck-beacon handling). Candidate
`965cbdbdfbd37` is **not** an ancestor of HEAD.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** (`git show 965cbdbdfbd37 | git apply --check`).
Surrounding function matches mainline hunks.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No other “free beacon SKB” commit. Other mt76 leak fixes
(`ec4a608bca405` probe leak, etc.) are unrelated.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** for those devices (common OpenWrt
APs), not CORE for every 6.6 user.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Mature driver (2018); this file is quiet. Bug is old (2023
stuck-beacon change), not a new-feature side effect.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific / config-specific:** `CONFIG_MT7603E`,
AP/beaconing. MT7628/MT7688 SoCs are widely deployed in consumer
routers.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record:
- Trigger: FQCR0 poll timeout (5 ms) while updating beacons — the same
  stuck-beacon condition this driver already recovers from.
- Frequency: pre-TBTT (~beacon interval, typically ~100 ms) per AP vif
  (up to 4). Watchdog work every 100 ms usually resets after one such
  event, so **~1 SKB per vif per stuck incident** if recovery works;
  **recurring** if the MAC stays stuck.
- Unprivileged trigger: no (AP beacon path).

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: **SKB leak**, not oops/UAF/corruption. **MEDIUM** (HIGH only if
stuck-beacon storms on a low-RAM AP). Still a real leak on a path
already considered serious enough to backport.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** stops leaking beacon frames on a known hardware-stuck
  path.
- **Risk:** very low (2 lines, error path only, clean apply).
- **Ratio:** favor backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Confirmed leak vs mac80211 SKB ownership.
- Buggy code is in this 6.6.157 tree (`8caa9dd3d1a7c9`).
- +2 lines, obviously correct, clean apply, no deps.
- Maintainer-applied.
- Same recovery path that already justified a stable backport.
- MT7603/MT76x8 used on production APs.

AGAINST:
- Error-path leak; volume per incident is small if watchdog resets.
- No crash/CVE/syzbot/user report.
- No Reviewed-by; mailing list silent.
- Not a core-kernel path.

UNRESOLVED:
- lore.kernel.org HTTP 403; stable@ search not fetched (b4/mbox used
  instead).
- Exact leak rate if reset fails repeatedly: not measured on hardware.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — ownership is documented;
   maintainer applied. No extra Tested-by.
2. Fixes a real bug that affects users? **PASS** — SKB leak on stuck-
   beacon recovery.
3. Important issue? **PASS** — resource leak on a periodic AP path (not
   a one-shot init leak). Severity medium, not a panic.
4. Small and contained? **PASS** — 2 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — verified with `git apply
   --check`.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
leak fix.

**Step 9.4: MAKE YOUR DECISION**

This is a two-line error-path `kfree` for a leak that exists in 6.6.157,
introduced by a stuck-beacon change already on this branch. Risk is
negligible; benefit is stopping SKB leaks on MT7603/MT76x8 APs when the
beacon DMA path wedges. That meets stable rules for this tree.

------------------------------------------------
What the commit solves for this tree
------------------------------------------------

In `mt7603_update_beacon_iter()`, `ieee80211_beacon_get()` returns an
SKB the driver must free. On FQCR0 poll timeout the function sets the
beacon watchdog and returns without queueing or freeing. That path is
the stuck-beacon recovery added in `8caa9dd3d1a7c9`, which is already
here. Each timeout leaks one beacon SKB per AP interface. The patch only
adds `dev_kfree_skb(skb)` on those two returns.

Risk vs benefit: almost no regression surface; the leak is real whenever
that recovery runs.

------------------------------------------------
Verification
------------------------------------------------

- [Phase 1] Tags: Link msgid `20260611215658.259324-1-mail@david-
  bauer.net`; SOBs David Bauer + Felix Fietkau; no Fixes/Reported-
  by/Cc:stable.
- [Phase 1] Mainline commit `965cbdbdfbd37` on `origin/master`.
- [Phase 2] Diff: +2 `dev_kfree_skb(skb)` in `mt7603_update_beacon_iter`
  poll-fail paths; success path still `mt76_tx_queue_skb`.
- [Phase 2] `include/net/mac80211.h`: “The driver is responsible for
  freeing the returned skb.”
- [Phase 2] `dev_kfree_skb` → `consume_skb` in `include/linux/skbuff.h`.
- [Phase 3] `git blame`: leaky `goto out` from `8caa9dd3d1a7c9` (stable
  form of `3176205933494`).
- [Phase 3] `git merge-base --is-ancestor 8caa9dd3d1a7c9 HEAD` → yes;
  `965cbdbdfbd37` → no; `3176205933494` → no (rewritten).
- [Phase 3] `git show 8caa9dd3d1a7c9`: moved `mt76_tx_queue_skb` after
  polls and added `goto out` without free.
- [Phase 4] `b4 dig -c 965cbdbdfbd37`: v1 only; no replies in mbox.
- [Phase 4] `b4 dig -w`: mt76 maintainers + linux-wireless on To/Cc.
- [Phase 4] lore WebFetch 403; openwall/patchew/ratatoskr match v1, no
  review replies.
- [Phase 5] Caller: `mt7603_pre_tbtt_tasklet` ← `mt7603_irq_handler`
  PRE_TBTT0.
- [Phase 5] Watchdog: `MT7603_WATCHDOG_TIME` 100 ms, timeout 10;
  `mt7603_mac_work` uses `beacon_check` with `check == NULL`.
- [Phase 6] `git describe HEAD` → `p-6.6-3-g04810563abb71`; `make
  kernelversion` → 6.6.157.
- [Phase 6] Local `beacon.c` still missing the kfrees (lines 57–66).
- [Phase 6] `git apply --check` of `965cbdbdfbd37` succeeded.
- [Phase 7] `CONFIG_MT7603E`; MAINTAINERS: Felix Fietkau.
- [Phase 8] Failure mode: SKB leak on stuck-beacon recovery; severity
  MEDIUM.
- UNVERIFIED: stable@ mailing-list archive (HTTP 403); hardware leak
  rate if reset keeps failing.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
index 6457ee06bb5a1..62e8de6949d1a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
@@ -56,6 +56,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN));
 	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
 		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		dev_kfree_skb(skb);
 		goto out;
 	}
 
@@ -63,6 +64,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC));
 	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
 		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		dev_kfree_skb(skb);
 		goto out;
 	}
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] perf: marvell: Cancel CN10K DDR PMU hrtimer on device remove
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (16 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
                   ` (30 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Geetha sowjanya, Will Deacon, Sasha Levin, mark.rutland,
	linux-arm-kernel, linux-perf-users, linux-kernel

From: Geetha sowjanya <gakula@marvell.com>

[ Upstream commit 7dbcb0268d1e2a1d3badb0c6e77ee70e550b1787 ]

cn10k_ddr_perf_remove() did not cancel the poll hrtimer before returning.
If the device was unbound while perf events were still active the timer
callback could run post-free.

To fix the issue by adding hrtimer_cancel() in remove().

Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough to decide: the UAF is in this 6.1 tree, the cancel is a
standalone 6-line fix, and it does not need the CN20K series.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**

Record: `[perf/marvell] [Cancel] Cancel CN10K DDR PMU hrtimer on device
remove`

Subsystem `perf: marvell:` is the Marvell CN10K DDR uncore PMU driver.
Verb `Cancel` is a stop-the-timer safety action. Claimed intent: stop
the poll hrtimer in the platform `remove()` path so it cannot fire after
the device is torn down.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record: tags present in the candidate message:
- `Signed-off-by: Geetha sowjanya <gakula@marvell.com>` (author)
- `Signed-off-by: Will Deacon <will@kernel.org>` (ARM perf maintainer
  merge; pipeline `Signed-off-by: Sasha Levin` ignored per instructions)

Tags **not** present (expected for this review queue, not treated as a
negative):
- No `Fixes:`
- No `Reported-by:` / `Tested-by:` / `Reviewed-by:` / `Acked-by:`
- No `Link:`
- No `Cc: stable@vger.kernel.org`

From mailing-list forensics (Phase 4): original submission was `[PATCH
v8 3/3]` of a CN20K feature series, Message-ID
`20260601073318.7098-4-gakula@marvell.com`. Will Deacon applied it to
`arm64 (for-next/perf)` as `7dbcb0268d1e`. Krzysztof’s `Reviewed-by` is
on patch 1/3 (dt-bindings) only, not on this UAF patch.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `cn10k_ddr_perf_remove()` returned without cancelling the
  overflow-poll hrtimer.
- **Symptom / failure mode:** if the device is unbound while events (and
  therefore the timer) are still active, `cn10k_ddr_pmu_timer_handler()`
  can run after `devm` frees `struct cn10k_ddr_pmu` and unmaps MMIO —
  use-after-free / MMIO-after-unmap.
- **Version info:** cover letter for v8 says this is **pre-existing for
  CN10K/Odyssey**, not a CN20K-only issue.
- **Root cause (author):** missing `hrtimer_cancel()` in `remove()`.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not a disguised cleanup. The message names a post-free timer
callback. This is an explicit UAF fix. The series is mostly a CN20K
feature add; **this patch was split out in v8 specifically as a pre-
existing bug fix**.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/perf/marvell_cn10k_ddr_pmu.c`
- Scope: **+6 / -0**, single function `cn10k_ddr_perf_remove()`
- Classification: **single-file surgical fix** (comment +
  `hrtimer_cancel()`)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:
- **Before:** `remove()` got drvdata, dropped the cpuhp instance,
  unregistered the PMU, returned. Timer left live if it had been
  started.
- **After:** `hrtimer_cancel(&ddr_pmu->hrtimer)` **first**, then the
  same teardown. `hrtimer_cancel()` also waits for a running callback,
  so the handler cannot continue after `remove()` returns.
- Path: **driver teardown / unbind / module unload**, not the normal
  event add/del path (that already cancels on last `event_del`).

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record: **Use-after-free / lifetime bug (memory safety)**

Mechanism verified in this tree:
- `ddr_pmu` is `devm_kzalloc()`’d; MMIO is
  `devm_platform_get_and_ioremap_resource()`. Both are released after
  `remove()` returns.
- Timer is started on first `event_add` (`hrtimer_start`,
  `HRTIMER_MODE_REL_PINNED`) and cancelled only when `active_events ==
  0` in `event_del`.
- Handler always `return HRTIMER_RESTART` after
  `cn10k_ddr_pmu_overflow_handler(pmu)`, which dereferences
  `pmu->events[]` and `pmu->base`.
- `perf_pmu_unregister()` in this tree (`kernel/events/core.c`) does
  **not** stop events or cancel driver timers; it only unlists the PMU,
  syncs RCU, and frees PMU context.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- **Quality:** obviously correct. `hrtimer_cancel()` on an already-idle
  timer is a no-op; cancelling before cpuhp/PMU teardown is the right
  order.
- **Regression risk:** very low. Callback only does `local_irq_save` +
  MMIO reads; it does not take locks `remove()` holds. No API/data-
  structure change.
- **Red flags:** none in the hunk itself. Series context (3/3 of CN20K)
  is a packaging concern, not a correctness concern — this hunk does not
  use CN20K code.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Buggy `cn10k_ddr_perf_remove()` (no timer cancel) introduced in
  `7cf83e222bce0` (`perf/marvell: CN10k DDR performance monitor
  support`, Bharat Bhushan, 2022-03-08).
- `git merge-base --is-ancestor 7cf83e222bce0 HEAD` succeeded; `git
  merge-base --is-ancestor 7cf83e222bce0 v6.1` succeeded.
- Present in this tree from the 6.1 baseline (driver landed in v5.18).

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No `Fixes:` tag. The introducing commit is `7cf83e222bce0`,
which **is** in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record: only four commits on this file in this tree:
- `7cf83e222bce0` CN10k DDR perfmon support
- `35a43326a9e3c` overflow handling
- `68fa55f0e05ce` core ownership
- `6676a42f1e4f1` `!CONFIG_OF` build fix

No later refactor of `remove()`. **Standalone** relative to this tree.
Does **not** need patches 1–2 of the CN20K series.

Related but **separate** bug (v7 of the same series, in patch 2/3):
`event_add` can `hrtimer_start()` then return `-EINVAL` from
`ddr_perf_get_event_bitmap()` without rolling back. That leak is **not**
this commit. This commit still stands alone.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: `git log --author=Geetha -- drivers/perf/` is empty in this 6.1
tree. Author is a Marvell engineer extending a Marvell driver originally
by Bharat Bhushan. Will Deacon (ARM perf maintainer) merged it. That is
sufficient maintainer vetting.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: **No functional prerequisites.** The only apply wrinkle is 6.1
still has `static int cn10k_ddr_perf_remove(...)` returning `0`; later
kernels converted platform `.remove` to `void`. The added
`hrtimer_cancel()` line and comment apply unchanged.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c HEAD` was the wrong SHA (this commit is not in the 6.1
  checkout). Direct lore fetch returned 403.
- `b4 am` on Message-ID `20260601073318.7098-4-gakula@marvell.com`
  succeeded: v8 series, 3 patches, DKIM-signed, no newer revision
  flagged.
- Lore/mirrors:
  https://patch.msgid.link/20260601073318.7098-1-gakula@marvell.com ,
  openwall, lkml.iu.edu, patchew, ratatoskr.
- Cover letter v8: “Cancel the poll hrtimer in `cn10k_ddr_perf_remove()`
  before `devm` frees `struct cn10k_ddr_pmu` (pre-existing for
  CN10K/Odyssey).”
- **No NAK.** Will Deacon: “Applied to arm64 (for-next/perf)” with git
  id `7dbcb0268d1e` for this patch.
- **No reviewer `Cc: stable` found** (not treated as a negative).

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record: To/Cc on the original mail: `linux-perf-users`, `linux-kernel`,
`linux-arm-kernel`, `devicetree`, Mark Rutland, Will Deacon, Krzysztof
Kozlowski. Will Deacon merged. No NAK on 3/3.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No syzbot, bugzilla, or external user report. Bug was found
during CN20K series review/development (added in v8). Still a concrete
UAF, just not fuzzer-reported.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Series is:
1. dt-bindings CN20K — feature, not this decision
2. CN20K driver support (+ event_add rollback) — feature / separate leak
   fix
3. **this UAF cancel** — independent 6-line fix

Do **not** pull 1/3 or 2/3 into 6.1. This commit does not call CN20K
pdata/helpers.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable search returned 403. No evidence on the
public v8 thread that stable rejected this. UNVERIFIED: whether
`-stable` ever discussed this hash by name.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**

Record: `cn10k_ddr_perf_remove()` only. Related existing functions:
`cn10k_ddr_perf_event_add`, `cn10k_ddr_perf_event_del`,
`cn10k_ddr_pmu_timer_handler`, `cn10k_ddr_pmu_overflow_handler`.

**Step 5.2: TRACE CALLERS**

Record:
- `cn10k_ddr_perf_remove` is the platform driver’s `.remove`
  (`cn10k_ddr_pmu_driver`). Callers: device unbind, parent device
  teardown, `platform_driver_unregister()` from `cn10k_ddr_pmu_exit()`.
- Timer handler is the hrtimer softirq/callback path, not a syscall.

**Step 5.3: TRACE CALLEES**

Record: `remove()` calls `platform_get_drvdata`, `hrtimer_cancel` (new),
`cpuhp_state_remove_instance_nocalls`, `perf_pmu_unregister`. Handler
calls overflow path which does MMIO `readq_relaxed` on `pmu->base`.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Userspace can start the timer via `perf_event_open` on this
uncore PMU (`event_add` when `active_events == 1`). Unbind/unload is
admin-triggered (module unload, device teardown), not an unprivileged
syscall by itself. `event_init` does **not** validate `attr.config`;
`event_add` can start the timer then fail `ddr_perf_get_event_bitmap()`.
`event_sched_in()` on add failure does **not** call `pmu->del()`
(verified at `kernel/events/core.c:2591-2595`). That can leave a running
timer even after a failed `perf_event_open`, after which `rmmod` can run
`remove()` with the timer still live. Reachable from userspace + admin
unload.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: In this tree, this driver only cancels the timer in `event_del`.
`drivers/perf/thunderx2_pmu.c` also cancels on CPU offline. Sibling DDR
PMU `fsl_imx8_ddr_perf.c` also does not cancel in `remove()` here —
pattern exists, but that does not make this UAF fictional.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes.** Local tree is **6.1.188** (`pending-6.1`, `git
describe` `p-6.1-10-g80966a5b14be4`).

```700:710:drivers/perf/marvell_cn10k_ddr_pmu.c
static int cn10k_ddr_perf_remove(struct platform_device *pdev)
{
        struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);

        cpuhp_state_remove_instance_nocalls(
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
                                &ddr_pmu->node);

        perf_pmu_unregister(&ddr_pmu->pmu);
        return 0;
}
```

No `hrtimer_cancel()`. Introduced with the driver in `7cf83e222bce0`
(v5.18), present for the whole 6.1 lifetime.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Minor context only.** 6.1 `remove` is `int` and returns `0`;
later kernels use `void`. OF match table in 6.1 has no `.data` / CN20K
entries. The added call does not depend on those. Expected apply:
**minor conflict, trivial rework**.

This tree still has `suppress_bind_attrs = true`, so **sysfs**
bind/unbind is hidden. That does **not** skip `.remove` on parent
teardown or `platform_driver_unregister()`.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No `hrtimer_cancel` in `remove()`. No event_add rollback (`goto
err_free_counter`). Nothing already fixes this UAF.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: `drivers/perf/` Marvell CN10K DDR PMU. **PERIPHERAL** (SoC-
specific uncore PMU). Config `MARVELL_CN10K_DDR_PMU` depends on
`ARCH_THUNDER || (COMPILE_TEST && 64BIT)` — Octeon 10 / Thunder-class
ARM64.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: File is mature and quiet in 6.1 (four commits total). Bug is
old, not a last-month regression.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific / config-specific:**
`CONFIG_MARVELL_CN10K_DDR_PMU` on Marvell CN10K (`ARCH_THUNDER`). Not
universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record:
- Timer starts when the first perf event is added; period default
  **100s** (`poll_period_sec`).
- Classic trigger: device `remove()` while the timer is queued (unbind /
  parent removal / module exit).
- Mitigations in **this** tree: `suppress_bind_attrs = true` (no sysfs
  unbind); successful events `try_module_get` the module so `rmmod`
  waits for last close, and last `event_del` already cancels the timer.
- Remaining realistic triggers: platform device teardown with events
  still open; **failed `event_add` after `hrtimer_start`** leaving a
  live timer so `rmmod` can hit `remove()` without `event_del`.
- Unprivileged user can start/leak the timer via `perf_event_open`;
  teardown is typically admin. Failure mode is still kernel UAF.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: Timer callback uses freed `cn10k_ddr_pmu` and unmapped MMIO →
**use-after-free / oops / memory corruption**. Severity: **HIGH** (UAF).
Not a guaranteed panic on every boot; when it hits, it is a hard kernel
memory-safety failure.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** HIGH for CN10K users who unload/unbind with a live poll
  timer; prevents UAF. Population is small but the bug class is serious.
- **Risk:** VERY LOW (6 lines, no-op if timer idle, no locking change).
- **Ratio:** strongly in favor of backporting.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real UAF: poll hrtimer can run after `devm` free of the PMU struct.
- Bug exists in this 6.1 tree since the driver was added
  (`7cf83e222bce0`).
- Surgical, obviously correct (`hrtimer_cancel` before teardown).
- Maintainer-merged (Will Deacon).
- Author/cover letter call it a **pre-existing CN10K** bug, not
  CN20K-only.
- Independent of CN20K patches 1–2.
- Failed `event_add` in this tree can leave the timer running;
  `pmu->add` failure does not call `del()`.
- `hrtimer_cancel` on idle timer is safe.

**AGAINST:**
- Peripheral SoC PMU, not a core path.
- No syzbot/user report.
- `suppress_bind_attrs` hides sysfs unbind; happy-path `rmmod` after
  clean event_del already cancels the timer.
- Packaged as 3/3 of a feature series (but this hunk is independent).
- Trivial `int` vs `void` `remove` context mismatch.

**UNRESOLVED:**
- Could not fetch lore.kernel.org (403) or git.kernel.org (Anubis);
  discussion reconstructed via `b4 am`, patchew, and mirrors.
- No `-stable` thread found (403).
- Exact mainline SHA in Linus’s tree not in this checkout; arm64
  application id `7dbcb0268d1e` from Will’s mail.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — one `hrtimer_cancel()`,
   merged by Will Deacon, idle-timer cancel is a no-op.
2. Fixes a real bug that affects users? **PASS** — UAF on remove with a
   live poll timer; code present here.
3. Important issue? **PASS** — use-after-free / crash / memory
   corruption (HIGH). Trigger is not every boot, but severity matches
   stable’s crash/UAF bar.
4. Small and contained? **PASS** — 6 lines, one function, one file.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — buggy `remove()` is here;
   only `int` vs `void` `remove` needs a one-line context tweak.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: Not a device-ID / quirk / DT / build / docs exception. It is a
normal small UAF fix.

**Step 9.4: MAKE YOUR DECISION**

This should be backported to **this** 6.1 tree. The CN20K feature
patches must stay out; this cancel is self-contained and matches the
code that has been in 6.1 from day one.

===============================================================
What the commit solves, and why it matters here
===============================================================

`cn10k_ddr_perf_remove()` tears down cpuhp and unregisters the PMU but
never stops the overflow-poll hrtimer. The PMU object and MMIO are
`devm`-managed, so they are freed as soon as `remove()` returns. If the
timer is still queued, `cn10k_ddr_pmu_timer_handler()` can run on freed
memory. That is a real UAF on Marvell CN10K systems that use this driver
— exactly the hardware this 6.1 tree already supports.

It meets stable rules: obviously correct, small, no new API, and the
buggy function is in this checkout. Risk is negligible. Benefit is
preventing a kernel UAF. The only backport edit is matching 6.1’s `int`
`remove` callback.

===============================================================
Verification
===============================================================

- [Phase 1] Parsed subject/body/tags: UAF-on-remove; SOBs Geetha
  sowjanya + Will Deacon; no Fixes/Reported-by/Cc-stable.
- [Phase 2] Diff: +6 in `cn10k_ddr_perf_remove()` only; adds
  `hrtimer_cancel()` before cpuhp/PMU teardown.
- [Phase 2] `perf_pmu_unregister()` at `kernel/events/core.c:11587` does
  not cancel driver timers or wait for `event_del`.
- [Phase 2] Handler at lines 600–612 always `HRTIMER_RESTART` and uses
  `pmu->base` / `pmu->events[]`.
- [Phase 3] `git describe HEAD` → `p-6.1-10-g80966a5b14be4`; `make
  kernelversion` → 6.1.188.
- [Phase 3] `git merge-base --is-ancestor 7cf83e222bce0 HEAD` →
  introducing driver commit is in this tree.
- [Phase 3] `git blame` on `remove()` → `7cf83e222bce0` (no cancel) and
  `68fa55f0e05ce` (cpuhp).
- [Phase 3] File history: 4 commits; no existing remove-path timer fix.
- [Phase 4] `b4 am` msgid `20260601073318.7098-4-gakula@marvell.com` →
  v8 3/3; cover letter “pre-existing for CN10K/Odyssey”.
- [Phase 4] Patchew: Will Deacon applied 3/3 as `7dbcb0268d1e`; no NAK.
- [Phase 4] lore.kernel.org and git.kernel.org fetches: 403 / Anubis —
  used b4/patchew/mirrors instead.
- [Phase 5] `event_sched_in` add-failure path (`core.c:2591`) does not
  call `pmu->del()`.
- [Phase 5] Local `event_init` does not validate `attr.config`;
  `event_add` can start the timer then return `-EINVAL`.
- [Phase 6] Read local `cn10k_ddr_perf_remove()`: no `hrtimer_cancel`;
  `devm_kzalloc` + `suppress_bind_attrs = true` confirmed.
- [Phase 7] Kconfig `MARVELL_CN10K_DDR_PMU` depends on `ARCH_THUNDER`.
- [Phase 8] Failure mode: UAF in hrtimer callback after `devm` free —
  HIGH.
- UNVERIFIED: `-stable` list discussion of this exact commit
  (lore/stable 403).
- UNVERIFIED: Linus-tree SHA beyond Will’s arm64 id `7dbcb0268d1e`.

**YES**

 drivers/perf/marvell_cn10k_ddr_pmu.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 72ac17efd846a..9974b62541f0d 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -1088,6 +1088,12 @@ static void cn10k_ddr_perf_remove(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
 
+	/*
+	 * Cancel the poll timer before further teardown so the handler
+	 * cannot run after this function returns.
+	 */
+	hrtimer_cancel(&ddr_pmu->hrtimer);
+
 	cpuhp_state_remove_instance_nocalls(
 				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
 				&ddr_pmu->node);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (17 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] perf: marvell: Cancel CN10K DDR PMU hrtimer on device remove Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
                   ` (29 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: David Bauer <mail@david-bauer.net>

[ Upstream commit a92cd5dd792a63a5d8a72142835382d4edbe9933 ]

When performing a full system recovery of the MCU on a dual-phy
platform, band 0 (usually 2.4GHz) stops reading correct noise floor
data.

This is due to noise floor reporting only being configured correctly
for the second device PHY.

Configure the respective registers correctly after restarting the MCU
firmware to fix reported noise-floor values.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.6.157** (`pending-6.6`). The buggy dual-PHY
restart path is present here, and this commit should be backported.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7915]** **[configure]** configure noise floor
reporting after MCU reset on dual-PHY platforms. “Configure” here is
restoring register state that recovery currently skips, not a new
feature.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: David Bauer &lt;mail@david-bauer.net&gt; (author)
- Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-
  bauer.net
- Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt; (mt76 maintainer)
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable (absence is expected)
- Ignored: any pipeline “Upstream commit” / Sasha Levin SOB markers

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** After full MCU recovery on a dual-PHY (DBDC) device, band 0
  (usually 2.4 GHz) stops reporting correct noise floor.
- **Symptom:** Wrong NF / survey noise on the primary PHY; the second
  PHY is configured correctly.
- **Root cause (author):** NF enable is only applied for the second PHY
  after firmware restart.
- **Version info:** none in the message. The restart path has been in
  this tree since before v6.6.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised cleanup. It is an explicit hardware-init fix. The
mechanism (clear `MT76_STATE_RUNNING` before `mt7915_run()`) also re-
runs the primary PHY’s PM/MAC init that the same `if (!running)` guard
skips, not only NF.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7915/mac.c` only
- Scope: ~+6/−2 in `mt7915_mac_restart()` (surgical, single function)
- Adds `bool run_main, run_ext`
- Replaces `test_bit(MT76_STATE_RUNNING)` with `test_and_clear_bit`,
  then uses those saved flags to decide whether to call `mt7915_run()`

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** After firmware reload, `mt7915_run()` is called while both
  PHYs still have `MT76_STATE_RUNNING`. `mt7915_dev_running()` is
  therefore true.
- In this tree, `mt7915_run()` only programs primary-PHY PM/MAC/NF when
  `!running`:

```32:58:drivers/net/wireless/mediatek/mt76/mt7915/main.c
        if (!running) {
                ret = mt76_connac_mcu_set_pm(&dev->mt76,
                                             dev->phy.mt76->band_idx,
0);
                ...
                mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);
        }

        if (phy != &dev->phy) {
                ...
                mt7915_mac_enable_nf(dev, phy->mt76->band_idx);
        }
```

- Primary `mt7915_run()` therefore skips band-0 NF. Ext `mt7915_run()`
  still hits `phy != &dev->phy` and enables band-1 NF. That matches the
  commit message.
- `ieee80211_restart_hw()` after full reset does not repair this:
  starting the main PHY while the ext PHY still has `MT76_STATE_RUNNING`
  keeps `running == true`, so band 0 is skipped again; starting the ext
  PHY then enables only the ext PHY’s NF.
- **After:** bits are cleared first, so the first `mt7915_run()` sees
  `running == false` and programs band 0. Saved flags still prevent
  starting a PHY that was never up.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-init.** After MCU reload, IPI/NF registers
(`mt7915_mac_enable_nf`: `MT_WF_PHY_RXTD12_*` and
`MT_WF_PHY_RX_CTRL1_IPI_EN`) are not programmed for band 0.
`mt7915_mac_init_band()` does not enable NF; only `mt7915_run()` does.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct. Same approach the mt76 maintainer asked for
on-list. Minimal. Mutex is already held in `mt7915_mac_full_reset()`;
`MT76_RESET` is already set. Risk is low: if `mt7915_run()` fails, the
RUNNING bits stay clear, but full reset retries and then calls
`ieee80211_restart_hw()`, which stop/start and restores them.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: The `test_bit` + `mt7915_run()` sequence was introduced in
`8a55712d124fd8` (“wifi: mt76: mt7915: enable full system reset
support”, Bo Jiao / Ryder Lee, 2022). `git describe --contains` →
`v6.2-rc1~...`. Present in this 6.6 tree (`git merge-base --is-ancestor
8a55712d124fd8 HEAD` succeeded).

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Not applicable. The introducing commit is in this
tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Related reset work already in this tree:
- `c71d2db21f153` improve hardware restart reliability
- `1e474cbe5db60` fix omac index assignment after hardware reset
- `72eabd4c1986b` firmware restart on devices with a second PCIe link
This patch is standalone; it does not depend on those.
`test_and_clear_bit(MT76_STATE_RUNNING)` is **not** in this tree (`git
grep` found no matches).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: David Bauer is an OpenWrt/wireless contributor; in this tree he
already has `b6c39aaa85c4e` (mt7915 MCU re-init). Felix Fietkau (mt76
maintainer) signed off and designed the committed approach.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: No functional prerequisites. Surrounding `mt7915_init_txpower()`
signature and `napi_enable` placement differ from later mainline; those
are context only. The `run_main`/`run_ext` change applies with a small
context tweak.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record: `b4 dig -c` was not usable (commit SHA not in this checkout’s
master). `b4 mbox` on msgid `20260516144944.2574053-1-mail@david-
bauer.net` saved a 4-message thread.
- v1 (16 May 2026): 4-line change in `mt7915_run()`: `if (!running ||
  (reset && phy == &dev->phy))`
- Felix (27 May): asked to clear `MT76_STATE_RUNNING` in
  `mt7915_mac_restart` instead
- David: explained the per-PHY RUNNING guard (don’t start a PHY that was
  never up)
- Felix (1 Jun): proposed exactly the committed `test_and_clear_bit`
  pattern
No NAK. No reviewer `Cc: stable`. Committed diff is the maintainer
rewrite, still linked to the v1 msgid.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Recipients included Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, linux-wireless, linux-mediatek. Felix both
reviewed and applied.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Author describes a real dual-PHY MCU
recovery failure. That is a field observation, not a theoretical report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Single patch, not N/M. v1 vs committed is a maintainer rewrite
of the same fix, not a multi-patch series.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject. No recorded reason
to keep it out of stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: Modified: `mt7915_mac_restart()`. Behavior depends on
`mt7915_run()`, `mt7915_dev_running()`, `mt7915_mac_enable_nf()`.

**Step 5.2: TRACE CALLERS**
Record:
- `mt7915_mac_restart()` ← `mt7915_mac_full_reset()` (only caller in
  this tree)
- `mt7915_mac_full_reset()` ← `mt7915_mac_reset_work()` when
  `dev->recovery.restart`
- `recovery.restart` set in `mt7915_reset()` on WA/WM watchdog
  (`MT_MCU_CMD_WDT_MASK`), which logs “firmware crash, attempting
  recovery”
- `mt7915_run()` also from `mt7915_start()` (normal iface start); this
  patch does not change that path

**Step 5.3: TRACE CALLEES**
Record: After firmware load: `mt7915_mcu_init_firmware`,
`mt7915_mcu_set_eeprom`, `mt7915_mac_init`, txpower/txbf, then
`mt7915_run()` (PM, `mt7915_mcu_set_mac`, `mt7915_mac_enable_nf`,
thermal, RTS, SKU, RX path).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Triggered by firmware watchdog recovery on `CONFIG_MT7915E`
dual-PHY (mt7915/mt7916/mt798x DBDC), common on APs/routers. Not a
generic syscall crash path. Userspace sees bad survey noise
(`mt76_get_survey` → `SURVEY_INFO_NOISE_DBM`) and ACS can use it.
Debugfs can also force full reset (`b662b71`).

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: No `test_and_clear_bit(MT76_STATE_RUNNING)` in this tree’s mt76.
Sibling chips (mt7615/mt7996) have similar NF helpers; this fix is
mt7915-restart-specific.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. `mt7915_mac_restart()` at
`drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1397-1407` still uses
`test_bit` without clearing. Introduced v6.2-era (`8a55712d124fd8`),
present since this 6.6 branch.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Minor context.** Mainline hunk context uses
`mt7915_init_txpower(&dev->phy)` / `mt7915_init_txpower(phy2)`; this
tree still has `mt7915_init_txpower(dev, &dev->mphy.sband_* )`.
`napi_enable` vs `local_bh_disable` order in the `out:` path also
differs. The RUNNING-bit change itself matches this tree. Easy manual
backport; not a rewrite.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: Reset reliability/omac-after-reset fixes are here. This NF re-
init after MCU recovery is not.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 mt7915**
(`drivers/net/wireless/mediatek/mt76/mt7915/`). **IMPORTANT** for users
of these radios (filogic/mt7915 DBDC APs), not core mm/net. Not staging.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still getting reset-path fixes in this 6.6 tree.
Not a newly added subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific, dual-PHY `CONFIG_MT7915E` after full MCU
recovery. Widely used on embedded/AP hardware.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Firmware WA/WM watchdog → full recovery. Unprivileged users
cannot trigger it directly. Timing is the recovery path, not a race.
Debugfs reset can also hit it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Wrong band-0 noise floor / survey after recovery; ACS can pick a
worse channel. Not an oops, deadlock, or corruption. Connectivity was
not reported broken; `mac_init` still runs, so MAC datapath likely
survives. **Severity: MEDIUM.**

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Medium. Restores intended PHY register state on a
  recovery path this tree already treats as backport-worthy.
- **Risk:** Low. ~8 lines, one function, maintainer-specified, under
  existing reset mutex.
- **Ratio:** Favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real dual-PHY bug after MCU full recovery; primary PHY NF registers
  never reprogrammed
- Code and introducing commit are in 6.6.157
- Small, obviously correct, maintainer-directed
- Same `!running` skip also omits band-0 `set_pm`/`set_mac` on that path
- This tree already backported other mt7915 reset corrections
- Dual-PHY mt7915/mt798x is common production AP hardware

AGAINST:
- Not a crash, UAF, deadlock, or security issue
- Trigger is firmware watchdog recovery, not a hot path
- User-visible effect is mainly survey/ACS noise, not a reported outage
- Apply needs a trivial context adjustment

UNRESOLVED:
- Upstream SHA is not on this checkout’s `master`, so `b4 dig -c <sha>`
  was not run (thread retrieved via msgid instead)
- No independent confirmation that band-0 MAC/PM skip causes traffic
  loss (author only reported NF)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — logic matches
   `mt7915_run()`; maintainer specified this form
2. Fixes a real bug that affects users? **PASS** — wrong NF after
   recovery on dual-PHY
3. Important issue? **PASS** (medium) — recovery leaves hardware
   misconfigured; not a panic, but it is a real functional failure of
   SER
4. Small and contained? **PASS** — one function, few lines
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — buggy code present; minor
   context only

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a new device ID/API. Closest class is hardware re-init after
reset (quirk-like). Qualifies on technical merit, not only via an
exception.

**Step 9.4: MAKE YOUR DECISION**
Backport. The 6.6 tree has the bug, the fix is surgical, and leaving MCU
recovery with band 0 NF unprogrammed is a real driver bug on hardware
this series already ships.

Verification:
- [Phase 1] Parsed tags: author David Bauer, Link to msgid, SOB Felix
  Fietkau; no Fixes/Cc stable/Reported-by
- [Phase 1] Body: dual-PHY MCU recovery → band 0 NF wrong because only
  PHY1 is configured
- [Phase 2] Diff: `mt7915_mac_restart()` saves/clears RUNNING then calls
  `mt7915_run()`
- [Phase 2] Local `mt7915_run()`: primary NF only if
  `!mt7915_dev_running()`; ext NF if `phy != &dev->phy`
- [Phase 2] `mt7915_mac_init_band()` does not set IPI/NF; only
  `mt7915_mac_enable_nf()` does
- [Phase 3] `git blame` `mac.c:1397-1407` → `8a55712d124fd8` (v6.2-rc1);
  ancestor of HEAD
- [Phase 3] `git grep test_and_clear_bit(MT76_STATE_RUNNING)` → no hits
  in this tree
- [Phase 3] Related reset fixes already here (`c71d2db21f153`,
  `1e474cbe5db60`); this NF fix is not
- [Phase 4] `b4 mbox` msgid → 4-message thread; Felix requested the
  committed approach; no NAK
- [Phase 4] lore.kernel.org WebFetch returned 403; used b4 mbox +
  openwall/ratatoskr instead
- [Phase 4] No meaningful stable-list discussion found
- [Phase 5] Call chain: WDT → `mt7915_reset()` → dump_work →
  `mt7915_mac_reset_work()` → `mt7915_mac_full_reset()` →
  `mt7915_mac_restart()`
- [Phase 5] Survey path: `mt7915_update_channel()` → `state->noise` →
  `mt76_get_survey()`
- [Phase 6] `git describe HEAD` / `make kernelversion` → p-6.6-3 /
  **6.6.157**
- [Phase 6] Local `mt7915_init_txpower()` signature differs from patch
  context; RUNNING change still maps 1:1
- [Phase 8] Failure mode: incorrect band-0 noise after firmware crash
  recovery; severity MEDIUM
- UNVERIFIED: exact upstream SHA (not on this `master`); whether band-0
  `set_mac` skip also breaks traffic (not claimed by author)

The patch is a small, maintainer-reviewed correction of MCU recovery on
dual-PHY mt7915, and the buggy code is in this 6.6 tree.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index dda4e7d179536..55d2553addb13 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1292,6 +1292,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 	struct mt7915_phy *phy2;
 	struct mt76_phy *ext_phy;
 	struct mt76_dev *mdev = &dev->mt76;
+	bool run_main, run_ext;
 	int i, ret;
 
 	ext_phy = dev->mt76.phys[MT_BAND1];
@@ -1387,13 +1388,17 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 	mt7915_init_txpower(phy2);
 	ret = mt7915_txbf_init(dev);
 
-	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
+	run_main = test_and_clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
+	run_ext = ext_phy &&
+		  test_and_clear_bit(MT76_STATE_RUNNING, &ext_phy->state);
+
+	if (run_main) {
 		ret = mt7915_run(dev->mphy.hw);
 		if (ret)
 			goto out;
 	}
 
-	if (ext_phy && test_bit(MT76_STATE_RUNNING, &ext_phy->state)) {
+	if (run_ext) {
 		ret = mt7915_run(ext_phy->hw);
 		if (ret)
 			goto out;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (18 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
                   ` (28 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 0bbd6c52dfff62b319963f54cd9370f9486e59d2 ]

The PS queue filed redirected frames under the TID taken from the TXD,
while mac80211 was told about the TID taken from the QoS header, or TID 0
for anything that is not a QoS data frame. When the two disagree,
mt7603_release_buffered_frames() skips the frame because it does not
match the requested TIDs, so it stays in the PS queue until the station
wakes up. Buffered MMPDUs hit this whenever they were sent on a
non-zero TID.

Use one TID for both.

Link: https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.12.111** (`p-6.12-2`). The mt7603 PS-queue TID mismatch
is present here, the two-line fix applies cleanly, and it is a real AP-
mode buffering bug.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603]** **[file]** buffered frames under the
TID reported to mac80211. “File” here means enqueue/classify; the body
is a correctness fix so mac80211 and the driver PS queue use the same
TID.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Link:**
  `https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name`
  (patch 08/10)
- **Signed-off-by:** Felix Fietkau (mt76 maintainer; ignore any Sasha
  Levin SOB)
- **No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable** (absence expected for this review)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Redirected PS frames are queued under the TXD TID, while
  `ieee80211_sta_set_buffered()` is told the QoS-header TID, or TID 0
  for non-QoS data / MMPDUs.
- **Symptom:** `mt7603_release_buffered_frames()` skips the skb (`tids &
  BIT(skb->priority)` fails). The frame sits in `msta->psq` until the
  station fully wakes (`mt7603_sta_ps()` splices the whole queue).
  Buffered MMPDUs hit this whenever the TXD TID is non-zero.
- **Root cause:** Two different TID sources for the same frame.
- **Fix:** Use the same `tid` for both `skb->priority` and
  `ieee80211_sta_set_buffered()`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit protocol/correctness
fix.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- **File:** `drivers/net/wireless/mediatek/mt76/mt7603/dma.c` (+1 / −1)
- **Function:** `mt7603_rx_loopback_skb()`
- **Scope:** single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `skb->priority = FIELD_GET(MT_TXD1_TID, val)` (3-bit TXD
  field), then later `ieee80211_sta_set_buffered(sta, tid, true)` with
  `tid` from the QoS header or 0.
- **After:** `skb->priority = tid` after that classification.
- **Path:** hardware PS redirect → MCU RX loopback → driver PS queue.
  Not an init-only path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / correctness.** Enqueue key (`skb->priority`) and
mac80211 TIM/TID bitmap disagree, so `release_buffered_frames` never
dequeues those skbs during PS-Poll/U-APSD.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and minimal. `tid` is already 0–7
(`IEEE80211_QOS_CTL_TAG1D_MASK` or 0). No new locks, APIs, or data
structures. Regression risk is very low: release matching becomes
consistent with what mac80211 was already told.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `skb->priority = FIELD_GET(MT_TXD1_TID, val)` comes from the original
  driver (`c8846e1015022`, 2018).
- Split vs mac80211 TID: `e004b700660025` (2019,
  `ieee80211_sta_set_buffered`) and `d55aa5e17461b8` (2019, QoS-only
  TID, default 0).
- Current if/else (QoS / data / bufferable MMPDU) is `b473c0e47f04d`
  (2024, “fix tx queue of loopback packets”), **already in this 6.12
  tree**.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Buggy split has been in the driver since 2019;
MMPDU TID-0 reporting since `d55aa5e17461b8` / `b473c0e47f04d`.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Recent `dma.c` history includes `b473c0e47f04d` and
`9b8d932053b8b`. This commit is **not** in HEAD (`git merge-base --is-
ancestor 0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not ancestor).
Standalone vs later 2026 PS series (see 3.5).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer. Nearby author work on this
driver is unrelated (chainmask, EEPROM, WPDMA EOF). Same 10-patch series
contains other mt7603 PS fixes he wrote.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Upstream SHA `0bbd6c52dfff62b319963f54cd9370f9486e59d2`. Series
08/10. Needed context `b473c0e47f04d` **is** in this tree. Later series
patches are **not** in this tree and are **not** required for this two-
line change:
- `697badc27a9b3` U-APSD EOSP
- `d5001f493fefd` clear buffered-TID when psq empty
- `636a883e2feef` re-arm HW PS after service period
Those fix other PS bugs; this patch only aligns enqueue TID with
`ieee80211_sta_set_buffered()`. It can apply standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 0bbd6c52dfff6` →
  https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
- Single series revision (v1 only; `-a` showed only this series)
- Thread: 11 messages = 10 patches + kernel test robot on **patch 10
  only** (mt7996 OOB, unrelated)
- No NAK, no reviewer risk comments, no Cc: stable on this patch

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To `linux-wireless@vger.kernel.org`, From Felix
Fietkau. No extra Reviewed-by. Author is the subsystem maintainer and
applied it himself.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by / bugzilla / syzbot. Failure mode is code-
derived. Related series patch 07 mentions U-APSD retry storms/packet
loss; that is a **different** bug.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: `[PATCH 01/10]` adds `MT_DRV_HW_PS_BUFFERING` for firmware-TIM
chips (mt7915/mt7996), not mt7603 loopback. mt7603 patches 05–07 are
sibling PS fixes, not semantic prerequisites of 08.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject (lore.kernel.org
fetch 403; web search returned unrelated archives). UNVERIFIED that
anyone already requested/rejected it for stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `mt7603_rx_loopback_skb()` only.

**Step 5.2: TRACE CALLERS**
Record:
- Called only from `mt7603_queue_rx_skb()` when `q == MT_RXQ_MCU` and
  the packet is not `PKT_TYPE_RX_EVENT` (HW-redirected TX).
- `mt7603_queue_rx_skb` is `.rx_skb` in
  `drivers/net/wireless/mediatek/mt76/mt7603/init.c`.
- Release path: mac80211 `drv_release_buffered_frames` →
  `mt7603_release_buffered_frames()` which filters on
  `BIT(skb->priority)` (verified at `main.c:458`).

**Step 5.3: TRACE CALLEES**
Record: `ieee80211_is_data_qos` / `ieee80211_is_data` /
`ieee80211_is_bufferable_mmpdu(skb)` (present in this tree’s
`ieee80211.h`), `ieee80211_sta_set_buffered`, `skb_queue` under
`ps_lock`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable in AP mode when a station is in PS and the PSE
redirects TX. Userspace/network traffic plus sleeping clients trigger
it. Not a syscall crash path; it is a common AP operation on this
hardware.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Other mt76 chips use `mt76_release_buffered_frames()`; mt7603
has its own `psq`. No duplicate of this exact TXD-vs-QoS TID split
elsewhere in this driver.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `dma.c` still has:

```42:75:drivers/net/wireless/mediatek/mt76/mt7603/dma.c
        skb->priority = FIELD_GET(MT_TXD1_TID, val);
        ...
        ieee80211_sta_set_buffered(sta, tid, true);
```

`MT_TXD1_TID` is `GENMASK(22, 20)`. `mt7603_release_buffered_frames()`
still skips on `!(tids & BIT(skb->priority))`. Bug introduced 2019;
still here in 6.12.111. Upstream commit is **not** an ancestor of HEAD.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** `git apply --check` of `0bbd6c52dfff6`
succeeded. This tree still uses `rcu_dereference(dev->mt76.wcid[idx])`
rather than `mt76_wcid_ptr()`; that is unused context, not a conflict.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent TID alignment. `git log --grep='buffered frames
under the TID'` on this path is empty. Sibling 2026 PS series patches
are not in this tree.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** (widely used AP/router silicon),
not core mm/net.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still receiving maintainer fixes. Not staging.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (and any PS-buffering) users of
MT7603/MT7628/MT7688. Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Station in power-save; HW redirects frames into the driver PS
queue; mac80211 later releases by TID (PS-Poll / U-APSD). Common on APs
with phones/IoT clients. Unprivileged Wi-Fi clients can trigger it by
sleeping. MMPDUs with non-zero TXD TID are the documented always-hit
case.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Frames are not released during the service period. They wait
until the station leaves PS, or they can be dropped if `psq` hits 64.
That delays bufferable management (deauth/disassoc/action) and
mismatched-TID data. **Severity: HIGH** for AP connectivity; not a
kernel oops.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for this hardware (PS buffering actually works
for the TIDs mac80211 asked for). **Risk: very low** (2 lines, no
locking/API change, applies cleanly). Ratio strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, explained bug; mechanism confirmed in this tree’s `dma.c` and
  `main.c`
- User-visible AP PS failure (stuck/delayed frames, possible psq
  overflow drops)
- 2-line, obviously correct, maintainer-authored
- Applies cleanly to 6.12.111
- Prerequisite loopback-queue rewrite (`b473c0e47f04d`) already present
- Does not need the rest of the 10-patch series

AGAINST:
- Not a crash, UAF, or CVE
- No reporter / Tested-by / Fixes tag
- Other mt7603 PS bugs in the same series remain unfixed here (does not
  make this patch wrong)

UNRESOLVED:
- No stable-list discussion found (lore 403 / search noise)
- No independent user report for this exact TID mismatch

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — two-line alignment; in
   mainline from the maintainer
2. Real bug affecting users? **PASS** — PS-buffered frames not released
   until wake
3. Important issue? **PASS** — AP power-save correctness / delayed
   MMPDUs; HIGH not panic
4. Small and contained? **PASS** — 2 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean apply on 6.12.111

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID / quirk / DT / build / docs exception).
Qualifies as a normal contained bugfix.

**Step 9.4: MAKE YOUR DECISION**
Backport. This 6.12 tree has the exact buggy split, the fix is surgical,
and it restores mac80211-driven release of buffered frames (especially
MMPDUs) for a still-deployed wireless SoC.

------------------------------------------------
What the commit solves for stable users
------------------------------------------------
On MT7603/MT7628 APs, hardware-redirected PS frames are advertised to
mac80211 under one TID and stored under another. Service-period release
then skips them, so management and some data stay in the driver queue
until the client fully wakes (or the 64-entry queue drops them). Using
one TID for both makes `release_buffered_frames` find those skbs.

Risk vs benefit: two lines, no API/locking change, clean apply; benefit
is correct PS delivery on real AP hardware.

Concerns: sibling U-APSD/PS-rearm fixes are separate commits and not
required. No backport rewrite needed on this tree.

===============================================================
Verification
===============================================================
- [Phase 1] Tags: Link msgid `20260801145334.1166751-8-nbd@nbd.name`;
  SOB Felix Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: move `skb->priority` from `MT_TXD1_TID` to classified
  `tid` in `mt7603_rx_loopback_skb` (+1/−1)
- [Phase 3] `git describe` / Makefile: **6.12.111**
  (`p-6.12-2-gd38d58a4e0359`)
- [Phase 3] Blame/history: TXD priority from `c8846e1015022`; mac80211
  TID from `e004b700660025` / `d55aa5e17461b8`; MMPDU/queue split
  `b473c0e47f04d` **is** ancestor of HEAD
- [Phase 3] `git merge-base --is-ancestor
  0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not present
- [Phase 3] Related series SHAs `697badc27a9b3`, `d5001f493fefd`,
  `636a883e2feef` → not in HEAD; not required
- [Phase 4] `b4 dig -c 0bbd6c52dfff6`: lore match, v1 only; `-w`: linux-
  wireless + author; robot reply only on patch 10
- [Phase 4] UNVERIFIED: stable@ discussion (lore 403)
- [Phase 5] Caller: `mt7603_queue_rx_skb` MCU loopback; release uses
  `BIT(skb->priority)` at `main.c:458`
- [Phase 6] Local `dma.c:42` still assigns priority from TXD; `git apply
  --check` of upstream diff **exit 0**
- [Phase 8] Failure mode: PS frames skipped until wake / possible psq
  drop; HIGH connectivity, not oops

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index e26cc78fff949..25009e49e7771 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -39,7 +39,6 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 
 	val = le32_to_cpu(txd[1]);
 	idx = FIELD_GET(MT_TXD1_WLAN_IDX, val);
-	skb->priority = FIELD_GET(MT_TXD1_TID, val);
 
 	if (idx >= MT7603_WTBL_STA - 1)
 		goto free;
@@ -72,6 +71,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 		hwq = MT_TX_HW_QUEUE_MGMT;
 	}
 
+	skb->priority = tid;
 	ieee80211_sta_set_buffered(sta, tid, true);
 
 	val = le32_to_cpu(txd[0]);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (19 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18] soc: amlogic: meson-clk-measure: remove debugfs tree Sasha Levin
                   ` (27 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 697badc27a9b3b2a8d86092abeed767714f735a2 ]

Frames released from the driver PS queue were all tagged with MORE_DATA
and none of them ever carried the EOSP bit, so from the client's point of
view a U-APSD service period was started but never finished. Clients that
keep their receiver on until EOSP arrives stop sending trigger frames,
and all downlink traffic for that station stalls until they give up.
ieee80211_sta_eosp() only cleared the service period state inside
mac80211, which is why the mismatch went unnoticed.

Assign MORE_DATA per frame and set the wire EOSP bit on the last one. If
the last released frame is a bufferable MMPDU it has no QoS control field
to carry EOSP, so let mac80211 append a QoS-Null frame instead.

Also stop handing the remaining frame budget to
mt76_release_buffered_frames() once frames have been released from the PS
queue: both would signal the end of the same service period. Releasing
fewer frames than requested is allowed, and MORE_DATA tells the client to
trigger again.

Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **5.15.221** (`pending-5.15`). The buggy mt7603 U-APSD
path is present here and matches mainline before `697badc27a9b3`. This
is a real protocol fix for a stall, and it should be backported.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi/mt76/mt7603] [fix] [U-APSD service period never ends on
the wire]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name`
  — patch **05/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Reviewed-by:`, no
  `Cc: stable` (absence of the last two is expected in this pipeline)
- Ignore any `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
  present; they are candidate-prep markers

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Frames pulled from the driver PS queue all get `MORE_DATA`
  and never `EOSP`. A U-APSD SP starts and never ends on the air.
- **Symptom:** Clients that stay awake until EOSP stop sending trigger
  frames; **all downlink traffic for that STA stalls** until they give
  up.
- **Root cause:** `ieee80211_sta_eosp()` only clears mac80211’s
  `WLAN_STA_SP`. mac80211 documents that a driver implementing
  `.release_buffered_frames` must set the **wire** EOSP bit itself.
- **Second bug in the same function:** leftover `nframes` is handed to
  `mt76_release_buffered_frames()`, which ends the **same** SP a second
  time.
- **Fix:** assign `MORE_DATA`/`EOSP` per frame; QoS-Null via
  `ieee80211_send_eosp_nullfunc()` if the last frame is a bufferable
  MMPDU; do not forward leftover budget once PS-queue frames were
  released.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject and body describe a concrete protocol
failure with a user-visible stall.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/main.c` (**+63 /
  −11**)
- Functions: `mt7603_ps_skb_hdr()` (new), `mt7603_ps_set_more_data` →
  `mt7603_ps_set_flags`, `mt7603_release_buffered_frames`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** every released PS-queue frame unconditionally ORs
  `IEEE80211_FCTL_MOREDATA`; never sets/clears EOSP;
  `ieee80211_sta_eosp()` is called if the list is non-empty, then
  leftover `nframes` still go to `mt76_release_buffered_frames()`.
- **After:**
  1. Walk remaining PS queue under `ps_lock` and build a pending-TID
     bitmap.
  2. If nothing was dequeued, fall through to
     `mt76_release_buffered_frames()` (unchanged).
  3. If anything was dequeued, **do not** also release from mac80211
     TXQs.
  4. `MORE_DATA` = not-last **or** more frames remain (mac80211
     `more_data` or pending matching TIDs).
  5. Wire `EOSP` only on the last frame and only for
     `IEEE80211_FRAME_RELEASE_UAPSD`.
  6. Last frame not QoS data → `ieee80211_send_eosp_nullfunc()`; else
     `ieee80211_sta_eosp()`.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** protocol / correctness (U-APSD SP termination), not
  UAF/leak/race.
- **Mechanism:** driver never put EOSP on the air; clients that wait for
  EOSP stop triggering; downlink stalls.
- Also: `MORE_DATA` was only set, never cleared. Recycled frames from
  `mt7603_filter_tx()` can keep a stale bit; the new helper assigns both
  bits.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Matches mac80211’s `.release_buffered_frames` contract
  (`include/net/mac80211.h`: driver must set EOSP in the QoS header;
  sending fewer frames than requested is allowed).
- `IEEE80211_QOS_CTL_EOSP` (0x0010) on the first QoS-control byte is the
  correct on-wire bit.
- `ieee80211_send_eosp_nullfunc()` uses `IEEE80211_TX_STATUS_EOSP` on
  the NDP; TX status then clears `WLAN_STA_SP`. iwlwifi already calls
  this from BH/TX context; `.release_buffered_frames` must be atomic,
  and `ieee80211_send_null_response()` uses `dev_alloc_skb` (GFP_ATOMIC)
  + `ieee80211_xmit`.
- Regression risk: **low–medium**. Logic is contained; PS-Poll does not
  set wire EOSP (`uapsd` is false). Companion series patches 06–08 make
  TIM / HW buffering / TID filing more complete but are not required for
  this EOSP fix to compile or to be correct on its own.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_release_buffered_frames`: `c8846e101502` (2018-11, **mt76: add
  driver for MT7603E and MT7628/7688**)
- Unconditional MORE_DATA: `b126c8897435` (2019-03)
- `ieee80211_sta_eosp()` without wire EOSP: `b7001f46085e` (2019-03)
- All three are ancestors of this 5.15 tree.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No `Fixes:` tag.** Buggy behavior dates to driver introduction
/ 2019 PS-queue helpers, all in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Mainline follow-ups on the same function (not in this tree):
- `d5001f493fef` — tell mac80211 when the PS queue is empty
  (`ieee80211_sta_set_buffered(..., false)`)
- `636a883e2feef` — restore hardware PS buffering after an SP
These are related U-APSD bugs, not prerequisites for this diff.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original author of this
driver. This is a maintainer fix.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Patch **05/10**. Patches 01–03/09–10 target mt7915/mt7996 / MLO
/ new HW TIM — **not needed**. Patch 04 sets wire EOSP in generic
`mt76_release_buffered_frames()` (`tx.c`); mt7603 has its **own**
`.release_buffered_frames` and only calls the generic helper when the
driver PS queue is empty. This patch does not use new APIs or struct
fields. **Can apply standalone.**

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 697badc27a9b3` →
  https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
- **v1 only** (no v2/v3)
- Thread is the 10-patch series plus a kernel-test-robot mail
- Robot error is on **patch 10 / patch 1** (`ieee80211_txq_aql_pending`
  missing) — **unrelated** to this patch
- No NAKs, no reviewer risk flags, no `Cc: stable` suggestion in the
  thread

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To/Cc were **Felix Fietkau** and **linux-
wireless@**. No extra reviewer SOB. Maintainer self-applied into
wireless-next (listed in the 2026-08-06 wireless-next pull).

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt mt76 users reported U-APSD stalls / **iPhone freezes**
on MT7603 APs (openwrt/mt76#1080 / PR #1084). Testers said an EOSP-
related change made iPhone freezes go away; remaining TX-retry/loss is
the separate HW-buffering bug (series patch 07).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Series 01–10 as above. This commit is self-contained. Patch 06
should be considered as a follow-up candidate (TIM never cleared); it is
not required for this hunk.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No evidence this fix was discussed on stable@ or previously
rejected. UNVERIFIED that every stable archive was searchable
(lore.kernel.org returned 403 for some URLs); `b4`/openwall/syzbot CI
were used instead.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_release_buffered_frames`, `mt7603_ps_set_flags`,
`mt7603_ps_skb_hdr`

**Step 5.2: TRACE CALLERS**
Record: Assigned as `ieee80211_ops.release_buffered_frames` in this
file. mac80211 calls it for **PS-Poll and U-APSD** from the RX/PS path
(atomic). Reachable whenever an AP-mode STA uses power save.

**Step 5.3: TRACE CALLEES**
Record: `mt7603_wtbl_set_ps`, `mt7603_ps_tx_list` /
`mt76_tx_queue_skb_raw`, `mt76_release_buffered_frames` (empty-PS-queue
only), `ieee80211_sta_eosp`, `ieee80211_send_eosp_nullfunc` — all exist
in this tree.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Client trigger (QoS-Null/PS-Poll) → mac80211 →
`mt7603_release_buffered_frames`. **Yes, userspace/STA traffic triggers
it.** Typical clients: phones with U-APSD.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Generic `mt76_queue_ps_skb()` in this tree still only sets
`IEEE80211_TX_STATUS_EOSP` + MORE_DATA, not wire EOSP (mainline patch
04). `mt7603_rx_loopback_skb()` sets `ieee80211_sta_set_buffered(...,
true)` and never clears it (mainline patch 06). Same U-APSD family,
different bugs.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `mt7603_ps_set_more_data` and
`mt7603_release_buffered_frames` in
`drivers/net/wireless/mediatek/mt76/mt7603/main.c` are **byte-for-byte
identical** to the parent of `697badc27a9b3`. Bug since ~2018/2019.

Local tree: `p-5.15-2-g6703e5d2f3a29`, **5.15.221**. `git merge-base
--is-ancestor 697badc27a9b3 HEAD` → **not in this tree**.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Same function bodies; needed APIs
(`ieee80211_send_eosp_nullfunc`, `ieee80211_get_qos_ctl`,
`IEEE80211_QOS_CTL_EOSP`, `IEEE80211_FRAME_RELEASE_UAPSD`) are in 5.15.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No related U-APSD EOSP/TIM/HW-rearm fixes on this file in this
tree.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`). Criticality:
**IMPORTANT** for users of that hardware (MT7603E / MT7628/MT7688 APs —
very common home routers), not core mm/net.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (since 5.0-era). This is a long-standing bug, not
a regression in new code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (or GO) mode on MT7603/MT7628 with
U-APSD (or PS-Poll) clients.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: STA enters power save; hardware redirects frames into
`msta->psq`; STA sends a U-APSD trigger. Common for phones. Unprivileged
wireless clients can trigger it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **Downlink stall / client freeze** until the STA gives up
(disconnect/retry). Not a kernel oops. Severity: **HIGH** for affected
APs (connectivity loss), not CRITICAL kernel crash.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7603 AP users — restores U-APSD SP completion
  so phones keep triggering.
- **Risk:** low–medium (contained ~50-line logic in one ops callback; no
  API/lock/core changes).
- **Ratio:** benefit outweighs risk.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real, user-visible stall (U-APSD SP never ends on the air)
- Matches mac80211 driver contract
- Present in this 5.15 tree since driver introduction
- Functions identical to mainline parent → clean apply
- Small, one file, no new APIs
- Maintainer-authored, merged to mainline as `697badc27a9b3`
- Corroborated by OpenWrt MT7603/iPhone freeze reports

**AGAINST:**
- Not crash/UAF/security
- Series 05/10 (other patches are separate bugs/chips)
- Follow-ups 06–08 still missing here (incomplete *overall* U-APSD, but
  this patch is a complete EOSP fix)
- No extra reviewer tags

**UNRESOLVED:**
- Direct lore.kernel.org HTTP often 403; thread recovered via `b4`
- No explicit stable@ discussion found

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — protocol-correct; maintainer
   merged; consistent with mac80211 docs and iwlwifi’s
   `ieee80211_send_eosp_nullfunc` usage
2. Fixes a real bug that affects users? **PASS** — stall / client freeze
   on common AP chipsets
3. Important issue? **PASS** — serious connectivity failure for U-APSD
   STAs (not a panic, but production-breaking for those devices)
4. Small and contained? **PASS** — one file, +63/−11
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean; APIs present

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. It is a **driver
protocol bugfix**.

**Step 9.4: DECISION**
Backport to this 5.15 tree. The bug exists here; the fix is self-
contained and applies cleanly. Companion commits `d5001f493fef` and
`636a883e2feef` are worth later evaluation but are not required for this
one.

---

### What the commit solves, and why it matters here

mt7603 implements its own `.release_buffered_frames` because hardware
redirects frames into a driver PS queue. That path tagged every frame
with `MORE_DATA` and never set EOSP on the air. mac80211 only saw
`ieee80211_sta_eosp()`, so the stack thought the SP ended while phones
waiting for EOSP stopped triggering. On 5.15 APs using `CONFIG_MT7603E`,
that is a real stall, not a cleanup.

### Stable rules / risk vs benefit

Surgical, obviously correct vs the documented U-APSD contract, no new
APIs, clean apply. Risk is limited to this driver’s PS release path.
Benefit is restoring downlink for power-save clients on a widely
deployed chipset.

### Concerns

Patches 06–08 (TIM clear, HW PS re-arm, TID filing) address **other**
remaining PS bugs. They are not compile or semantic prerequisites for
this hunk. Patch 04 is the analogous EOSP fix for chips that use generic
`mt76_release_buffered_frames`; mt7603 only hits that when its PS queue
is empty.

---

Verification:
- [Phase 1] Parsed subject/body/tags: Link is 05/10; author Felix
  Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: +63/−11 in `mt7603_release_buffered_frames`;
  MORE_DATA+EOSP assignment; stop double SP end; QoS-Null for MMPDU
- [Phase 2] Confirmed `IEEE80211_QOS_CTL_EOSP` is 0x0010 and
  `ieee80211_get_qos_ctl()` returns `u8 *` to the first QoS byte
- [Phase 2] Confirmed `ieee80211_send_eosp_nullfunc()` in 5.15 sets
  `IEEE80211_TX_STATUS_EOSP` on the NDP; TX status clears `WLAN_STA_SP`
- [Phase 3] blame: `c8846e101502` / `b126c8897435` / `b7001f46085e`; all
  ancestors of HEAD
- [Phase 3] `git merge-base --is-ancestor 697badc27a9b3 HEAD` → not
  present
- [Phase 3] Follow-ups on origin/master: `d5001f493fef`, `636a883e2feef`
  only; no revert
- [Phase 4] `b4 dig -c 697badc27a9b3`: v1 series, msgid
  `20260801145334.1166751-5-nbd@nbd.name`
- [Phase 4] `b4 dig -w`: linux-wireless@ + author only
- [Phase 4] `b4 mbox`: 11 messages; robot fail is patch
  10/`ieee80211_txq_aql_pending`, unrelated
- [Phase 4] OpenWrt mt76#1084: EOSP-related change reported to stop
  iPhone freezes
- [Phase 5] ops hook `.release_buffered_frames =
  mt7603_release_buffered_frames`; callers are mac80211 PS-Poll/U-APSD
- [Phase 5] `ieee80211_send_eosp_nullfunc` exists and is exported in
  this tree; iwlwifi calls it from TX/BH
- [Phase 6] `make kernelversion` → 5.15.221; `git describe HEAD` →
  p-5.15-2-g6703e5d2f3a29
- [Phase 6] Byte-for-byte match of both functions vs `697badc27a9b3^`
- [Phase 7] `CONFIG_MT7603E` present for MT7603E/MT7628
- [Phase 8] Failure mode: downlink stall / client freeze, severity HIGH
  for that hardware
- UNVERIFIED: exhaustive stable@ archive search (lore HTTP 403); no
  evidence of a prior stable rejection

**YES**

 .../net/wireless/mediatek/mt76/mt7603/main.c  | 74 ++++++++++++++++---
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 0d7c84941cd0a..f8a43d9f72f95 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -423,13 +423,33 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 	mt7603_ps_tx_list(dev, &list);
 }
 
+static struct ieee80211_hdr *
+mt7603_ps_skb_hdr(struct sk_buff *skb)
+{
+	return (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
+}
+
+/*
+ * Buffered frames can be recycled into the PS queue by mt7603_filter_tx(), so
+ * both bits have to be assigned, not just set.
+ */
 static void
-mt7603_ps_set_more_data(struct sk_buff *skb)
+mt7603_ps_set_flags(struct sk_buff *skb, bool more_data, bool eosp)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr *hdr = mt7603_ps_skb_hdr(skb);
+
+	if (more_data)
+		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+	else
+		hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+
+	if (!ieee80211_is_data_qos(hdr->frame_control))
+		return;
 
-	hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
-	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+	if (eosp)
+		*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+	else
+		*ieee80211_get_qos_ctl(hdr) &= ~IEEE80211_QOS_CTL_EOSP;
 }
 
 static void
@@ -442,7 +462,10 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
 	struct mt7603_dev *dev = hw->priv;
 	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
 	struct sk_buff_head list;
-	struct sk_buff *skb, *tmp;
+	struct sk_buff *skb, *tmp, *last;
+	bool eosp_null, uapsd;
+	u16 pending = 0;
+	u8 last_tid;
 
 	__skb_queue_head_init(&list);
 
@@ -458,20 +481,49 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
 
 		skb_set_queue_mapping(skb, MT_TXQ_PSD);
 		__skb_unlink(skb, &msta->psq);
-		mt7603_ps_set_more_data(skb);
 		__skb_queue_tail(&list, skb);
 		nframes--;
 	}
+
+	skb_queue_walk(&msta->psq, skb)
+		pending |= BIT(skb->priority);
 	spin_unlock_bh(&dev->ps_lock);
 
-	if (!skb_queue_empty(&list))
-		ieee80211_sta_eosp(sta);
+	last = skb_peek_tail(&list);
+	if (!last) {
+		mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
+					     more_data);
+		return;
+	}
+
+	/*
+	 * End the service period here instead of passing the remaining frame
+	 * budget on to mt76_release_buffered_frames(), which would signal the
+	 * end of the same service period a second time.
+	 */
+	uapsd = reason == IEEE80211_FRAME_RELEASE_UAPSD;
+	more_data |= !!(pending & tids);
+
+	skb_queue_walk(&list, skb)
+		mt7603_ps_set_flags(skb, skb != last || more_data,
+				    skb == last && uapsd);
+
+	/*
+	 * EOSP lives in the QoS control field, so a bufferable MMPDU cannot
+	 * terminate a U-APSD service period on its own. In that case mac80211
+	 * has to append a QoS-Null frame, which ends the SP through its tx
+	 * status.
+	 */
+	eosp_null = uapsd &&
+		    !ieee80211_is_data_qos(mt7603_ps_skb_hdr(last)->frame_control);
+	last_tid = __fls(tids);
 
 	mt7603_ps_tx_list(dev, &list);
 
-	if (nframes)
-		mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
-					     more_data);
+	if (eosp_null)
+		ieee80211_send_eosp_nullfunc(sta, last_tid);
+	else
+		ieee80211_sta_eosp(sta);
 }
 
 static int
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] soc: amlogic: meson-clk-measure: remove debugfs tree
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (20 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/tegra241-cmdqv: Rate-limit the error ISR's log message Sasha Levin
                   ` (26 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Neil Armstrong, Sasha Levin, khilman,
	linux-arm-kernel, linux-amlogic, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 67481152be2ec5de3529664c82054b43d6d4b9f5 ]

meson_msr_probe() creates a debugfs tree with entries that reference
devm-managed measurement table entries and the driver's private regmap
state. The driver has no remove callback, so unbinding the device can
leave those debugfs entries behind after the private data is released.

Store the debugfs root and remove the subtree from a new remove callback.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20260615091531.21964-1-pengpeng@iscas.ac.cn
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
- Record: `[soc: amlogic: meson-clk-measure]` `[remove]` `[tear down
  leftover debugfs on driver unbind]`

**Step 1.2 — Tags**
- `Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>` (Amlogic SoC
  maintainer; also committed the patch)
- `Link:
  https://patch.msgid.link/20260615091531.21964-1-pengpeng@iscas.ac.cn`
- `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
- `Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>`
  (maintainer)
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Cc: stable`
  (absence is expected)
- No syzbot / bugzilla / CVE tags

**Step 1.3 — Body**
- Record: `[Bug: probe creates debugfs entries that point at devm-
  managed `msr_table` and private regmap state, but the driver had no
  remove callback.]`
- `[Symptom: after unbind, leftover debugfs files can be used after that
  memory is released.]`
- `[Version info: none in the message. Driver has existed since v5.0.]`
- `[Root cause: missing lifetime teardown for debugfs vs. devm-managed
  private data.]`

**Step 1.4 — Hidden bug fix?**
- Record: `[Not hidden. This is an explicit lifetime/UAF fix, even
  though the verb is "remove".]`

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
- Record: `[drivers/soc/amlogic/meson-clk-measure.c: +14 / −0]`
- Functions: `struct meson_msr` (new `debugfs_root`),
  `meson_msr_probe()`, new `meson_msr_remove()`, `meson_msr_driver`
  table
- Scope: single-file surgical fix

**Step 2.2 — Code flow**
- Before: `meson_msr_probe()` builds `/sys/kernel/debug/meson-clk-msr/`
  (`measure_summary` plus per-clock files). File private data is
  `priv->data.msr_table` and `&priv->data.msr_table[i]`, with `.priv =
  priv`. `priv`, `msr_table`, `reg`, and `regmap` are all `devm_*`
  allocations. There was no `platform_set_drvdata()` and no `.remove`.
- After: root dentry is stored, `platform_set_drvdata()` is set, and
  `meson_msr_remove()` calls `debugfs_remove_recursive()` so the tree is
  gone before devres frees private data.
- Path: driver remove / module unload / sysfs unbind, not the normal
  measure path.

**Step 2.3 — Bug mechanism**
- Record: `[Use-after-free / leftover debugfs after unbind]`
- Mechanism: unbind runs `devres` teardown and frees `priv` /
  `msr_table` / `regmap`. Debugfs files remain. `clk_msr_summary_show()`
  does `msr_table->priv->data.msr_count`; `meson_measure_id()` then uses
  `priv->regmap` and `priv->data.reg`. That is a UAF if those files are
  read after unbind.
- Category (c)/(d): lifetime/refcount-style teardown; memory safety.

**Step 2.4 — Fix quality**
- Record: `[Obviously correct, minimal, standard pattern.]`
- `debugfs_remove()` itself already ignores `IS_ERR_OR_NULL`, so the
  extra check is redundant but harmless.
- `platform_set_drvdata()` is required for `platform_get_drvdata()` in
  remove.
- `.remove` is `void (*)(struct platform_device *)` in this tree,
  matching the new callback.
- Regression risk: low. `debugfs_remove()` uses
  `simple_recursive_removal()`, so in-flight file users are drained
  before return. No public API change.

## Phase 3: Git history

**Step 3.1 — Blame**
- Record: `[Buggy debugfs creation is from 2b45ebef39a2c ("soc: amlogic:
  Add Meson Clock Measure driver"), 2018-11-28, first in v5.0-rc1.]`
- The missing-remove bug is as old as the driver. Confirmed on the
  parent of the fix: no `platform_set_drvdata`, no `debugfs_root`, no
  remove callback.

**Step 3.2 — Fixes: tag**
- Record: `[No Fixes: tag. Introducer is 2b45ebef39a2c, present in this
  tree.]`

**Step 3.3 — File history**
- Record: `[Recent commits add SoC tables (A1/T7, S4, C3) and register-
  offset refactoring. None change debugfs lifetime.]`
- Standalone, not patch X/Y.

**Step 3.4 — Author**
- Record: `[Pengpeng Hou: only this commit on this driver.
  Reviewer/committer Neil Armstrong is the original driver author and
  Amlogic maintainer.]`

**Step 3.5 — Dependencies**
- Record: `[None. Uses existing `debugfs_create_dir` /
  `debugfs_remove_recursive` / `platform_set_drvdata`. Can apply
  standalone to this tree.]`

## Phase 4: Mailing list and external research

**Step 4.1 — Original discussion**
- Record: `[https://patch.msgid.link/20260615091531.21964-1-
  pengpeng@iscas.ac.cn]`
- `b4 dig -a`: only v1; that version was applied.
- Maintainer review: `Reviewed-by: Neil Armstrong`.
- Sashiko bot flagged a pre-existing probe-time race (`measure_summary`
  created before `.priv` is filled). Armstrong replied: “Impossible the
  driver is initialized way before userspace starts.” That race is not
  introduced by this patch and was not treated as a blocker.
- No NAK. No reviewer request for `Cc: stable`.

**Step 4.2 — Recipients (`b4 dig -w`)**
- Record: `[Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin
  Blumenstingl, linux-amlogic, linux-arm-kernel, linux-kernel. Right
  maintainers were on the patch.]`

**Step 4.3 — Bug report**
- Record: `[No Reported-by / syzbot / bugzilla. Bug is from code
  inspection of lifetime mismatch.]`

**Step 4.4 — Series**
- Record: `[Standalone single patch. No follow-up on this file after
  67481152be2ec.]`

**Step 4.5 — Stable list**
- Record: `[UNVERIFIED: lore.kernel.org/stable returned HTTP 403.]`

## Phase 5: Code semantic analysis

**Step 5.1 — Functions**
- Record: `[meson_msr_probe, meson_msr_remove (new), meson_msr_driver;
  readers clk_msr_show / clk_msr_summary_show / meson_measure_id]`

**Step 5.2 — Callers**
- Record: `[probe/remove from the platform core on bind/unbind. Debugfs
  show via `DEFINE_SHOW_ATTRIBUTE`. `meson_msr_remove` is only the new
  driver `.remove`.]`

**Step 5.3 — Callees**
- Record: `[debugfs_create_dir/file, debugfs_remove_recursive,
  platform_set/get_drvdata, and on read: mutex + regmap MMIO.]`

**Step 5.4 — Reachability**
- Record: `[Yes. CONFIG_MESON_CLK_MEASURE is tristate, default y on
  ARCH_MESON. DT nodes exist for GX, Meson8/8b, AXG, G12A, SM1, C3, S4,
  A1, T7. Unbind is `rmmod meson-clk-measure` or sysfs unbind, then
  reading leftover debugfs. Typically root-only, but still a real kernel
  UAF.]`

**Step 5.5 — Similar patterns**
- Record: `[Same teardown exists in other SoC drivers (qcom
  smem/socinfo/aoss, ti smartreflex). This driver was the one missing
  it.]`

## Phase 6: This tree (v7.3-rc4)

**Step 6.1 — Does the buggy code exist here?**
- Record: `[Yes in this lineage. Driver is `drivers/soc/amlogic/meson-
  clk-measure.c`. Bug introduced in v5.0 (2b45ebef39a2c). This checkout
  is `v7.3-rc4-27-gf0100363d8c37` / 7.3.0-rc4. The fix landed in
  v7.3-rc1 (`git merge-base --is-ancestor 67481152be2ec v7.3-rc1`
  succeeded; it is not in v7.2).]`
- Current file already has `debugfs_root` and `meson_msr_remove()`. That
  is because the commit merged during 7.3; it is not a reason to treat
  the bug as never existing here.

**Step 6.2 — Backport difficulty**
- Record: `[Clean apply on this tree. Context matches. `.remove` is
  already void.]`

**Step 6.3 — Related fixes already here?**
- Record: `[This is the fix. No alternate teardown was present before
  it.]`

## Phase 7: Subsystem context

**Step 7.1**
- Record: `[Subsystem: drivers/soc/amlogic clock-measure debugfs helper.
  Criticality: PERIPHERAL (Amlogic-only, debugfs), but UAF is still a
  crash/memory-safety bug.]`

**Step 7.2**
- Record: `[Mature driver (2018). Recent work is new SoC tables, not
  lifetime redesign.]`

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
- Record: `[Amlogic Meson users with CONFIG_MESON_CLK_MEASURE and
  CONFIG_DEBUG_FS, after driver unbind/unload.]`

**Step 8.2 — Trigger**
- Record: `[Unbind or rmmod, then open leftover debugfs. Not a boot-hot
  path. Privileged in typical debugfs setups. Deterministic UAF, not a
  heisenrace.]`

**Step 8.3 — Failure mode**
- Record: `[UAF → oops / KASAN / possible memory corruption. Severity:
  HIGH.]`

**Step 8.4 — Risk-benefit**
- Record: `[Benefit: high for the affected unbind path (prevents UAF).
  Risk: very low (14 lines, standard debugfs teardown). Ratio favors
  taking the fix.]`

## Phase 9: Synthesis

**Step 9.1 — Evidence**

For:
- Real UAF: leftover debugfs vs. `devm` private data after unbind
- Small (+14), obviously correct
- Reviewed and applied by the subsystem maintainer
- Driver and bug exist in this 7.3 tree’s history since v5.0
- `MESON_CLK_MEASURE` is tristate, so module unload is a supported path
- Same teardown pattern used elsewhere in `drivers/soc/`

Against:
- No user/syzbot report
- Debugfs, typically root-only
- Amlogic-only helper, not core kernel
- Maintainer did not nominate stable

Unresolved:
- Could not search lore.kernel.org/stable (HTTP 403)

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — standard remove +
   `debugfs_remove_recursive`; maintainer Reviewed-by
2. Real bug affecting users? **PASS** — leftover debugfs after unbind is
   a UAF
3. Important (crash/security/corruption/deadlock)? **PASS** — UAF oops /
   memory-safety; HIGH, not a theoretical warning
4. Small and contained? **PASS** — 14 lines, one file
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS** — driver present, void `.remove`, no
   missing prereqs

**Step 9.3 — Exception category**
- Record: `[None. This is a normal bugfix, not a device-
  ID/quirk/DT/build/docs exception.]`

**Step 9.4 — Decision**
This tree is 7.3-rc4. The clock-measure driver is here, the missing-
remove UAF has been here since v5.0, and the patch is a small, correct
teardown. It meets stable criteria for this checkout.

### What it fixes and why it matters
`meson_msr_probe()` publishes debugfs files whose private pointers refer
to `devm`-allocated `priv` / `msr_table` / `regmap`. Without a remove
callback those dentries survive unbind, so a later read of
`measure_summary` or a per-clock file uses freed memory. On 7.3 that is
a real module-unload/unbind UAF on Amlogic boards that ship this IP.

### Stable rules / risk
The change is 14 lines, does not add APIs, and matches
`debugfs_remove()` semantics already used by sibling SoC drivers.
Benefit is preventing a UAF; regression risk is very low.

### Concerns
No public reproducer. Trigger is privileged debugfs/unbind. That lowers
breadth, not severity. No extra commits are required on this tree.

Verification:
- [Phase 1] Parsed tags: Reviewed-by Neil Armstrong; Link to msgid
  20260615091531.21964-1; no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: +14 in meson-clk-measure.c; store debugfs root, set
  drvdata, add void remove
- [Phase 2] Pre-fix parent 67481152be2ec^: no platform_set_drvdata, no
  debugfs_root, no remove
- [Phase 2] clk_msr_summary_show uses msr_table->priv; meson_measure_id
  uses priv->regmap — UAF after unbind confirmed
- [Phase 3] git blame: debugfs create from 2b45ebef39a2c (v5.0-rc1)
- [Phase 3] git describe HEAD: v7.3-rc4-27-gf0100363d8c37; Makefile
  7.3.0-rc4
- [Phase 3] git merge-base --is-ancestor 67481152be2ec v7.3-rc1: yes;
  not in v7.2
- [Phase 4] b4 dig -c 67481152be2ec:
  https://patch.msgid.link/20260615091531.21964-1-pengpeng@iscas.ac.cn
- [Phase 4] b4 dig -a: v1 only, applied as-is
- [Phase 4] b4 dig -w: Armstrong, Hilman, Brunet, Blumenstingl, linux-
  amlogic
- [Phase 4] mbox: Armstrong Reviewed-by; dismissed sashiko probe-race as
  pre-existing/impossible
- [Phase 5] Kconfig MESON_CLK_MEASURE tristate default ARCH_MESON; DT
  compatibles in meson-gx/g12/axg/sm1/s4/a1/t7/c3 dtsi
- [Phase 5] platform_driver.remove is void (*)(struct platform_device *)
  in include/linux/platform_device.h:280
- [Phase 5] debugfs_remove() already IS_ERR_OR_NULL-safe
  (fs/debugfs/inode.c:778)
- [Phase 6] File present; no later changes on this file after the fix
- [Phase 8] Failure mode: UAF on leftover debugfs after unbind, severity
  HIGH
- UNVERIFIED: lore.kernel.org/stable search (HTTP 403)

**YES**

 drivers/soc/amlogic/meson-clk-measure.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
index d862e30a244ed..7ca43bcb622a2 100644
--- a/drivers/soc/amlogic/meson-clk-measure.c
+++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -7,6 +7,7 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/bitfield.h>
+#include <linux/err.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/regmap.h>
@@ -50,6 +51,7 @@ struct meson_msr_data {
 struct meson_msr {
 	struct regmap *regmap;
 	struct meson_msr_data data;
+	struct dentry *debugfs_root;
 };
 
 #define CLK_MSR_ID(__id, __name) \
@@ -952,6 +954,7 @@ static int meson_msr_probe(struct platform_device *pdev)
 	       sizeof(struct msr_reg_offset));
 
 	root = debugfs_create_dir("meson-clk-msr", NULL);
+	priv->debugfs_root = root;
 	clks = debugfs_create_dir("clks", root);
 
 	debugfs_create_file("measure_summary", 0444, root,
@@ -967,9 +970,19 @@ static int meson_msr_probe(struct platform_device *pdev)
 				    &priv->data.msr_table[i], &clk_msr_fops);
 	}
 
+	platform_set_drvdata(pdev, priv);
+
 	return 0;
 }
 
+static void meson_msr_remove(struct platform_device *pdev)
+{
+	struct meson_msr *priv = platform_get_drvdata(pdev);
+
+	if (!IS_ERR_OR_NULL(priv->debugfs_root))
+		debugfs_remove_recursive(priv->debugfs_root);
+}
+
 static const struct msr_reg_offset msr_reg_offset = {
 	.duty_val = 0x0,
 	.freq_ctrl = 0x4,
@@ -1065,6 +1078,7 @@ MODULE_DEVICE_TABLE(of, meson_msr_match_table);
 
 static struct platform_driver meson_msr_driver = {
 	.probe	= meson_msr_probe,
+	.remove = meson_msr_remove,
 	.driver = {
 		.name		= "meson_msr",
 		.of_match_table	= meson_msr_match_table,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] iommu/tegra241-cmdqv: Rate-limit the error ISR's log message
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (21 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18] soc: amlogic: meson-clk-measure: remove debugfs tree Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] mmc: sdhci-of-ma35d1: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (25 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Nicolin Chen, Will Deacon, Sasha Levin, thierry.reding, joro,
	jonathanh, linux-tegra, linux-arm-kernel, iommu, linux-kernel

From: Nicolin Chen <nicolinc@nvidia.com>

[ Upstream commit a86c36163c9722545d27e92bdad8418fdcaa8b1d ]

tegra241_cmdqv_isr() logs the error-map registers on every error interrupt.
A malfunctioning device, or a guest deliberately faulting its own VCMDQs,
can raise these interrupts rapidly, and the unconditional dev_warn() then
floods the kernel log.

Rate-limit the message with dev_warn_ratelimited(), and pass the error-map
registers straight to it so their four MMIO reads run only when the limiter
prints, instead of building the string on every interrupt.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local checkout is **v7.3-rc4**. The driver and the unconditional ISR
`dev_warn()` are present here; the change is a small, self-contained
log-flood / guest-DoS mitigation, so it belongs in this tree.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[iommu/tegra241-cmdqv] [Rate-limit] [stop the error ISR from
printing on every interrupt]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by / Acked-by:** none on the commit itself
- **Link:** none
- **Cc: stable:** none on this patch
- **Assisted-by:** Claude:claude-opus-4-8
- **Signed-off-by:** Nicolin Chen (NVIDIA; author), Will Deacon (arm-
  smmu maintainer; applied it)
- Pipeline markers such as Sasha Levin SOB / “[Upstream commit]” were
  not on the real commit (`a86c36163c972`)

Notable: no user/syzbot report. The cover letter says the series came
from **Sashiko** (LLM) review, not a production crash.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `tegra241_cmdqv_isr()` logs error-map registers with
  unconditional `dev_warn()` on every error interrupt.
- **Symptom:** kernel log flood.
- **Trigger (stated):** malfunctioning device, or a **guest deliberately
  faulting its own VCMDQs**, raising interrupts rapidly.
- **Root cause:** every interrupt builds a 256-byte string (including
  four extra MMIO reads) and prints it.
- **Fix:** `dev_warn_ratelimited()`, and pass the MMIO reads as printk
  args so they run only when the limiter actually prints.
- **Version info:** none in the message.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit flood/DoS mitigation.
It does not fix a UAF, leak, or crash by itself.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c` (+7 / −9)
- Function: `tegra241_cmdqv_isr()`
- Scope: **single-file surgical** (one logging site)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** ISR always `snprintf()`s into `char err_str[256]`, always
  does four `CMDQ_ERR_MAP` MMIO reads, always `dev_warn()`.
- **After:** no stack buffer; `dev_warn_ratelimited(...)` with the four
  `readl_relaxed()` calls as arguments.
- Path: **error interrupt path** (threaded IRQ). Error *handling* after
  the log is unchanged.

Verified `dev_level_ratelimited()` in `include/linux/dev_printk.h`: the
`__VA_ARGS__` are only substituted inside `if (__ratelimit(&_rs))`, so
those MMIO reads run only when a line is printed.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** ISR log flood / availability (guest-triggered printk
  storm), plus extra MMIO on every interrupt.
- **Not:** UAF, leak, deadlock, OOB, or NULL deref.
- **Hardware workaround?** No.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct: standard `*_ratelimited` pattern already used in
  other IOMMU fault paths (`arm-smmu-v3.c`, `virtio-iommu.c`, AMD/Intel,
  etc.).
- Minimal; no unrelated edits.
- Regression risk: **very low**. Worst case is fewer error-map dumps in
  dmesg (intended). Error recovery is untouched.
- Red flags: LLM-assisted; no `Fixes:`/`Reported-by`. Not a new API.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Unconditional `dev_warn()` + `snprintf` were in the original driver:
  `918eb5c856f6` (“Add in-kernel support for NVIDIA Tegra241 (Grace)
  CMDQV”), **2024-08-30**, first in **v6.12-rc1**.
- This tree is **v7.3-rc4**, so that code is in this lineage.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. N/A. The logging has been there since the
driver was added.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: This is **v2 11/11** of “Fix error-interrupt races and VINTF
lifecycle bugs” (Nicolin Chen, 2026-07-14). Cover letter: ordered
**most-critical-first**; this is the last, smallest issue (“ISR flooding
the kernel log under repeated guest errors”).
Standalone: it only changes the log line and does **not** need the
earlier UAF/lifecycle patches to be correct.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Nicolin Chen is the NVIDIA CMDQV contributor for this file; Will
Deacon applied the series. Same-day siblings are real
lifecycle/UAF/bounds fixes. This one is the leftover logging hardening.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None required. `dev_warn_ratelimited` is old. The hunk applies
to the original ISR as well as the post-series ISR.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c a86c36163c972` → https://patch.msgid.link/2e9d088c059037d5f
  c23532820444720b870d2c7.1784059577.git.nicolinc@nvidia.com
- **v1** (2026-07-02) and **v2** (2026-07-14); committed version is **v2
  11/11**.
- No NAK on this patch. Review noise in the thread was about **patch
  10/11** (dropped); Will applied 01–09 and 11.
- No reviewer asked for `Cc: stable` on *this* patch. Patch 07/11 in the
  same series did have `Cc: stable` (unrelated vSID check).
- WebFetch to lore returned **403**; thread was read from the b4 mbox
  instead.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Nicolin Chen, Will Deacon, Robin Murphy, Joerg
Roedel, Jason Gunthorpe; lists `iommu@`, `linux-arm-kernel`, `linux-
tegra`. Maintainer **Will Deacon applied it** (“Applied (apart from
patch 10)”).

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla link. Origin is **Sashiko** static review,
described in the cover letter. Nicolin also noted Sashiko false
positives (including a wrong “level-triggered / kdump storm” claim);
CMDQV is **edge-triggered**, so an *unacked* pending error does not re-
assert. **Each new error still fires the ISR**, which is the remaining
flood path this patch addresses.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 11-patch series; this patch is independent logging. Not blocked
on the dropped 10/11.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** via lore.kernel.org/stable (HTTP 403). The
submitted 11/11 message itself has no `Cc: stable`.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

semcode MCP: **not available**. Used `git grep` / file reads.

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `tegra241_cmdqv_isr()` only.

**Step 5.2: TRACE CALLERS**
Record: Registered in `__tegra241_cmdqv_probe()` via
`request_threaded_irq(..., tegra241_cmdqv_isr, IRQF_ONESHOT, ...)`. Not
a hardirq; still a hot error path. Hardware: NVIDIA Tegra241 (Grace)
CMDQ-V (`CONFIG_TEGRA241_CMDQV`).

**Step 5.3: TRACE CALLEES**
Record: `readl_relaxed` of VINTF/CMDQ error maps;
`dev_warn_ratelimited`; then `tegra241_vintf0_handle_error` /
`tegra241_vintf_user_handle_error`. Those handlers are unchanged.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable when CMDQV is enabled (Grace SMMU). A guest with a
user VINTF/VCMDQ can generate command-queue errors; each new error
latches and interrupts. That is a userspace/VM-reachable path, not a
theoretical internal-only site.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Rate-limited IOMMU fault logs are the normal pattern elsewhere.
This driver was the outlier with a raw `dev_warn()` in the ISR.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- `git describe HEAD` → **v7.3-rc4-27-gf0100363d8c37**
- `make kernelversion` → **7.3.0-rc4**
- Driver file exists; original ISR logging from `918eb5c856f6` (v6.12).
- `git merge-base --is-ancestor a86c36163c972 HEAD` → **yes** (already
  merged here). That is not used as “already selected for stable”; it
  only confirms this lineage has the driver and the fix.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply** on this tree (already applied). The hunk does
not depend on later ISR locking. On a tree that still has the original
`snprintf`/`dev_warn` ISR, it would apply with at most trivial context.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No earlier equivalent rate-limit. `a2ee315db4261` only uses
`WARN_ON_ONCE` for out-of-bounds map bits; it does not throttle the
“unexpected error reported” line.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/iommu/arm/arm-smmu-v3** (NVIDIA Grace CMDQ-V).
**PERIPHERAL/IMPORTANT for that platform**: only `CONFIG_TEGRA241_CMDQV`
/ Tegra241 (Grace) systems, including virtualization hosts using user
VINTFs.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Actively developed in 2026 (large Sashiko fix series + iommufd
work). Logging bug itself is old (v6.12).

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **platform-specific / config-specific** — NVIDIA Grace +
`CONFIG_TEGRA241_CMDQV`. Hosts that expose guest VCMDQs are the
interesting population.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: CMDQV error IRQ. Commonness: rare on healthy HW; can be
**frequent** if a device malfunctions or a **guest injects VCMDQ
errors**. Unprivileged guest with VCMDQ access can trigger it. Not every
boot.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record:
- Direct effect: dmesg/console flood; extra MMIO + `snprintf` on every
  interrupt.
- Indirect: printk/console contention, lost messages, possible stalls on
  a slow console.
- Not an oops, UAF, or data corruption.
- **Severity: MEDIUM** (availability / “oh, that’s not good”), with a
  stated guest DoS path.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** medium for Grace virtualization hosts; low for everyone
  else.
- **Risk:** very low (7 lines, logging only).
- **Ratio:** favorable. Official stable rules allow “oh, that’s not
  good” and require an exploit explanation for “could be a problem”
  issues; the message gives that explanation.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, described flood: guest or bad device can fire the error IRQ
  repeatedly; each new error still interrupts (edge-triggered, latched
  per event).
- Tiny, obviously correct, matches other IOMMU drivers.
- Error handling unchanged; MMIO for the log runs only when printing.
- Driver and buggy logging exist in **this** 7.3-rc4 tree (since v6.12).
- Applied by the arm-smmu maintainer; no NAK on this patch.
- Official rules: not a trivia cleanup; exploit path is written down.

AGAINST:
- No production `Reported-by`; LLM-found.
- Least-critical patch in its series (11/11).
- Threaded IRQ (`IRQF_ONESHOT`), so not a hardirq printk.
- Unacked-guest *storm* was already ruled out as a false positive; this
  only limits *new*-error spam.
- Not a crash/corruption/UAF.

UNRESOLVED:
- Could not query lore.kernel.org/stable (403).
- No Tested-by.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — standard ratelimit;
   maintainer applied. No extra tester tag.
2. Fixes a real bug that affects users? **PASS** — log flood / guest-
   driven interrupt spam on Grace CMDQV; users of that hardware exist.
3. Important issue? **PASS** (low end) — not oops/corruption; it is an
   explained availability issue (“oh, that’s not good” / guest printk
   DoS), which the documented rules allow.
4. Small and contained? **PASS** — ~16 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — pre-image exists here; apply
   is clean.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID, quirk table, DT, build, or docs fix).
Qualifies as a normal small bugfix, not via an exception.

**Step 9.4: MAKE YOUR DECISION**
This tree contains the Tegra241 CMDQV driver and the original
unconditional ISR `dev_warn()`. The patch is a 7-line, obviously correct
rate-limit that closes a guest-reachable log flood without touching
recovery logic. Benefit is limited to Grace CMDQV, but risk is
negligible, so it meets the bar for this tree.

What it solves for users here: a VM or failing CMDQ can spam the host
log and extra MMIO on every error IRQ. That is not a panic, but it is a
real host-side availability nuisance on this platform.

Verification:
- [Phase 1] Tags: Assisted-by Claude; SOB Nicolin Chen + Will Deacon; no
  Fixes/Reported-by/Cc: stable on this commit
- [Phase 2] Diff: `tegra241_cmdqv_isr()` snprintf+dev_warn →
  dev_warn_ratelimited; +7/−9
- [Phase 2] Confirmed `dev_level_ratelimited` only evaluates args when
  `__ratelimit()` allows print
- [Phase 3] `git blame` / original file: logging from `918eb5c856f6`
  (v6.12-rc1)
- [Phase 3] `git describe --contains 918eb5c856f6` →
  v6.12-rc1~149^2^2~19
- [Phase 3] Series: v2 11/11; parent is VINTF0 leak fix, not a
  functional prereq
- [Phase 4] `b4 dig -c a86c36163c972`: lore/patch.msgid.link match; v1
  then v2
- [Phase 4] `b4 dig -a`: v1 2026-07-02, v2 2026-07-14 (applied)
- [Phase 4] `b4 dig -w`: iommu maintainers on To/Cc; Will applied 11/11,
  dropped 10/11
- [Phase 4] mbox: cover letter lists log flood; no comments/NAK on
  11/11; Cc: stable only on 07/11
- [Phase 4] WebFetch lore/stable: 403; stable-list search UNVERIFIED
- [Phase 5] Caller: `request_threaded_irq` in `__tegra241_cmdqv_probe`;
  CONFIG_TEGRA241_CMDQV
- [Phase 6] `git describe HEAD` → v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` → 7.3.0-rc4
- [Phase 6] `git merge-base --is-ancestor a86c36163c972 HEAD` → ancestor
  (code exists here)
- [Phase 8] Failure mode: printk flood / guest DoS, severity MEDIUM
- UNVERIFIED: lore.kernel.org/stable discussion (HTTP 403)

**YES**

 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
index fdbd487848e64..8c9530873ed98 100644
--- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
@@ -350,21 +350,19 @@ static irqreturn_t tegra241_cmdqv_isr(int irq, void *devid)
 {
 	struct tegra241_cmdqv *cmdqv = (struct tegra241_cmdqv *)devid;
 	void __iomem *reg_vintf_map = REG_CMDQV(cmdqv, VINTF_ERR_MAP);
-	char err_str[256];
 	u64 vintf_map;
 
 	/* Use readl_relaxed() as register addresses are not 64-bit aligned */
 	vintf_map = (u64)readl_relaxed(reg_vintf_map + 0x4) << 32 |
 		    (u64)readl_relaxed(reg_vintf_map);
 
-	snprintf(err_str, sizeof(err_str),
-		 "vintf_map: %016llx, vcmdq_map %08x:%08x:%08x:%08x", vintf_map,
-		 readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(3))),
-		 readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(2))),
-		 readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(1))),
-		 readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(0))));
-
-	dev_warn(cmdqv->dev, "unexpected error reported. %s\n", err_str);
+	dev_warn_ratelimited(
+		cmdqv->dev,
+		"unexpected error reported. vintf_map: %016llx, vcmdq_map %08x:%08x:%08x:%08x\n",
+		vintf_map, readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(3))),
+		readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(2))),
+		readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(1))),
+		readl_relaxed(REG_CMDQV(cmdqv, CMDQ_ERR_MAP(0))));
 
 	/* Handle VINTF0 and its LVCMDQs */
 	if (vintf_map & BIT_ULL(0)) {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] mmc: sdhci-of-ma35d1: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (22 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/tegra241-cmdqv: Rate-limit the error ISR's log message Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp: " Sasha Levin
                   ` (24 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Ulf Hansson, Sasha Levin, adrian.hunter, ychuang3,
	schung, linux-mmc, linux-arm-kernel, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 9b3732cce41d177acac731e0b8024d72f0dfde38 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

# Stable backport analysis: `mmc: sdhci-of-ma35d1: add missing
MODULE_DEVICE_TABLE()`

Local tree: **v7.3-rc4** (`7.3.0-rc4`, `VERSION=7 PATCHLEVEL=3
SUBLEVEL=0 EXTRAVERSION=-rc4`).
Candidate: `9b3732cce41d177acac731e0b8024d72f0dfde38`.
The driver and the missing-alias bug exist in this tree; the one-line
fix is already present here as a mainline commit.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[mmc / sdhci-of-ma35d1] [add] [export OF match table via
MODULE_DEVICE_TABLE so the module can autoload]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected)
- **Reported-by / Tested-by / Reviewed-by / Acked-by:** none
- **Link:** none in the committed message
- **Cc: stable:** none (expected)
- **Signed-off-by:** Pengpeng Hou (author); Ulf Hansson (MMC maintainer,
  applied it)
- Ignore any pipeline SOBs

Notable: maintainer SOB; no user report; no syzbot.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** OF match table is wired to `.of_match_table` but not exported
  with `MODULE_DEVICE_TABLE(of, ...)`.
- **Symptom:** `depmod`/`modinfo` get no `of:` aliases, so udev/kmod
  will not autoload `sdhci-ma35` when DT has `compatible =
  "nuvoton,ma35d1-sdhci"`. Built-in (`=y`) matching still works.
- **Version info:** none in the message. Driver introduced in v6.12-rc1.
- **Root cause:** missing `MODULE_DEVICE_TABLE` so `file2alias.c` never
  publishes the table.

Original mailing-list body (stripped before commit) said this is a
source-level fix with no hardware reproduction; evidence is the table
itself.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** It is an explicit autoload/alias fix. Same class
as “add a device ID”: the ID exists; userspace was never told.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/mmc/host/sdhci-of-ma35d1.c` — **+1 / −0**
- Function: none; one statement after `sdhci_ma35_dt_ids[]`
- Scope: **single-file, one-line surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `sdhci_ma35_dt_ids` is only used as `.of_match_table` (in-
  kernel match when the module is already loaded or built-in).
- **After:** same, plus `MODULE_DEVICE_TABLE(of, sdhci_ma35_dt_ids)` so
  modpost emits `MODULE_ALIAS("of:N*T*Cnuvoton,ma35d1-sdhci")`.
- Path: **module build / autoload**, not probe/error/init runtime logic.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Hardware enablement / missing module alias]** — category
**(h) plus logic for autoload**. Not UAF, leak, race, or crash. Without
the macro, a modular build never gets OF aliases. Confirmed by
`include/linux/module.h`: `MODULE_DEVICE_TABLE` creates a `used` alias
so `scripts/mod/file2alias.c` can find the table.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- **Quality:** obviously correct; this is the documented way to export
  OF IDs.
- **Regression risk:** negligible. Macro only adds a static alias
  symbol; no locking, no API, no runtime path change except autoload
  starts working.
- **Red flags:** none on the diff. Author is doing a wide
  `MODULE_DEVICE_TABLE` sweep (rtc, vdpa, gpio, iio, …); that does not
  make *this* line wrong. MMC maintainer applied it after trimming the
  disclaimer.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Table and driver: `addc9ecb9ddb3` (“Add Nuvoton MA35D1 SDHCI driver”),
  Shan-Chun Hung, 2024-07-16, committed 2024-08-26.
- First appeared: **v6.12-rc1** (`git describe --contains addc9ecb9ddb3`
  → `v6.12-rc1~158^2~42`).
- Original driver had the match table and `.of_match_table` and **no**
  `MODULE_DEVICE_TABLE` from day one.
- Bug age: ~v6.12 through this July 2026 fix.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No Fixes: tag.** Buggy commit is the original driver add,
verified by blame and by `git show addc9ecb9ddb3` (tail of the file has
the table without the macro). That commit **is** an ancestor of this
tree.

**Step 3.3: CHECK FILE HISTORY**
Record (this file only):
- `addc9ecb9ddb3` — add driver
- `078e548af9c3a` — `remove_new` → `remove`
- `01bc623f9a5c2` — drop `sdhci_pltfm_free()`
- `995832b2cebe6` — include-header churn
- `9b3732cce41d1` — this fix

No prerequisite refactor for this one line. **Standalone.**

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Pengpeng Hou is not the MMC maintainer; many similar “add
missing MODULE_DEVICE_TABLE()” commits across subsystems. Ulf Hansson
applied this one. Related MMC precedent by others: `6e540da4c1db7`
(“mmc: sdhci-of-aspeed: fix module autoloading”) is the same one-line
change **and had `Fixes:` + `Cc: stable@vger.kernel.org`**.

**Step 3.5: DEPENDENT/PREREQUISITE COMMITS**
Record: **None.** Only needs `sdhci_ma35_dt_ids` and `module.h` (already
included). Can apply standalone on any tree that has this driver.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 9b3732cce41d1` →
  https://patch.msgid.link/20260704124115.2874-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only** (2026-07-04). Applied version is that v1
  (commit message cleaned).
- Thread (mbox): Ulf Hansson, 2026-07-06: **“Applied for next (by
  cleanup of the commit message a bit), thanks!”**
- No NAK, no reviewer-requested `Cc: stable`, no risk discussion.
- lore.kernel.org HTTP fetch returned 403 (Anubis); thread recovered via
  `b4 dig -m`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc included Ulf Hansson (MMC), Adrian Hunter
(SDHCI), Nuvoton (Jacky Huang, Shan-Chun Hung), `linux-mmc`, `linux-arm-
kernel`. Right people. Only maintainer reply was “applied”.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: **No user/syzbot/bugzilla report.** Author stated it was
inferred from source. The failure mode is still deterministic for `=m`
builds.

**Step 4.4: RELATED PATCHES AND SERIES**
Record: **Standalone 1/1.** Same-week author activity is a tree-wide
missing-alias sweep, not a multi-patch MMC series.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** via lore.kernel.org/stable (Anubis 403). No `Cc:
stable` on this patch. Closest analogue in-tree (`sdhci-of-aspeed`
autoload) *was* explicitly nominated for stable.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: **No function body changed.** Touches `sdhci_ma35_dt_ids` and
the `sdhci_ma35_driver` registration site.

**Step 5.2: TRACE CALLERS**
Record:
- `.probe = ma35_probe` — driver-core platform probe.
- `.of_match_table = sdhci_ma35_dt_ids` — OF matching when the driver is
  present.
- `MODULE_DEVICE_TABLE` is not a runtime caller; it feeds **modpost**.
- Impact surface: modular `CONFIG_MMC_SDHCI_OF_MA35D1=m` on
  `nuvoton,ma35d1-sdhci` DT.

**Step 5.3: TRACE CALLEES**
Record: Unchanged. `ma35_probe` still does `sdhci_pltfm_init` / host
setup. Macro expands to a static alias (verified in
`include/linux/module.h`).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: DT node `compatible = "nuvoton,ma35d1-sdhci"` → kmod alias
lookup → load `sdhci-ma35` → `ma35_probe`. Reachable on MA35D1 boot if
the driver is a module. Not a syscall/UAF path. **Userspace-visible:**
missing MMC/SD host until manual `modprobe`.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Other `sdhci-of-*.c` drivers already have
`MODULE_DEVICE_TABLE(of, ...)`. Historical MMC autoload fixes: aspeed,
am654, at91, mediatek. This driver was the outlier.

Kconfig: `MMC_SDHCI_OF_MA35D1` is **tristate** (`depends on ARCH_MA35 ||
COMPILE_TEST`), so `=m` is a supported config. Help text: “say Y or M
here.”

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** File exists; table and `.of_match_table` exist; the
missing alias was the original 6.12 code. This checkout already contains
the fix line at `drivers/mmc/host/sdhci-of-ma35d1.c:293`. `git merge-
base --is-ancestor addc9ecb9ddb3 HEAD` and `9b3732cce41d1 HEAD` both
succeed. Bug introduced **v6.12**, not after this tree.

**Step 6.2: BACKPORT COMPLICATIONS**
Record: **Clean apply.** One added line next to a table that has been
there since the driver was added. Later churn (`remove`,
`sdhci_pltfm_free`, includes) does not conflict with this hunk.

**Step 6.3: RELATED FIXES ALREADY HERE**
Record: This *is* the fix. No earlier equivalent. Sibling OF SDHCI
drivers already export their tables.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **MMC host / SDHCI platform driver.** Criticality:
**PERIPHERAL** (Nuvoton MA35D1 only), but it is the SD/MMC host for that
SoC — root-on-SD/eMMC is a realistic layout.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: `drivers/mmc/host/` is active (many recent fixes). This
particular file is low-churn (five commits total).

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Platform-specific / config-specific:** `ARCH_MA35` +
`CONFIG_MMC_SDHCI_OF_MA35D1=m`. Built-in (`=y`) is unaffected. Distro-
style modular kernels are the users who benefit.

**Step 8.2: TRIGGER CONDITIONS**
Record: Every boot/enumeration of `nuvoton,ma35d1-sdhci` when the driver
is a module. Not a race. Unprivileged users do not trigger it;
**boot/udev does**. Common *on that hardware* if distros ship the driver
as `=m`.

**Step 8.3: FAILURE MODE SEVERITY**
Record: **Missing driver autoload → SD/MMC host never probes → no
card/root disk until manual load.** Not oops/UAF. Severity **MEDIUM**,
**HIGH** if root is on that host and the module is not in the initramfs
by name. Same user-visible class as a missing device ID.

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** medium for MA35D1 modular builds (storage may not
  appear).
- **Risk:** **very low** (1 line, alias-only).
- **Ratio:** favorable. Same pattern already taken for stable on other
  SDHCI OF drivers.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: EVIDENCE**

**For backporting:**
- Real, deterministic autoload bug when `MMC_SDHCI_OF_MA35D1=m`.
- One-line, obviously correct, no new API.
- Driver has been in this lineage since v6.12; table was never exported.
- MMC maintainer applied it; SDHCI/Nuvoton were on Cc; no NAK.
- Same change as `mmc: sdhci-of-aspeed: fix module autoloading`, which
  carried `Cc: stable`.
- Matches the stable-rules “device ID” / hardware-enablement exception
  in spirit: publish an ID the driver already matches.
- Applies cleanly; no prerequisites.

**Against:**
- No `Reported-by` / no hardware reproduction (author said so).
- Peripheral SoC, not a core path.
- Not a crash, UAF, or corruption.
- No `Cc: stable` on this specific patch (Ulf took it for *next*, not as
  an urgent fix).
- Author is running a tree-wide alias sweep (quality of *this* hunk is
  still fine).

**Unresolved:**
- Whether linux-stable already discussed this (lore.kernel.org/stable
  blocked).
- How many shipping MA35D1 kernels use `=m` vs `=y` (unverified).

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — standard macro; maintainer
   applied. “Tested” is source-level, not lab hardware.
2. Fixes a real bug that affects users? **PASS** — modular autoload is
   broken; Kconfig allows `=m`.
3. Important issue? **PASS** (as device-ID / hardware-enablement, not as
   a crash). Storage host may never appear on boot.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — only module aliases for an
   existing compatible string.
6. Can apply to the local tree? **PASS** — driver present; hunk is the
   existing table site.

**Step 9.3: EXCEPTION CATEGORIES**
Record: **Device ID / module alias publication for an existing driver**
(same practical class as adding PCI/USB/OF IDs). Not a new driver.

**Step 9.4: DECISION**
This tree has the MA35D1 SDHCI driver and had the missing alias from
introduction until this commit. The patch is a one-line, zero-runtime-
risk fix that makes the already-supported compatible string autoload
when the driver is a module. That is stable-appropriate hardware
enablement, not a feature or refactor.

---

## What the commit solves for stable users

On Nuvoton MA35D1, `sdhci-of-ma35d1` already matches
`nuvoton,ma35d1-sdhci` **if loaded**. Without `MODULE_DEVICE_TABLE`, a
modular kernel never generates the OF alias, so the MMC/SD controller is
silent until someone runs `modprobe`. Backporting restores autoload.
Risk is essentially zero.

---

## Verification
- [Phase 1] Parsed commit `9b3732cce41d1`: no Fixes/Reported-
  by/Cc:stable; SOBs Pengpeng Hou + Ulf Hansson
- [Phase 2] Diff: +1 line `MODULE_DEVICE_TABLE(of, sdhci_ma35_dt_ids)`
  in `sdhci-of-ma35d1.c`
- [Phase 2] `MODULE_DEVICE_TABLE` expansion verified in
  `include/linux/module.h:255-257`
- [Phase 3] `git blame`: table from `addc9ecb9ddb3` (v6.12-rc1), no
  MODULE_DEVICE_TABLE until this commit
- [Phase 3] `git show addc9ecb9ddb3`: original driver had
  `.of_match_table` only
- [Phase 3] `git merge-base --is-ancestor addc9ecb9ddb3 HEAD` and
  `9b3732cce41d1 HEAD`: both true
- [Phase 3] File log: 5 commits; no extra prereqs for this line
- [Phase 3] Precedent `6e540da4c1db7` (aspeed autoload): same one-liner,
  had `Cc: stable`
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1-only; lore msgid
  `20260704124115.2874-1-pengpeng@iscas.ac.cn`; Ulf “Applied for next”
- [Phase 4] WebFetch lore/patch.msgid.link: 403; thread read from mbox
  instead
- [Phase 5] Kconfig: `MMC_SDHCI_OF_MA35D1` is tristate, `depends on
  ARCH_MA35 || COMPILE_TEST`
- [Phase 5] Other `sdhci-of-*.c` already have `MODULE_DEVICE_TABLE`
- [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`; `make
  kernelversion` = `7.3.0-rc4`
- [Phase 6] Current file line 293 already has the macro
- [Phase 8] Failure mode: module not autoloaded; no oops
- UNVERIFIED: linux-stable list discussion (Anubis); how common `=m` is
  on MA35D1 distro kernels

**YES**

 drivers/mmc/host/sdhci-of-ma35d1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/sdhci-of-ma35d1.c b/drivers/mmc/host/sdhci-of-ma35d1.c
index 287026422616c..73f772db04148 100644
--- a/drivers/mmc/host/sdhci-of-ma35d1.c
+++ b/drivers/mmc/host/sdhci-of-ma35d1.c
@@ -291,6 +291,7 @@ static const struct of_device_id sdhci_ma35_dt_ids[] = {
 	{ .compatible = "nuvoton,ma35d1-sdhci" },
 	{}
 };
+MODULE_DEVICE_TABLE(of, sdhci_ma35_dt_ids);
 
 static struct platform_driver sdhci_ma35_driver = {
 	.driver	= {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (23 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] mmc: sdhci-of-ma35d1: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
                   ` (23 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Brian Masney, Abel Vesa, Sasha Levin, abelvesa,
	sboyd, bmasney+clk, jbrunet+clk, Frank.Li, linux-clk, imx,
	linux-arm-kernel, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit cd21fdcbef3fb32136f72075ab668b075423b3f6 ]

The driver has a match table for the of bus wired into its driver
structure, but the table is not exported with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE() entry so module alias information
is generated for automatic module loading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the driver registration structure, and the missing module alias
publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Link: https://patch.msgid.link/20260705001705.70400-1-pengpeng@iscas.ac.cn
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: **[clk/imx]** **[add]** missing `MODULE_DEVICE_TABLE()` so the
i.MX8QXP SCU clock driver’s OF match table is exported as module
aliases.

**Step 1.2 — Tags**
Record:
- `Reviewed-by: Brian Masney <bmasney@redhat.com>`
- `Link:
  https://patch.msgid.link/20260705001705.70400-1-pengpeng@iscas.ac.cn`
- `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
- `Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>` (clk/imx
  maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Acked-by:`, or `Cc:
  stable` (absence of the last two is expected for this review)

**Step 1.3 — Body**
Record: The driver already has `imx8qxp_match[]` wired as
`of_match_table`, but it never called `MODULE_DEVICE_TABLE(of, …)`.
Without that, modpost/`file2alias` does not emit `of:N*T*C…` aliases, so
udev/`modprobe`/initramfs tools cannot autoload `clk-imx-scu` from DT
compatible strings. Failure mode: modular `CONFIG_CLK_IMX8QXP=m` does
not bind on `fsl,scu-clk` / `fsl,imx8qxp-clk` / `fsl,imx8qm-clk` /
`fsl,imx8dxl-clk`. The author presents this as a source-level
correctness fix, not a live hardware repro. No version range is given.

**Step 1.4 — Hidden bug fix?**
Record: Not disguised. It is an explicit completeness fix for module
alias publication. That is a real functional bug for `=m` builds, not
style cleanup.

---

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record: One file, `drivers/clk/imx/clk-imx8qxp.c`, **+1 / -0**. One
insertion after `imx8qxp_match[]`. Surgical single-file change.

**Step 2.2 — Code flow**
Record: **Before:** `imx8qxp_match[]` is only referenced by
`imx8qxp_clk_driver.driver.of_match_table` (bind-time matching if the
module is already loaded). **After:** the same table is also aliased for
modpost (`__mod_device_table__kmod_*__of__imx8qxp_match`), which
produces OF module aliases. No probe, init, or error-path logic changes.

**Step 2.3 — Bug mechanism**
Record: **Hardware/module-autoload omission** (same class as missing
device IDs). The OF table existed; aliases were not published.
`MODULE_DEVICE_TABLE` is the required export so
`scripts/mod/file2alias.c` `do_of_entry()` can emit aliases.

**Step 2.4 — Fix quality**
Record: Obviously correct: same pattern as `clk-imx8mm.c`
(`MODULE_DEVICE_TABLE(of, imx8mm_clk_of_match)`) and the sibling LPCG
driver. Minimal, no API/data-structure change. Regression risk is
essentially none: for `=y` the extra alias symbol is unused at runtime;
for `=m` it only adds `modules.alias` entries.

---

## Phase 3: Git history

**Step 3.1 — Blame**
Record: Match table introduced in `c2cccb6d0b33b` (2018, original
driver). Modular build introduced in `e0d0d4d86c766` (“Support building
i.MX8QXP clock driver as module”, 2020-08-22, first in **v5.9**). That
is when `MODULE_DEVICE_TABLE` became necessary and was omitted. Bug is
long-standing, not recent.

**Step 3.2 — Fixes: tag**
Record: None. The introducing commit is `e0d0d4d86c766`; it is an
ancestor of this HEAD.

**Step 3.3 — File history**
Record: Immediate neighbor `e89485455ac49` (`clk: imx: imx8qxp-lpcg: add
missing MODULE_DEVICE_TABLE()`) is the same author/pattern on the LPCG
sibling. Independent 1-line fix; this patch does not depend on it. Other
recent file history (`aadb7d1f2ca0f` softdep on `scu_pd`) is unrelated.

**Step 3.4 — Author**
Record: Pengpeng Hou submitted a cluster of clk `MODULE_DEVICE_TABLE`
additions (imx8qxp, imx8qxp-lpcg, mediatek mt6735). Not the clk/imx
maintainer. Maintainer Abel Vesa applied it; Brian Masney reviewed.

**Step 3.5 — Dependencies**
Record: None. Needs only `imx8qxp_match[]` and `MODULE_DEVICE_TABLE`
from `<linux/module.h>`, both present. Standalone.

---

## Phase 4: Mailing list / external research

**Step 4.1 — Original discussion**
Record: `b4 dig -c cd21fdcbef3fb` →
https://patch.msgid.link/20260705001705.70400-1-pengpeng@iscas.ac.cn
`b4 dig -a`: single **v1**, no later revisions.
Thread (gnuweeb mirror; lore.kernel.org returned 403): Brian Masney
`Reviewed-by`; Abel Vesa “Applied, thanks!” as `cd21fdcbef3fb`. No NAK,
no stable nomination, no risk flags.

**Step 4.2 — Recipients (`b4 dig -w`)**
Record: Abel Vesa, Peng Fan, Stephen Boyd, Michael Turquette, Frank Li,
Sascha Hauer, Fabio Estevam, linux-clk, imx@lists.linux.dev, linux-arm-
kernel. Correct maintainers and lists.

**Step 4.3 — Bug report**
Record: No `Reported-by` / syzbot / bugzilla. Evidence is the match
table vs missing export. Pull text for clk-imx 7.3 lists “Add missing
MODULE_DEVICE_TABLE() declarations for i.MX8QXP clock drivers.”

**Step 4.4 — Series**
Record: Standalone `[PATCH]`, not `N/M`. Sibling LPCG patch is parallel
and not a prerequisite.

**Step 4.5 — Stable list**
Record: gnuweeb `/stable/?q=imx8qxp+MODULE_DEVICE_TABLE` did not show a
dedicated discussion of this patch (hits were unrelated imx8 noise).
lore.kernel.org/stable returned 403.

---

## Phase 5: Code semantics

**Step 5.1 — Functions**
Record: No function body changed. Data: `imx8qxp_match[]`. Related:
`imx8qxp_clk_driver`, `imx8qxp_clk_init()`, `imx8qxp_clk_probe()`.

**Step 5.2 — Callers**
Record: `imx8qxp_clk_init()` (`module_init`) →
`platform_driver_register(&imx8qxp_clk_driver)`. Probe runs when OF
compatible matches. Autoload is what was broken: without aliases the
module may never load, so probe never runs.

**Step 5.3 — Callees**
Record: Probe calls `imx_clk_scu_init()`, many
`imx_clk_scu`/`imx_clk_scu2`, `of_clk_add_hw_provider()`. Unchanged.

**Step 5.4 — Reachability**
Record: Userspace-reachable only in the sense that missing aliases
prevent the module from being requested. Affects i.MX8QXP/QM/DXL boards
with `CONFIG_CLK_IMX8QXP=m`. DT compatibles: `fsl,scu-clk`,
`fsl,imx8dxl-clk`, `fsl,imx8qxp-clk`, `fsl,imx8qm-clk`.

**Step 5.5 — Similar patterns**
Record: Other imx clk files already had `MODULE_DEVICE_TABLE(of, …)`
(`clk-imx8mm.c`, `clk-imx8mn.c`, `clk-imx8mp.c`, `clk-imx8mq.c`, `clk-
imx8-acm.c`, etc.). This file was the omission.

---

## Phase 6: Local tree

**Step 6.1 — Does the buggy code exist here?**
Record: Local tree is **v7.3-rc4** (`git describe` =
`v7.3-rc4-27-gf0100363d8c37`, `VERSION=7 PATCHLEVEL=3 SUBLEVEL=0
EXTRAVERSION=-rc4`). `CLK_IMX8QXP` is **tristate**. File has
`imx8qxp_match[]`, `module_init`/`module_exit`, and (after this commit)
`MODULE_DEVICE_TABLE`. The omission existed from v5.9 until this 7.3-era
commit. `git merge-base --is-ancestor cd21fdcbef3fb HEAD` is true — the
fix is already in this checkout; the underlying driver and match table
are present.

**Step 6.2 — Backport difficulty**
Record: Clean apply: one line after the sentinel of `imx8qxp_match[]`.
No refactor of that region.

**Step 6.3 — Related fixes already here?**
Record: Sibling LPCG table already has `MODULE_DEVICE_TABLE`. No earlier
equivalent for `clk-imx8qxp.c`. No competing fix.

---

## Phase 7: Subsystem / maintainer

**Step 7.1**
Record: **clk / i.MX SoC clocks**. **IMPORTANT** for i.MX8QXP/QM/DXL
(clock provider for the SoC), not core mm/vfs. Peripheral relative to
the whole kernel, critical on those boards.

**Step 7.2**
Record: Actively maintained (`clk-imx-7.3` pull by Abel Vesa). The
missing alias is old; the rest of the file is mature.

---

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: **Platform/config-specific**: NXP i.MX8QXP/QM/DXL with
`CONFIG_CLK_IMX8QXP=m`. Built-in (`=y`) is unchanged.

**Step 8.2 — Trigger**
Record: Modular kernel + DT node with those compatibles + autoload via
aliases (udev, `request_module`, dracut/mkinitramfs). Common for distro
`=m` configs. Unprivileged users do not trigger it; boot/device-probe
does.

**Step 8.3 — Failure mode**
Record: Module never autoloads → SCU clocks never register → consumers
fail to probe (UART, net, display, etc.). **MEDIUM–HIGH** on affected
boards; not a panic/UAF. For `=y`, **no effect**.

**Step 8.4 — Risk vs benefit**
Record: **Benefit:** restores documented autoload for a supported
tristate clock driver. **Risk:** very low (1 line, no runtime path).
Ratio is strongly favorable.

---

## Phase 9: Synthesis

**Step 9.1 — Evidence**

FOR:
- Real bug: OF match table not exported; aliases missing for a
  `tristate` driver with `module_init`.
- Same pattern already used throughout `drivers/clk/imx/`.
- 1-line, obviously correct; maintainer applied; Reviewed-by Brian
  Masney.
- Zero runtime change when built-in.
- Analogous to device-ID additions (exception category: make existing
  hardware/driver work).
- Bug present since v5.9 modular support (`e0d0d4d86c766`).
- Applies cleanly to this tree’s `imx8qxp_match[]`.

AGAINST:
- No crash/syzbot/user report; source-level only.
- Impact limited to `CLK_IMX8QXP=m` (many images use `=y`).
- Not a security/UAF/deadlock class bug.

UNRESOLVED:
- Could not fetch lore.kernel.org (403); used b4 + gnuweeb/LKML mirrors
  instead.
- No dedicated stable-list thread found.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — 1-line standard macro;
   reviewed and applied by clk/imx.
2. Real bug affecting users? **PASS** — `=m` autoload/initramfs alias
   generation is broken without it.
3. Important? **PASS** — SoC clock provider failing to load breaks the
   platform; severity is functional, not panic, but that is enough for
   this class of fix.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features/APIs? **PASS** — publishes existing table.
6. Can apply to this tree? **PASS** — match table, `linux/module.h`, and
   modular Kconfig are all here.

**Step 9.3 — Exception category**
Record: Closest match is **device-ID / module-alias enablement** for an
existing driver (not a new driver).

**Step 9.4 — Decision**
This tree is mainline **7.3-rc4**. The driver, OF table, and tristate
module support are here; the fix is a one-line alias export with no
runtime risk. That meets stable criteria for this checkout.

---

### Problem and why it matters
`clk-imx8qxp.c` can be `=m` since v5.9 and already matches DT via
`imx8qxp_match[]`, but never published that table with
`MODULE_DEVICE_TABLE()`. Users with modular i.MX8QXP/QM/DXL kernels do
not get `of:` aliases, so the clock module may not autoload and
consumers never get clocks.

### Stable rules
Small, obviously correct, no new API, real autoload bug, applies to this
tree.

### Risk vs benefit
Benefit is correct module loading on a supported config; risk is
negligible.

### Concerns
No hardware repro and no `Fixes:` tag; neither blocks this pattern.
Sibling LPCG patch is independent.

---

Verification:
- [Phase 1] Parsed tags: Reviewed-by Brian Masney; Link
  patch.msgid.link/20260705001705.70400-1-pengpeng@iscas.ac.cn; SOBs Hou
  and Abel Vesa; no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: +1 line `MODULE_DEVICE_TABLE(of, imx8qxp_match)` in
  `drivers/clk/imx/clk-imx8qxp.c`; no function body change
- [Phase 3] `git blame`: table from `c2cccb6d0b33b` (2018); modular
  support `e0d0d4d86c766` (v5.9) introduced the need for aliases
- [Phase 3] `git merge-base --is-ancestor e0d0d4d86c766 HEAD`: yes; `git
  merge-base --is-ancestor cd21fdcbef3fb HEAD`: yes
- [Phase 3] Neighbor `e89485455ac49` is independent LPCG
  MODULE_DEVICE_TABLE add
- [Phase 4] `b4 dig -c cd21fdcbef3fb`: matched v1 at that msgid; `-a`
  only v1; `-w` listed clk/imx and linux-clk recipients
- [Phase 4] gnuweeb thread: Masney Reviewed-by; Vesa Applied as
  cd21fdcbef3fb; no NAK
- [Phase 4] lore.kernel.org fetch: 403; used mirrors
- [Phase 5] `CLK_IMX8QXP` is tristate in `drivers/clk/imx/Kconfig`;
  built as `clk-imx-scu` via Makefile; `module_init(imx8qxp_clk_init)`
  registers the platform driver
- [Phase 5] `scripts/mod/file2alias.c` `do_of_entry()` emits
  `of:N*T*C<compatible>` from MODULE_DEVICE_TABLE
- [Phase 5] Sibling `clk-imx8mm.c` already uses the same macro
- [Phase 6] `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion`: 7.3.0-rc4; file currently contains the added line
- [Phase 6] Apply difficulty: one line after existing `imx8qxp_match[]`
- [Phase 8] Failure mode: modular clock provider not autoloaded;
  severity MEDIUM–HIGH on those SoCs, none if `=y`
- UNVERIFIED: live udev/initramfs failure on hardware (author did not
  claim a runtime repro); stable-list discussion beyond the gnuweeb
  search

**YES**

 drivers/clk/imx/clk-imx8qxp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 3ae162625bb1a..15b08fc02f920 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -337,6 +337,7 @@ static const struct of_device_id imx8qxp_match[] = {
 	{ .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx8qxp_match);
 
 static struct platform_driver imx8qxp_clk_driver = {
 	.driver = {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (24 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp: " Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18] memory: stm32_omm: initialize ret in stm32_omm_set_amcr Sasha Levin
                   ` (22 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Ahmed Naseef, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Ahmed Naseef <naseefkm@gmail.com>

[ Upstream commit d16447d7470502e998d82e806ca7ed49d1baa853 ]

Some EcoNet based routers ship an on-flash EEPROM whose chip-id is
0x7592 instead of the expected 0x7603. The device probes as PCI
14c3:7603 and the hardware MT_HW_CHIPID register reports 0x7603,
independent of the EEPROM value.

This is seen across multiple EcoNet EN751221 and EN7528 based devices
(for example the Genexis Platinum 4410).

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The evaluation target is **pending-6.6 (6.6.157)**. The mt7603 driver is
present; the 0x7592 EEPROM ID is not. This is a one-line ID addition to
an existing driver, which is a standard stable exception.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [wifi: mt76: mt7603] [add] [accept EEPROM chip ID 0x7592 in
mt7603_check_eeprom]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Signed-off-by: Ahmed Naseef \<naseefkm@gmail.com\> (author)
- Link:
  https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- Signed-off-by: Felix Fietkau \<nbd@nbd.name\> (mt76 maintainer,
  applied the patch)
- No Fixes: tag (expected for this review queue)
- No Cc: stable (expected)
- No Reported-by / Tested-by / Reviewed-by / Acked-by
- No syzbot / KASAN tags
- Sasha Levin SOB not present on this commit

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: EcoNet routers store chip-id 0x7592 in on-flash EEPROM instead of
  0x7603/0x7628/0x7600.
- Hardware identity is still MT7603: PCI 14c3:7603, and MT_HW_CHIPID
  reads 0x7603.
- Symptom: driver treats a valid factory EEPROM as invalid.
- Devices: EcoNet EN751221 and EN7528, e.g. Genexis Platinum 4410.
- No stack trace; this is hardware recognition, not a crash fix.
- Root cause: mt7603_check_eeprom() whitelist is incomplete.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. It is an explicit EEPROM ID addition.
When the ID is rejected and OTP exists, mt7603_eeprom_init() memcpy()s
OTP over the flash EEPROM, so MAC/calibration from flash are discarded.
That is a real functional bug for those boards, not a new API.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
- +1 line, 0 removed
- Function: mt7603_check_eeprom()
- Scope: single-file, one-line surgical change

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: switch accepts 0x7628, 0x7603, 0x7600; anything else returns
  -EINVAL.
- After: also accepts 0x7592.
- Path: probe → mt7603_register_device() → mt7603_init_hardware() →
  mt7603_eeprom_init().
- If check succeeds and OTP exists: apply cal-free OTP overlay onto
  flash EEPROM.
- If check fails and OTP exists: overwrite entire flash EEPROM with OTP
  (MAC, TX power, xtal data from flash lost).
- Probe does not fail on unknown EEPROM ID.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: [Hardware ID / quirk] [Whitelist used to decide whether on-flash
EEPROM is trusted. Missing 0x7592 caused valid EcoNet EEPROMs to be
discarded in favor of OTP.]

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: same pattern as the existing 0x7600 case.
- Minimal: one case label.
- Regression risk: very low. A random EEPROM whose first LE16 is 0x7592
  would be trusted; that is the same risk as the existing IDs.
- No API or data-structure change.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- mt7603_check_eeprom() introduced in c8846e1015022 ("mt76: add driver
  for MT7603E and MT7628/7688"), 2018, first released in v5.1-rc1.
- 0x7600 added by bf4a938ab2cf8 ("mt76: mt7603: add additional EEPROM
  chip ID"), 2020, same one-line pattern for TP-Link Archer C50 v4.
- Both commits are ancestors of pending-6.6.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. Buggy whitelist dates to the original driver
(v5.1), which is in this tree.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Related: bf4a938ab2cf8 already in 6.6 (precedent).
- Candidate d16447d747050 is not an ancestor of pending-6.6.
- Standalone; not patch X/Y.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record:
- Author Ahmed Naseef has no other mt76 commits on pending-6.6.
- Applied by Felix Fietkau, listed maintainer of MEDIATEK MT76.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record:
- No new helpers or struct fields.
- pending-6.6 vs patch parent only differs in SPDX and later
  chainmask/return of mt76_eeprom_override(); the switch hunk is
  identical.
- Can apply standalone with a clean hunk.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- b4 dig -c d16447d747050 →
  https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- b4 dig -a: single v1 series, no v2/v3.
- Thread mbox is the patch only; no replies, no NAK, no Cc: stable in
  review.
- Included in wireless-next-2026-08-06 pull (Johannes Berg).
- Syzbot CI: build/boot passed; fuzz skipped.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record:
- b4 dig -w: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
  Sean Wang, linux-wireless, linux-mediatek, linux-kernel.
- Applied by Felix Fietkau (maintainer SOB). No separate Reviewed-by.

Step 4.3: SEARCH FOR THE BUG REPORT
Record:
- No bugzilla/syzbot link.
- Commit cites multiple EcoNet EN751221/EN7528 devices, example Genexis
  Platinum 4410.
- OpenWrt mt76 tree already contains case 0x7592.
- No independent public crash report found (UNVERIFIED beyond the commit
  text and OpenWrt tree).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone one-patch series. Same pattern as bf4a938ab2cf8.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned 403. No stable discussion found
via b4/mbox. UNVERIFIED whether anyone requested/rejected this for
stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: mt7603_check_eeprom() only.

Step 5.2: TRACE CALLERS
Record:
- Only caller: mt7603_eeprom_init() (same file).
- mt7603_eeprom_init() ← mt7603_init_hardware() ←
  mt7603_register_device()
- mt7603_register_device() ← mt76pci_probe() (PCI 14c3:7603) and
  mt76_wmac_probe() (mediatek,mt7628-wmac).
- Probe/init path, not hot path or IRQ.

Step 5.3: TRACE CALLEES
Record: get_unaligned_le16() on eeprom.data[0]. No alloc, lock, or I/O
in the changed function.

Step 5.4: FOLLOW THE CALL CHAIN
Record:
- Reachable when an MT7603 PCI device or MT7628 WMAC probes with
  CONFIG_MT7603E.
- Not a syscall-triggered memory bug; firmware/EEPROM contents decide
  the branch.
- Unprivileged users cannot trigger it except by plugging/using the
  device.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record:
- Sibling drivers use the same EEPROM-ID switch (mt7615, mt76x0,
  mt76x2).
- This tree already backported other mt76 ID adds, e.g. efd75512e38ac
  (mt76x2u TP-Link USB ID).

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- Tree under evaluation: pending-6.6, 6.6.157 (git describe
  p-6.6-3-g04810563abb71).
- Yes. pending-6.6 eeprom.c switch has 0x7628/0x7603/0x7600 only.
- git merge-base --is-ancestor d16447d747050 pending-6.6 → not present.
- Bug present since v5.1 driver introduction.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. Switch context matches. Later chainmask/license
diffs are outside the hunk.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: 0x7600 ID is present. 0x7592 is not. No alternate fix.

Note: EcoNet SoC support landed in 6.16 (arch/mips/econet), not in 6.6.
That lowers vanilla-6.6 user count; it does not remove the driver or the
ID check. PCI 14c3:7603 still exists in this tree.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [drivers/net/wireless/mediatek/mt76/mt7603] [IMPORTANT for
MT7603/MT7628 users; PERIPHERAL relative to core kernel]

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver since v5.1. 6.6 still receives mt76 fixes.
Maintainer is Felix Fietkau.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific / config-specific (CONFIG_MT7603E). Documented
users are EcoNet EN751221/EN7528 routers with MT7603 PCI WiFi. Vanilla
6.6 cannot boot EcoNet SoCs; downstream 6.6 kernels and any other board
with this EEPROM still benefit.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: probe of MT7603 when flash EEPROM starts with 0x7592 and OTP
  is present.
- Every boot on those devices, not a race.
- Not exploitable by unprivileged software alone.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: [Wrong EEPROM source: factory MAC/calibration replaced by OTP]
[Severity: MEDIUM for those devices — broken/degraded WiFi or wrong MAC,
not oops/corruption]

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: medium for affected hardware (WiFi uses intended EEPROM);
  lower on vanilla 6.6 because EcoNet platform is later, but this is the
  usual device-ID case.
- Risk: very low (one case label, no locking/API).
- Ratio: favorable. Device-ID additions are accepted in stable for this
  reason.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- One-line EEPROM/chip ID addition to an existing driver (stable
  exception).
- Same pattern as 0x7600, already in 6.6.
- Real boards named; hardware already binds as PCI 14c3:7603.
- Without it, valid flash EEPROM is discarded for OTP (MAC/cal).
- Maintainer applied it; applies cleanly here; no new API.
- This tree already contains similar mt76 ID backports.

AGAINST:
- Not a crash/security/deadlock.
- No Tested-by/Reviewed-by; mailing list had no discussion.
- EcoNet platform is not in 6.6, so vanilla 6.6 user count is small.
- No Fixes:/Cc: stable (expected, not a negative).

UNRESOLVED:
- Could not search lore.kernel.org/stable (403).
- No independent public repro beyond the commit and OpenWrt mt76 tree.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — one-line whitelist, maintainer-
   applied, syzbot CI build/boot passed.
2. Fixes a real bug that affects users? PASS — those boards trust OTP
   instead of factory EEPROM.
3. Important issue? PASS under the device-ID/quirk exception (functional
   WiFi/MAC on real hardware), even though not a panic.
4. Small and contained? PASS — +1 line, one file.
5. No new features or APIs? PASS — existing driver, additional ID only.
6. Can apply to the local tree? PASS — hunk matches pending-6.6.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Device ID addition to an existing driver (EEPROM chip ID,
analogous to PCI/USB ID). Also a hardware quirk for boards whose EEPROM
ID does not match MT_HW_CHIPID.

Step 9.4: MAKE YOUR DECISION
This belongs in 6.6.y. The driver and the incomplete whitelist are in
this tree; the fix is the standard one-line ID addition stable already
takes for mt76. EcoNet SoC support arriving later reduces vanilla-6.6
exposure but does not make the patch a new feature or a dependency-heavy
backport.

What it solves for stable users: MT7603 devices whose flash EEPROM ID is
0x7592 keep factory MAC and calibration instead of having them replaced
by OTP on probe.

Risk vs benefit: essentially no regression risk; benefit is enabling
correct EEPROM use on existing hardware.

Verification:
- [Phase 1] Tags: author SOB, Felix Fietkau SOB, msgid link; no Fixes/Cc
  stable/Reported-by
- [Phase 2] Diff: +1 `case 0x7592:` in mt7603_check_eeprom()
- [Phase 2] Confirmed eeprom_init: fail → memcpy OTP over flash; success
  → cal-free overlay only
- [Phase 3] blame: function from c8846e1015022 (v5.1); 0x7600 from
  bf4a938ab2cf8; both in pending-6.6
- [Phase 3] git merge-base --is-ancestor d16447d747050 pending-6.6 → not
  in 6.6
- [Phase 3] git diff pending-6.6 vs parent: switch identical; only
  SPDX/chainmask elsewhere
- [Phase 4] b4 dig -c d16447d747050: lore msgid
  20260719082530.3879831-1-naseefkm@gmail.com
- [Phase 4] b4 dig -a: v1 only; mbox has no replies
- [Phase 4] b4 dig -w: mt76 maintainers + linux-wireless CC'd; Felix
  applied
- [Phase 4] wireless-next-2026-08-06 pull lists this commit
- [Phase 5] callers: mt7603_eeprom_init → init_hardware →
  register_device → pci/soc probe
- [Phase 6] pending-6.6 Makefile 6.6.157; switch lacks 0x7592; would
  apply cleanly
- [Phase 6] EcoNet arch not in 6.6 (added ~6.16) — lowers vanilla user
  count, code still present
- [Phase 7] MAINTAINERS: Felix Fietkau maintains mt76
- [Phase 8] Failure: OTP replaces flash EEPROM (MAC/cal); not oops
- UNVERIFIED: stable@ lore search (HTTP 403); no independent field crash
  report

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
index 88382b537a33b..06f61988655e5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
@@ -142,6 +142,7 @@ static int mt7603_check_eeprom(struct mt76_dev *dev)
 	case 0x7628:
 	case 0x7603:
 	case 0x7600:
+	case 0x7592:
 		return 0;
 	default:
 		return -EINVAL;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] memory: stm32_omm: initialize ret in stm32_omm_set_amcr
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (25 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/arm-smmu-qcom: Add SM8450 MDSS compatible Sasha Levin
                   ` (21 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Ruoyu Wang, Patrice Chotard, Krzysztof Kozlowski, Sasha Levin,
	mcoquelin.stm32, alexandre.torgue, linux-kernel, linux-stm32,
	linux-arm-kernel

From: Ruoyu Wang <ruoyuw560@gmail.com>

[ Upstream commit 1527acf2295cf2d6e11e3e9b121d63709667e6e7 ]

stm32_omm_set_amcr() returns ret after checking whether the AMCR value
matches the device tree description. On the normal matching path ret is
not otherwise assigned, so initialize it to 0 before the checks.

Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Link: https://patch.msgid.link/20260617182202.961843-1-ruoyuw560@gmail.com
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.53**. `stm32_omm_set_amcr()` in that tree still
returns uninitialized `ret` on the AMCR-match path, and the one-line
init is a real probe/resume correctness fix.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[memory / stm32_omm] [initialize] [set ret=0 in
stm32_omm_set_amcr so the AMCR-match success path does not return an
uninitialized stack value]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>` (driver
  maintainer; MAINTAINERS lists him for ST STM32 OCTO MEMORY MANAGER)
- `Link:
  https://patch.msgid.link/20260617182202.961843-1-ruoyuw560@gmail.com`
- `Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>` (author)
- `Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>` (memory-
  controller maintainer; applied the patch)
- No `Fixes:` tag (expected)
- No `Cc: stable` (expected)
- No `Reported-by:` / `Tested-by:` / syzbot / kernel test robot tags
- Pipeline-only tags (`[Upstream commit ...]`, `Signed-off-by: Sasha
  Levin`) ignored

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- Bug: `stm32_omm_set_amcr()` returns `ret` after the AMCR vs DT check.
  On the matching (success) path, `ret` is not assigned `-EINVAL` and
  may never have been assigned at all.
- Symptom: the function can return a leftover stack value as an errno to
  probe/configure/resume. Callers treat any non-zero as failure, so
  garbage can fail device bring-up or resume; a lucky 0 would hide the
  mismatch path’s intent.
- Version info: none in the message.
- Root cause (author): success path does not initialize `ret` before
  `return ret`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. This is an explicit uninitialized-variable fix
(`int ret` → `int ret = 0`). Same class as KMSAN/compiler “used
uninitialized” fixes even without a sanitizer tag.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/memory/stm32_omm.c` (`1` insertion, `1` deletion)
- Function: `stm32_omm_set_amcr`
- Scope: single-file, one-line surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Before, `int ret, idx;` then the loop may assign `ret` from
`of_address_to_resource()`, mismatch sets `ret = -EINVAL`, and the
function always `return ret`. After, `ret` starts at `0`, so AMCR match
returns success unless an earlier path already returned an error.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: Category **uninitialized data / logic correctness**. Mechanism:
`ret` is assigned only by a successful `of_address_to_resource()`
(inside a loop that can `continue`) or by `ret = -EINVAL` on AMCR
mismatch. The success `return ret` is therefore undefined if the loop
never assigned `ret`. Fix: default `ret = 0`.

Verified from the pre-fix function (v6.18.53 and the original driver):

```50:50:drivers/memory/stm32_omm.c
        int ret = 0, idx;
```

(v6.18.53 still has `int ret, idx;` — confirmed via `git show
v6.18.53:drivers/memory/stm32_omm.c`.)

Mismatch path:

```116:121:drivers/memory/stm32_omm.c
        if (amcr != read_amcr) {
                dev_err(dev, "AMCR value not coherent with DT memory-map
areas\n");
                ret = -EINVAL;
        }

        return ret;
```

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct. Error returns in the loop are unchanged
(`return ret` / `return -EFAULT`). AMCR mismatch still returns
`-EINVAL`. Risk is negligible: initializing an errno to 0 cannot
deadlock, cannot change a public API, and matches the intended success
code.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: `int ret, idx;` and the `return ret` were introduced in
`8181d061dcff1` (“memory: Add STM32 Octo Memory Manager driver”,
2025-04-28 / committed 2025-05-07). Present from the first version of
the driver. Driver first appears in **v6.16**; still present in v6.17
and v6.18.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. The introducing commit is `8181d061dcff1`,
which **is** an ancestor of v6.18 (`git merge-base --is-ancestor
8181d061dcff1 v6.18` succeeded).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record (path-limited `git log --oneline -- drivers/memory/stm32_omm.c`):
driver add, spelling, several probe/error-handling fixes,
`syscon_regmap_lookup_by_phandle_args`, req2ack test fix. Intermediate
commit `6d8b18ae647bb` changed syscon lookup but left `int ret, idx;`
and `return ret` in place. This init patch is standalone, not “patch
X/Y”.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Ruoyu Wang has only this commit under `drivers/memory/`. The
driver maintainer (Patrice Chotard) reviewed it. Memory-controller
maintainer (Krzysztof Kozlowski) applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None. The hunk only changes a local `int ret` declaration. No
new helpers, types, or APIs. Can apply standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 1527acf2295cf2d6e11e3e9b121d63709667e6e7` →
  https://patch.msgid.link/20260617182202.961843-1-ruoyuw560@gmail.com
- `b4 dig -a`: single revision **v1 only**; committed version is that v1
- Thread: author submission; Patrice Chotard `Reviewed-by`; Krzysztof
  “Applied, thanks!” (mem-ctrl commit
  `1527acf2295cf2d6e11e3e9b121d63709667e6e7`)
- No NAK, no risk flags, no reviewer request for `Cc: stable`
- lore.kernel.org WebFetch returned 403; discussion recovered via `b4
  dig -m` and openwall/lkml mirrors

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc included Patrice Chotard (driver
maintainer), Krzysztof Kozlowski (memory controllers), Maxime Coquelin,
Alexandre Torgue, linux-kernel, linux-stm32, linux-arm-kernel.
Appropriate maintainers were on the patch and it was reviewed/applied.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by`, no bugzilla/syzbot link. No verified kernel-
test-robot mail in the thread. The author describes the uninit return
from code inspection.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone `[PATCH]`, not a series. No sibling patches required.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** for lore.kernel.org/stable (HTTP 403). Web search
and the saved mbox show no stable-list discussion of this subject.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `stm32_omm_set_amcr` only. (semcode MCP not available; used hunk
headers + `rg`.)

**Step 5.2: TRACE CALLERS**
Record (verified with `rg` on `drivers/memory/stm32_omm.c`):
1. `stm32_omm_configure()` → `stm32_omm_set_amcr(dev, true)` then
   returns that `ret` (probe, full firewall access)
2. `stm32_omm_probe()` → `stm32_omm_set_amcr(dev, false)` when OMM
   access is not granted; `if (ret) return ret`
3. `stm32_omm_resume()` → `stm32_omm_set_amcr(dev, true)`; `if (ret)
   return ret`

All three are driver probe / system-resume paths, not an obscure debug
hook.

**Step 5.3: TRACE CALLEES**
Record: `of_property_match_string`, `of_parse_phandle`,
`of_address_to_resource`, `syscon_regmap_lookup_by_phandle_args`,
`regmap_update_bits` / `regmap_read`. Side effects are DT parse + AMCR
syscon R/W.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Platform probe of `compatible = "st,stm32mp25-omm"` (SoC node in
`arch/arm64/boot/dts/st/stm32mp251.dtsi`, enabled on
`stm32mp257f-ev1.dts`). Reachable on STM32MP25 boot and suspend/resume.
Not a syscall fuzzer path; hardware/DT driven.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: No second copy of this AMCR helper. Binding example uses both
`ospi1` and `ospi2` regions; in-tree board `stm32mp257f-ev1.dts` only
sets `memory-region-names = "ospi1"`. Binding **does not require**
`memory-region` (required list is
compatible/reg/clocks/resets/`st,syscfg-amcr`/ranges). Omitting `memory-
region-names` is a valid DT; the loop then never assigns `ret`.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- `git describe HEAD` / `make kernelversion`: **v6.18.53** (branch
  `autosel`)
- `git show v6.18.53:drivers/memory/stm32_omm.c` has `int ret, idx;` and
  `return ret` after the AMCR compare
- Driver exists in v6.18 (`git cat-file -e
  v6.18:drivers/memory/stm32_omm.c`)
- Bug introduced with the driver in v6.16 (`8181d061dcff1`)

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. The one-line `int ret, idx;` → `int ret = 0, idx;`
is present exactly once in v6.18.53. Surrounding function matches the
upstream hunk. No rework needed.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: `git log --oneline --grep='stm32_omm' -- drivers/memory/` on
this history shows other stm32_omm error-handling fixes, but none
initialize `ret` in `stm32_omm_set_amcr` in v6.18.53. No alternate fix
for this uninit.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/memory/` STM32 Octo Memory Manager (OSPI mux / 256MB
map split on STM32MP25). Criticality: **PERIPHERAL** (SoC-specific), but
it sits under flash/OSPI bring-up for that platform, so probe/resume
failure is user-visible there.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Modest, mature-enough driver (added v6.16, a handful of follow-
up fixes). Not a staging driver. Maintainer-reviewed.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Config-specific / platform-specific: `CONFIG_STM32_OMM` on
STM32MP25 (`st,stm32mp25-omm`). Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record:
- Always runs during OMM probe (and again on system resume if
  `restore_omm`).
- Uninitialized `return ret` is **guaranteed** if the memory-region loop
  never assigns `ret` (optional DT property missing or names do not
  match `ospi1`/`ospi2`) **and** AMCR equals computed `amcr` (0 when no
  ospi2 region).
- On the in-tree ev1 board, `ospi1` is present, so
  `of_address_to_resource` typically sets `ret = 0` before the AMCR
  check; the uninit is then a maybe-uninitialized / custom-DT / failed-
  phandle path. Compilers still cannot prove assignment because of the
  `continue`s.
- Not an unprivileged syscall trigger.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Returning uninitialized `int` as errno. Callers abort probe or
resume on non-zero. Failure mode: OSPI/OMM device fails to probe or
fails to resume (flash/memory-map unavailable). Severity **MEDIUM**
(wrong control-plane result / possible resume failure; not a documented
oops, but C undefined behavior). Garbage zero would incorrectly look
like success on a path that never validated regions.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- Benefit: prevents UB and spurious probe/resume failures on STM32MP25
  OMM; makes the success path well-defined. Medium benefit for that
  platform, low global blast radius.
- Risk: **very low** (one initializer, no locking/API/data-structure
  change).
- Ratio: strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real uninitialized return in a function whose callers treat `ret` as
  errno
- Reachable on probe and system resume
- DT binding leaves `memory-region` optional, so the loop is allowed to
  assign nothing
- 1-line, obviously correct, reviewed by the driver maintainer, applied
  by the subsystem maintainer
- Driver and buggy code exist in this 6.18.53 tree since the driver
  landed in v6.16
- Clean apply; no prerequisites
- Matches the uninitialized-data class that stable routinely takes

AGAINST:
- STM32MP25-only (narrow user set)
- No crash log, syzbot, or user `Reported-by`
- On the one in-tree board with `memory-region-names = "ospi1"`, `ret`
  is often already 0 from `of_address_to_resource`
- Not CORE mm/net/fs

UNRESOLVED:
- Could not query lore.kernel.org/stable (403)
- No confirmed compiler-warning/KMSAN report in the thread (web-search
  snippets that mentioned kernel test robot were not backed by the
  actual mails)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one initializer; maintainer
   Reviewed-by; applied upstream
2. Fixes a real bug that affects users? **PASS** — uninitialized errno
   on OMM probe/resume
3. Important issue? **PASS** at MEDIUM — probe/resume malfunction and
   UB, not a documented panic; still a user-visible device failure mode
4. Small and contained? **PASS** — 1 line, 1 function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — v6.18.53 has the uninit
   declaration unchanged

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/docs patch. Closest extra: it also
silences a typical `-Wmaybe-uninitialized` shape, but the decision is on
the runtime uninit return, not on the build-fix exception.

**Step 9.4: MAKE YOUR DECISION**
Backport. The local 6.18.53 tree contains the driver and the bug; the
fix is a one-line initialization of a returned errno with essentially no
regression risk.

What this does for 6.18.y users: STM32MP25 Octo Memory Manager probe and
resume no longer return a stack-garbage error code when AMCR matches DT
and `ret` was never written. That is a real, contained correctness fix.

Risk vs benefit: benefit is defined success (`0`) vs undefined errno;
risk is a single `= 0`.

### Verification
- [Phase 1] Parsed tags: Reviewed-by Patrice Chotard, Link msgid, SOBs
  Wang + Kozlowski; no Fixes/Cc-stable/Reported-by
- [Phase 2] Diff: `int ret, idx` → `int ret = 0, idx` in
  `stm32_omm_set_amcr` only
- [Phase 2] Pre-fix function: loop may skip all `ret =
  of_address_to_resource` stores; mismatch sets `-EINVAL`; success falls
  through to `return ret`
- [Phase 3] `git blame` on parent: uninit from `8181d061dcff1` (driver
  add, 2025)
- [Phase 3] Driver in v6.16+; `git merge-base --is-ancestor
  8181d061dcff1 v6.18` true
- [Phase 3] No series/prereqs; later `6d8b18ae647bb` did not fix `ret`
- [Phase 4] `b4 dig -c 1527acf2295cf2d6e11e3e9b121d63709667e6e7`: lore
  msgid 20260617182202.961843-1
- [Phase 4] `b4 dig -a`: v1 only
- [Phase 4] `b4 dig -w`: Chotard, Kozlowski, STM32/ARM lists CC’d
- [Phase 4] mbox: Reviewed-by Chotard; Applied by Kozlowski; no NAK
- [Phase 4] lore.kernel.org WebFetch 403; used openwall + mbox instead
- [Phase 5] Callers verified: `stm32_omm_configure`, `stm32_omm_probe`,
  `stm32_omm_resume`
- [Phase 5] Binding `st,stm32mp25-omm.yaml`: `memory-region` not in
  `required:`
- [Phase 5] Board DT `stm32mp257f-ev1.dts` has only `ospi1` memory-
  region
- [Phase 6] `git describe HEAD` / Makefile: v6.18.53; `git show
  v6.18.53:drivers/memory/stm32_omm.c` still has `int ret, idx;`
- [Phase 6] Python check: old pattern present once in v6.18.53;
  initialized form absent
- [Phase 7] MAINTAINERS: Patrice Chotard owns
  `drivers/memory/stm32_omm.c`
- [Phase 8] Failure mode: garbage errno → probe/resume fail on STM32MP25
  OMM
- UNVERIFIED: stable@ mailing-list thread (lore 403); no verified
  kernel-test-robot report

**YES**

 drivers/memory/stm32_omm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/memory/stm32_omm.c b/drivers/memory/stm32_omm.c
index 5d06623f3f689..2a1af229d2444 100644
--- a/drivers/memory/stm32_omm.c
+++ b/drivers/memory/stm32_omm.c
@@ -47,7 +47,7 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
 	struct device_node *node;
 	struct resource res, res1;
 	unsigned int syscon_args[2];
-	int ret, idx;
+	int ret = 0, idx;
 	unsigned int i, amcr, read_amcr;
 
 	for (i = 0; i < omm->nb_child; i++) {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] iommu/arm-smmu-qcom: Add SM8450 MDSS compatible
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (26 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18] memory: stm32_omm: initialize ret in stm32_omm_set_amcr Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
                   ` (20 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Esteban Urrutia, Konrad Dybcio, Will Deacon, Sasha Levin,
	robin.clark, joro, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel

From: Esteban Urrutia <esteuwu@proton.me>

[ Upstream commit d149c8b2c0146a01f1be326ddb1e182b55aee638 ]

Add the compatible for the MDSS client on the Snapdragon 8 Gen 1 so it can
be properly configured by the IOMMU driver.

Otherwise, there is an unhandled context fault, because the framebuffer is
already configured in UEFI.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Esteban Urrutia <esteuwu@proton.me>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: `[iommu/arm-smmu-qcom] [Add] SM8450 MDSS compatible so the
Qualcomm SMMU driver can configure that display client`

**Step 1.2: Tags**
Record:
- `Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>`
  (Qualcomm SoC/display maintainer)
- `Signed-off-by: Esteban Urrutia <esteuwu@proton.me>` (author)
- `Signed-off-by: Will Deacon <will@kernel.org>` (IOMMU/arm-smmu
  maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Link:`, or `Cc:
  stable@vger.kernel.org` (absence is expected for this review)

**Step 1.3: Body**
Record:
- Bug: SM8450 MDSS is missing from `qcom_smmu_client_of_match`, so it
  does not get the identity-domain workaround.
- Symptom: unhandled ARM SMMU context fault because UEFI already
  programmed the framebuffer with physical addresses.
- Root cause: without a match, `qcom_smmu_def_domain_type()` returns 0
  and the IOMMU uses a translated DMA domain instead of identity
  mapping.
- Version info: none in the message. SM8450 display support has been in
  this tree since v6.3 (`drm/msm: mdss add support for SM8450`).

**Step 1.4: Hidden bug fix?**
Record: Not hidden. The subject says “Add”, but the body describes a
real hardware workaround (IOMMU identity domain for a bootloader-
configured display), not a new feature.

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c` (+1 / −0)
- Function: static table `qcom_smmu_client_of_match[]`
- Scope: single-file, one-line compatible addition

**Step 2.2: Code flow**
Record: Before, `of_match_device(qcom_smmu_client_of_match, dev)` misses
`qcom,sm8450-mdss`, so `qcom_smmu_def_domain_type()` returns 0. After,
that compatible matches and the function returns
`IOMMU_DOMAIN_IDENTITY`. Path: IOMMU default-domain selection at MDSS
probe, not an error path.

**Step 2.3: Bug mechanism**
Record: Hardware workaround / device-ID (compatible) addition. MDSS
streams keep using the UEFI framebuffer mapping. Without identity domain
those accesses translation-fault (`arm-smmu: Unhandled context fault`).
Same pattern as SM6115, SDM670, X1E80100, QCM2290, SC8280XP.

**Step 2.4: Fix quality**
Record: Obviously correct and minimal. Only devices with
`qcom,sm8450-mdss` change behavior. Regression risk is very low;
neighboring SoCs already use this table the same way. ACTLR table
already listed `qcom,sm8450-mdss`; the client table was the omission.

## Phase 3: Git history

**Step 3.1: Blame**
Record:
- Table introduced in `0e764a01015df` (2020, “Allow client devices to
  select direct mapping”).
- This line added by `d149c8b2c0146` (2026-07-22).
- SM8450 MDSS driver: `80056d9ac47ab` (2023-01-12, v6.3-rc1).
- SM8450 DT: `a6dd1206e45a4` (2022-12-28).
- Bug window: from v6.3 until this commit (about three years).

**Step 3.2: Fixes: tag**
Record: No `Fixes:` tag. Implicit introducer is `80056d9ac47ab` adding
SM8450 MDSS without the IOMMU match. That driver and DT are in this
tree.

**Step 3.3: File history**
Record: Several sibling “Add … MDSS compatible” commits (`f7fa8520f3037`
SM6115, `12721e6600579` X1E80100, `28af105cb6504` QCM2290,
`270a1470408e4` SDM670, `617937d4d5533` Glymur). Standalone one-line
table entries; SM6115 even had `Cc: stable` and crash logs. No extra
prerequisite beyond the existing match table.

**Step 3.4: Author**
Record: Esteban Urrutia has only this IOMMU commit here. Reviewed by
Konrad Dybcio; applied by Will Deacon. Not a drive-by unreviewed change.

**Step 3.5: Dependencies**
Record: Needs `qcom_smmu_client_of_match` /
`qcom_smmu_def_domain_type()` and a `qcom,sm8450-mdss` client. All
present. No new APIs. Applies as a one-line insert next to
`qcom,sm8250-mdss`.

## Phase 4: Mailing list / external research

**Step 4.1: Original discussion**
Record:
- `b4 dig -c d149c8b2c0146` →
  https://patch.msgid.link/20260711-sm8450-qol-
  smmu-v2-1-41a6fba41c3e@proton.me
- v1: 8-patch “sm8450-qol” series (2026-06-22)
- v2: this patch split out alone (2026-07-11)
- Will Deacon: “Applied to iommu (arm/smmu/updates), thanks!” — no NAK
- Cover note: “This patch allows the MDSS driver to properly function on
  SM8450 based devices.”
- lore.kernel.org fetches returned 403; content confirmed via patchew
  and LKML mirror.

**Step 4.2: Recipients (`b4 dig -w`)**
Record: Will Deacon, Robin Murphy, Joerg Roedel, Rob Clark, Konrad
Dybcio; lists `iommu@`, `linux-arm-msm@`, `linux-arm-kernel@`, `phone-
devel@`. Right maintainers and lists.

**Step 4.3: Bug report**
Record: No syzbot/bugzilla. Author describes the UEFI framebuffer
context-fault. Same failure as SM6115 (`f7fa8520f3037`): flood of
`Unhandled context fault` and failed DPU/GPU bind.

**Step 4.4: Series**
Record: v2 is standalone. Other v1 QoL patches (dispcc, dts, qmp) are
not required for this one-line match.

**Step 4.5: Stable list**
Record: No stable-thread hit for this subject. Precedent: SM6115
equivalent was `Cc: stable`.

## Phase 5: Semantic analysis

**Step 5.1: Functions**
Record: Table `qcom_smmu_client_of_match[]` only. Consumer:
`qcom_smmu_def_domain_type()`.

**Step 5.2: Callers**
Record: `qcom_smmu_def_domain_type` is `.def_domain_type` on the
Qualcomm SMMU impls. `arm_smmu_def_domain_type()` in `arm-smmu.c` calls
it; IOMMU core `iommu_get_def_domain_type()` uses that at device attach.
Probe-time, not IRQ/hot path.

**Step 5.3: Callees**
Record: `of_match_device()` only.

**Step 5.4: Reachability**
Record: Yes, on Qualcomm SM8450 with MDSS enabled (`iommus` in
`sm8450.dtsi`; `&mdss { status = "okay"; }` in `sm8450-hdk.dts`).
Userspace does not need to do anything; boot + display probe is enough.

**Step 5.5: Similar patterns**
Record: Same omission pattern for many MDSS SoCs; several already
patched. SM8450 was the gap between sm8250 and x1e80100.

## Phase 6: Local tree (this checkout)

**Step 6.1: Does the buggy code exist here?**
Record:
- `git describe HEAD`: `v7.3-rc4-27-gf0100363d8c37`
- `make kernelversion`: `7.3.0-rc4`
- This is the 7.3-rc4 mainline checkout, not an older LTS branch.
- Match table, `qcom_smmu_def_domain_type()`, DRM `qcom,sm8450-mdss`,
  and DT node all exist.
- `git merge-base --is-ancestor d149c8b2c0146 HEAD` succeeded (commit is
  already in HEAD). That is ignored as “already selected”; it does not
  change technical merit.
- Without this line, SM8450 MDSS would still take a translated domain on
  this tree’s code.

**Step 6.2: Backport difficulty**
Record: Clean one-line apply against this file. Context around
`sm8250-mdss` / `x1e80100-mdss` is stable.

**Step 6.3: Related fixes already here?**
Record: ACTLR prefetch entry for `qcom,sm8450-mdss` is already present
(`f91879fdf70bd`). That does not set identity domain. No other fix
covers this bug.

## Phase 7: Subsystem context

**Step 7.1**
Record: `drivers/iommu/arm/arm-smmu/` Qualcomm implementation. IMPORTANT
for ARM64 Qualcomm devices; not core mm/VFS, but IOMMU misconfig breaks
display on those boards.

**Step 7.2**
Record: Actively maintained (recent Glymur, ACTLR, fastrpc fixes). The
match-table mechanism itself dates to 2020 and is mature.

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
Record: SM8450 (Snapdragon 8 Gen 1) boards with MDSS, e.g.
`sm8450-hdk.dts` (`status = "okay"`). Config: `CONFIG_ARM_SMMU` +
`CONFIG_ARM_SMMU_QCOM` (default y on `ARCH_QCOM`).

**Step 8.2: Trigger**
Record: Boot when UEFI left the framebuffer mapped and MDSS probes.
Common on these phones/HDKs, not a rare race. Unprivileged userspace is
not required.

**Step 8.3: Failure mode**
Record: Unhandled SMMU context faults; display init can fail (same class
as SM6115: DPU/GPU bind errors). Severity: HIGH for those devices
(broken display, fault spam). Not a universal panic.

**Step 8.4: Risk–benefit**
Record: Benefit high for SM8450 display. Risk very low (one compatible,
existing quirk table). Ratio strongly favors backport.

## Phase 9: Synthesis

**Step 9.1: Evidence**

For:
- Real bug: missing identity-domain quirk → SMMU context faults / non-
  working MDSS
- Hardware quirk / compatible addition (stable exception)
- 1 line, obviously correct
- Reviewed by Konrad Dybcio, applied by Will Deacon
- Same class as SM6115, which was `Cc: stable`
- SM8450 MDSS has been in this lineage since v6.3
- No new API, no refactor, no extra dependencies

Against:
- No `Fixes:` / `Cc: stable` (expected here, not a negative)
- Affects one SoC family, not all machines
- Originally in a “QoL” series (v2 is a standalone bugfix)

Unresolved: lore.kernel.org 403 prevented reading every v1 reply; v2
application and Konrad’s Reviewed-by are verified via patchew/LKML/`b4
dig`.

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** — one-line OF match;
   maintainer review/apply
2. Real user bug? **PASS** — context faults / MDSS broken on SM8450 with
   UEFI FB
3. Important (crash/security/corruption/deadlock)? **PASS** — unhandled
   SMMU faults and failed display; HIGH for that hardware
4. Small and contained? **PASS** — +1 line, one file
5. No new features/APIs? **PASS** — existing quirk table only
6. Can apply to this tree? **PASS** — table, MDSS driver, and DT are
   here

**Step 9.3: Exception**
Record: Device ID / hardware quirk on an existing driver. Automatic YES
class.

**Step 9.4: Decision**
This tree (`v7.3-rc4`) has SM8450 MDSS and the Qualcomm SMMU client
table. The patch is the standard identity-domain compatible for a
bootloader-configured display. It should be treated as stable material.

Explanation: Without `qcom,sm8450-mdss` in `qcom_smmu_client_of_match`,
MDSS is attached to a translated IOMMU domain while UEFI still owns a
physically addressed framebuffer, which produces unhandled context
faults and can prevent the display stack from coming up. Adding the
compatible selects `IOMMU_DOMAIN_IDENTITY`, matching every other
Qualcomm MDSS entry in that table. Benefit is working display on SM8450;
risk is a single OF match that cannot affect other hardware.

Verification:
- [Phase 1] Parsed tags: Reviewed-by Konrad Dybcio; SOB Esteban Urrutia,
  Will Deacon; no Fixes/Cc stable
- [Phase 2] Diff: +1 line in `qcom_smmu_client_of_match[]`;
  `qcom_smmu_def_domain_type()` returns `IOMMU_DOMAIN_IDENTITY` on match
- [Phase 3] `git log`/`git blame`: table from `0e764a01015df` (2020);
  SM8450 DRM `80056d9ac47ab` (v6.3-rc1); this commit `d149c8b2c0146`
- [Phase 3] Sibling SM6115 commit `f7fa8520f3037` had `Cc: stable` and
  context-fault logs
- [Phase 3] `git merge-base --is-ancestor d149c8b2c0146 HEAD` → yes
  (already in this checkout)
- [Phase 4] `b4 dig -c d149c8b2c0146`: v2 at
  patch.msgid.link/20260711-sm8450-qol-smmu-v2-1-41a6fba41c3e@proton.me
- [Phase 4] `b4 dig -a`: v1 8-patch QoL series → v2 standalone SMMU
  patch
- [Phase 4] `b4 dig -w`: Will Deacon, Robin Murphy, Rob Clark, Konrad
  Dybcio, iommu@ and linux-arm-msm@
- [Phase 4] patchew: Will Deacon applied; no NAK
- [Phase 4] lore.kernel.org WebFetch: 403 — UNVERIFIED full v1 reply
  text; v2 content verified via patchew/LKML
- [Phase 5] Callers: `arm_smmu_def_domain_type` → IOMMU default domain
  at probe
- [Phase 6] `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion`: 7.3.0-rc4
- [Phase 6] Confirmed `qcom,sm8450-mdss` in `msm_mdss.c`, `sm8450.dtsi`,
  HDK `&mdss { status = "okay"; }`
- [Phase 6] Pre-commit file still had ACTLR `sm8450-mdss` only; client
  table lacked it
- [Phase 7] `CONFIG_ARM_SMMU_QCOM` default y on `ARCH_QCOM`
- [Phase 8] Failure mode: unhandled SMMU context fault / broken MDSS on
  SM8450, severity HIGH for that platform
- [Phase 4.5] No stable-list discussion found for this specific commit

**YES**

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index f7cb7de80cfb9..b6493e92343be 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -394,6 +394,7 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
 	{ .compatible = "qcom,sm6375-mdss" },
 	{ .compatible = "qcom,sm8150-mdss" },
 	{ .compatible = "qcom,sm8250-mdss" },
+	{ .compatible = "qcom,sm8450-mdss" },
 	{ .compatible = "qcom,x1e80100-mdss" },
 	{ }
 };
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (27 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/arm-smmu-qcom: Add SM8450 MDSS compatible Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: zynq: handle kasprintf() failure in periph_clk registration Sasha Levin
                   ` (19 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Chad Monroe, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 98aff74779da9f417386c589c36848e9c568f0f9 ]

mt7615_tx() falls back to the vif BSS wcid when mac80211 hands a frame
over without a station, e.g. while a station is being torn down, and to
the global wcid when there is no vif either. Both tx_prepare_skb
implementations derive a mt7615_sta from that wcid unconditionally and,
if the rate control probe flag is set, pass it to mt7615_mac_set_rates(),
which dereferences the NULL vif backpointer of the per-vif embedded sta:

  Unable to handle kernel read from unreadable memory at virtual
  address 0000000000000002
  ...
  pc : mt7615_mac_set_rates
  lr : mt7615_tx_prepare_skb

Neither entry is rate controlled by mac80211: the embedded sta has an
empty rate set, and for the global wcid the container_of does not yield a
valid mt7615_sta at all. Only resolve the sta for wcids that belong to a
station.

Reported-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: `[wifi: mt76: mt7615]` `[fix]` `[NULL deref in
mt7615_mac_set_rates when TX uses a non-station wcid]`

**Step 1.2 — Tags**
Record:
- `Reported-by: Chad Monroe <chad@monroe.io>` — real user hit this
- `Link:
  https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name` —
  patch 23/29 of an mt76-next series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
- No `Fixes:`, no `Cc: stable` (expected for this review)
- No `Reviewed-by` / `Tested-by` / `Acked-by` on the commit itself
- Ignore `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
  present (pipeline)

**Step 1.3 — Body**
Record:
- Bug: `mt7615_tx()` falls back to the vif BSS wcid when mac80211 TX has
  no station (e.g. station teardown), and to `global_wcid` if there is
  no vif. Both `tx_prepare_skb` paths `container_of` that wcid into
  `mt7615_sta` and, if `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is set, call
  `mt7615_mac_set_rates()`.
- Symptom: kernel NULL deref / oops:
  `Unable to handle kernel read from unreadable memory at virtual
  address 0000000000000002`, `pc: mt7615_mac_set_rates`, `lr:
  mt7615_tx_prepare_skb`
- Root cause: BSS-embedded sta has a NULL `vif` backpointer;
  `global_wcid` is not a `mt7615_sta` at all. Neither is rate-
  controlled.
- Fix: only resolve `msta` when `wcid->sta` is set.

**Step 1.4 — Hidden bug fix?**
Record: Not hidden. Explicit crash fix with a stack trace and a
reporter.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- `drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c`:
  `mt7615_tx_prepare_skb` — ~3 lines
- `drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c`:
  `mt7663_usb_sdio_tx_prepare_skb` — ~3 lines
- Scope: single-driver surgical fix, two TX prepare paths (PCIe/MMIO and
  USB/SDIO)

**Step 2.2 — Code flow**
Record: Before, any non-NULL `wcid` was treated as `mt7615_sta`. After,
`msta` is set only if `wcid && wcid->sta`. The existing `if (...
RATE_CTRL_PROBE && msta)` already skips `mt7615_mac_set_rates()` when
`msta` is NULL.

**Step 2.3 — Bug mechanism**
Record: `[NULL pointer dereference]` — `mt7615_mac_set_rates()` does
`sta->vif->mt76.omac_idx`. For the per-vif embedded sta, `vif` is never
set. For `global_wcid`, `container_of` is invalid. The fix uses the
existing `wcid->sta` flag.

**Step 2.4 — Fix quality**
Record: Obviously correct. Same pattern already used in this tree
(`wcid_to_sta()`, `mt76_connac_pm_dequeue_skbs()`,
`mt7615_rx_get_wcid()`). Skipping rate-probe setup for non-station wcids
is intended: those entries are not rate-controlled. Regression risk is
very low. No API change.

## Phase 3: Git history

**Step 3.1 — Blame**
Record: The incomplete NULL check is `8d3cdc1bbb1d3` (“mt76: mt7615: fix
NULL pointer dereference in tx_prepare_skb()”, Lorenzo Bianconi, 2021).
That only handled `wcid == NULL` (then `global_wcid`). The BSS-wcid
fallback in `mt7615_tx()` is from 2019 (`04b8e65922f631` /
`2b8cdfb28d3402`). The bug has been in this lineage since mt7615 TX was
added.

**Step 3.2 — Fixes: tag**
Record: None. The incomplete 2021 fix is already in this tree (`git
merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD` succeeded). This commit
closes the remaining hole.

**Step 3.3 — File history**
Record: Recent mt7615 changes in this tree are unrelated (runtime-pm
timeout, TSF, DMA reset). No prerequisite refactor for this two-line
guard. Standalone.

**Step 3.4 — Author**
Record: Felix Fietkau is the mt76 maintainer. Related earlier NULL-deref
fix was also signed off by him.

**Step 3.5 — Dependencies**
Record: Patch 23/29 of an mt76-next batch, but the other patches are
independent (mt7996/mt7915/scan/WED). This hunk only needs `wcid->sta`
and the existing `msta` NULL check, both present here. Standalone.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
Record: `b4 mbox` saved the thread. Subject: `[PATCH mt76-next 23/29]
wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates`. Sent 24 Jul
2026 by Felix to linux-wireless. 29-message thread is the series itself,
not a v2/v3 of this patch. No NAK. No reviewer `Cc: stable`. Lore HTTP
fetch returned 403; discussion was recovered via `b4`.

**Step 4.2 — Recipients**
Record: To: linux-wireless@vger.kernel.org. Maintainer is the author.

**Step 4.3 — Bug report**
Record: Reported-by Chad Monroe with a concrete oops (`pc:
mt7615_mac_set_rates`, `lr: mt7615_tx_prepare_skb`). Chad also authored
other patches in the same series, so this is a real device user, not a
theoretical report.

**Step 4.4 — Series**
Record: Independent mt76 bug-fix dump. mt7996 patches are irrelevant to
5.15. This patch does not need 1–22 or 24–29.

**Step 4.5 — Stable list**
Record: UNVERIFIED — lore.kernel.org/stable HTTP 403. No evidence it was
rejected for stable.

## Phase 5: Semantic / call-chain

**Step 5.1 — Functions**
Record: `mt7615_tx_prepare_skb`, `mt7663_usb_sdio_tx_prepare_skb`
(callers of `mt7615_mac_set_rates`).

**Step 5.2 — Callers**
Record:
- PCIe/MMIO: `mt7615_tx_prepare_skb` via `mt7615/mmio.c`
  `.tx_prepare_skb`, from `mt76_dma_tx_queue_skb` (`dma.c:409`)
- USB: `usb.c:917`; SDIO: `sdio.c:263`
- Upstream of that: `mt7615_tx()` → `mt76_tx()` /
  `mt76_connac_pm_queue_skb()`

**Step 5.3 — Callees**
Record: `mt7615_mac_set_rates()` immediately uses
`sta->vif->mt76.omac_idx` (mac.c:1063 in this tree).

**Step 5.4 — Reachability**
Record: Yes, from normal wireless TX. `mt7615_tx()`:

```737:743:drivers/net/wireless/mediatek/mt76/mt7615/main.c
        if (vif && !control->sta) {
                struct mt7615_vif *mvif;
                mvif = (struct mt7615_vif *)vif->drv_priv;
                msta = &mvif->sta;
                wcid = &msta->wcid;
        }
```

mac80211 can pass `control->sta == NULL` while
`IEEE80211_TX_CTL_RATE_CTRL_PROBE` is still set on a previously rate-
controlled skb (station teardown). That is a userspace-reachable
AP/client path.

**Step 5.5 — Similar patterns**
Record: Same `wcid && wcid->sta` guard already exists in
`mt76x02_mac.c`, `mt76_connac_mac.c`, `wcid_to_sta()`.
`mt7615_rx_get_wcid()` already refuses non-station wcids. `wcid.sta = 1`
is set only in `mt7615_mac_sta_add()`, not in `mt7615_add_interface()`.

## Phase 6: Local tree (5.15.221 / pending-5.15)

**Step 6.1 — Buggy code present?**
Record: Yes.
- `pci_mac.c:142`: `msta = wcid ? container_of(wcid, struct mt7615_sta,
  wcid) : NULL;`
- `usb_sdio.c:200`: same
- `mac.c:1063`: `u16 idx = sta->vif->mt76.omac_idx;`
- `add_interface` sets `mvif->sta.wcid` but never `mvif->sta.vif` or
  `wcid.sta`
- `wcid->sta` exists in `struct mt76_wcid` (`mt76.h:251`)

**Step 6.2 — Backport difficulty**
Record: Minor context mismatch, easy rework. Mainline USB path has extra
locals (`key`, `pktid`) and an in-function `global_wcid` fallback that
5.15 keeps in `mt7663_usb_sdio_write_txwi()`. PCIe path uses
`MT_TX_HW_QUEUE_EXT_PHY` / `mdev->phy2` here vs later `phys[MT_BAND1]`.
The semantic change is the same two-line `wcid->sta` check.
`mt76_vif_link` in the provided hunk context is *not* required.

**Step 6.3 — Related fixes already here?**
Record: `8d3cdc1bbb1d3` is present and is incomplete. No later
`mt7615_mac_set_rates` NULL-deref fix in this tree.

## Phase 7: Subsystem context

**Step 7.1**
Record: `[drivers/net/wireless/mediatek/mt76/mt7615]` `[IMPORTANT]` —
not core kernel, but a widely used 802.11ac chipset (MT7615E/MT7663E
PCIe, MT7663U USB, MT7663S SDIO, MT7622 SoC WMAC). Common on routers and
embedded boards, including 5.15 LTS/Android/OpenWrt-class systems.

**Step 7.2**
Record: Mature driver; this bug is old, not a new-subsystem issue.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: Users of MT7615/MT7663/MT7622 (`CONFIG_MT7615E` /
`CONFIG_MT7663U` / `CONFIG_MT7663S` / `CONFIG_MT7622_WMAC`). Driver-
specific, not universal.

**Step 8.2 — Trigger**
Record: TX without a station while `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is
set — typically station teardown / disconnect with a probe rate sample
in flight. Not every packet, but a normal Wi-Fi event. Unprivileged
clients disconnecting from an AP can induce it.

**Step 8.3 — Failure mode**
Record: `[Kernel oops / NULL deref in hard TX path]` `[CRITICAL]`

**Step 8.4 — Risk vs benefit**
Record: Benefit high for that hardware (prevents oops). Risk very low
(~6 lines, existing flag, same pattern as sibling code). Skipping
`mac_set_rates` on BSS/global wcid is the correct behavior.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

FOR:
- Real oops with reporter and stack trace
- Bug and incomplete 2021 fix both exist in this 5.15 tree
- Small, obviously correct guard
- Maintainer-authored
- Matches stable rules (crash, contained, no new API)
- Hardware is common on 5.15-era devices

AGAINST:
- Driver-specific, not core
- Won’t `git am` cleanly (context only)
- Part of a 29-patch series (other patches are unrelated)
- No `Fixes:` / `Cc: stable` (not a negative under these rules)
- No mailing-list review tags on this specific patch

UNRESOLVED:
- Could not fetch lore/stable over HTTP (403); recovered the thread with
  `b4`
- Exact crash address `...0002` matches a newer `vif` layout; in 5.15
  `omac_idx` is at offset 1. Same NULL `vif` deref either way.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — maintainer fix; user-
   reported oops; logic matches existing `wcid->sta` usage
2. Real bug affecting users? **PASS** — Chad Monroe crash
3. Important (crash/security/corruption/deadlock)? **PASS** — kernel
   oops in TX
4. Small and contained? **PASS** — two functions, ~6 lines
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** — code is here; needs a trivial
   context tweak, not a rewrite

**Step 9.3 — Exceptions**
Record: None (not a device-ID/quirk/DT/build/docs exception). It
qualifies as a normal crash fix.

**Step 9.4 — Decision**
This is a real NULL deref in the mt7615 TX path that 5.15 still has. The
2021 patch only covered a NULL wcid; the BSS-wcid fallback still
crashes. Backport it.

## What the commit solves for this tree

On 5.15.221, `mt7615_tx()` still substitutes the per-vif embedded sta
when mac80211 has no station. `tx_prepare_skb` still `container_of`s
that wcid and can call `mt7615_mac_set_rates()`, which immediately loads
`sta->vif->mt76.omac_idx` while `vif` is NULL. That oopses. Restricting
`msta` to `wcid->sta` stops it. Same change belongs in both PCIe and
USB/SDIO prepare paths.

Risk is a skipped rate-probe update on wcids that were never valid for
rate control. Benefit is avoiding a driver oops during client teardown.

## Verification
- [Phase 1] Parsed tags: Reported-by Chad Monroe; Link to 23/29
  mt76-next; SOB Felix Fietkau; no Fixes/Cc stable
- [Phase 2] Diff: two `msta` assignments; require `wcid->sta` before
  `container_of`
- [Phase 3] Blame: 8d3cdc1bbb1d3 (2021) only NULL-wcid; BSS fallback
  since 2019
- [Phase 3] `git merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD`: yes,
  incomplete fix is here
- [Phase 3] `git log --grep="fix NULL deref in mt7615_mac_set_rates" --
  mt7615/`: not in this tree
- [Phase 4] `b4 mbox 20260724124813.3961474-23-nbd@nbd.name`: 29-message
  independent mt76 series; this patch standalone; no NAK
- [Phase 4] lore HTTP 403; UNVERIFIED stable@ discussion
- [Phase 5] Call chain: mac80211 `drv_tx` → `mt7615_tx` → `mt76_tx` /
  DMA `tx_prepare_skb` → `mt7615_mac_set_rates`
- [Phase 5] `mt7615_add_interface` does not set `mvif->sta.vif` or
  `wcid.sta`; only `mt7615_mac_sta_add` sets `wcid.sta = 1`
- [Phase 6] `make kernelversion` / Makefile: **5.15.221**, branch
  `pending-5.15`
- [Phase 6] Buggy lines present in `pci_mac.c:142` and `usb_sdio.c:200`;
  deref at `mac.c:1063`
- [Phase 6] Surrounding context differs (phy2 vs phys[MT_BAND1], USB
  locals); semantic apply is still two lines
- [Phase 8] Failure: NULL deref oops in TX; severity CRITICAL for
  MT7615/MT7663/MT7622 users

**YES**

 drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c  | 5 +++--
 drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
index b795d11d943d0..61efdf59133f5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
@@ -68,10 +68,11 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	int pid, id;
 	u8 *txwi = (u8 *)txwi_ptr;
 	struct mt76_txwi_cache *t;
-	struct mt7615_sta *msta;
+	struct mt7615_sta *msta = NULL;
 	void *txp;
 
-	msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+	if (wcid && wcid->sta)
+		msta = container_of(wcid, struct mt7615_sta, wcid);
 	if (!wcid)
 		wcid = &dev->mt76.global_wcid;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
index 820b395900275..01e79f37649c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
@@ -187,10 +187,11 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	struct sk_buff *skb = tx_info->skb;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_key_conf *key = info->control.hw_key;
-	struct mt7615_sta *msta;
+	struct mt7615_sta *msta = NULL;
 	int pad, err, pktid;
 
-	msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+	if (wcid && wcid->sta)
+		msta = container_of(wcid, struct mt7615_sta, wcid);
 	if (!wcid)
 		wcid = &dev->mt76.global_wcid;
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] clk: zynq: handle kasprintf() failure in periph_clk registration
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (28 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] media: cec: stm32: return an error when log-address wait times out Sasha Levin
                   ` (18 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: William Theesfeld, Brian Masney, Michal Simek, Sasha Levin, sboyd,
	bmasney+clk, jbrunet+clk, linux-clk, linux-arm-kernel,
	linux-kernel

From: William Theesfeld <william@theesfeld.net>

[ Upstream commit d4d0d335e8d37c6c7e1c5664c7664288eca5a09b ]

zynq_clk_register_periph_clk() ignores the return value of the two
kasprintf() calls used to build the mux and divider clock names, and
passes the resulting (possibly NULL) pointers straight into
clk_register_mux(), clk_register_divider() and clk_register_gate() as
the clock '"'name'"' argument.  On allocation failure that name later
gets dereferenced by the clock framework (e.g. in debugfs name
formatting), causing a NULL-pointer dereference.

Check both kasprintf() returns.  On failure unwind any allocated name
buffer and the spinlock, then fall through to the existing err label
which sets clks[] to ERR_PTR(-ENOMEM).  Freeing the spinlock on the
error path is correct here because no clk_register_*() call has had
a chance to take ownership of it; the success path intentionally
hands it off to the registered clocks.

The neighbouring zynq_clk_register_fclk() in the same file already
uses this per-allocation goto-label cleanup pattern; this change
brings periph_clk into line with it.

Signed-off-by: William Theesfeld <william@theesfeld.net>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.53**. The buggy
`zynq_clk_register_periph_clk()` path is present here, and the patch is
an 8-line error-path fix. Full nine-phase analysis follows.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
- Subsystem: `clk: zynq`
- Action verb: **handle** (bug-fix verb: missing failure handling)
- Intent: check `kasprintf()` in peripheral clock registration so a NULL
  name is not passed into the clock framework
- Record: `[clk/zynq] [handle] [check kasprintf failure when registering
  periph clocks]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- `Reviewed-by: Brian Masney <bmasney@redhat.com>` — clk co-maintainer;
  also final `Signed-off-by` into clk tree
- `Reviewed-by: Michal Simek <michal.simek@amd.com>` — ARM/Zynq
  architecture maintainer
- `Signed-off-by: William Theesfeld <william@theesfeld.net>` — author
- `Signed-off-by: Brian Masney <bmasney@redhat.com>` — maintainer merge
- No `Fixes:` tag (expected for this review pipeline)
- No `Reported-by:`, `Tested-by:`, `Link:`, or `Cc: stable`
- Pipeline-added markers ignored per instructions: `[Upstream commit
  d4d0d335…]`, `Signed-off-by: Sasha Levin`
- Record: maintainer-reviewed, no syzbot/user report, no Fixes tag

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
- Bug: `zynq_clk_register_periph_clk()` ignores two `kasprintf()`
  results used as mux/divider names and passes them into
  `clk_register_mux/divider/gate`
- Claimed symptom: NULL name later dereferenced in CCF (commit cites
  debugfs name formatting) → NULL-pointer dereference
- Fix: check both returns; on failure free the other name buffer and the
  spinlock, then the existing `err` label sets `clks[] =
  ERR_PTR(-ENOMEM)`
- Author notes the sibling `zynq_clk_register_fclk()` already uses this
  goto-cleanup pattern
- Record: `[Bug: unchecked kasprintf] [Symptom: NPD / broken clock init]
  [No version info] [Root cause: missing NULL checks before
  clk_register_*]`

**Step 1.4: DETECT HIDDEN BUG FIXES**
- Not disguised. Explicit error-path fix. Also closes a spinlock leak on
  the failure path (lock is allocated before `kasprintf`; success hands
  it to registered clocks, so failure must `kfree(lock)`).
- Record: `[Not hidden; allocation-failure / leak / NPD-class error-path
  fix]`

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
- File: `drivers/clk/zynq/clkc.c` — **+8 / -0**
- Function: `zynq_clk_register_periph_clk()`
- Scope: single-file surgical error-path fix
- Record: `[clkc.c +8] [zynq_clk_register_periph_clk] [surgical]`

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Verified against parent `e3b8b15ec6f0a^`:

Before:
```
mux_name = kasprintf(...);   /* unchecked */
div_name = kasprintf(...);   /* unchecked */
clk_register_mux(..., mux_name, ...);
clk_register_divider(..., div_name, mux_name, ...);
clks[clk0] = clk_register_gate(..., clk_name0, div_name, ...);
```
`err` was only used for `kmalloc(lock)` failure.

After: NULL `mux_name` → `err_mux_name` (`kfree(lock)`); NULL `div_name`
→ `err_div_name` (`kfree(mux_name)` then lock). Then `err` sets
`clks[clk0/clk1] = ERR_PTR(-ENOMEM)`. Success path unchanged.
- Record: `[error path only: skip clk_register_* on kasprintf failure
  and unwind]`

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Category: **error path / resource leak** plus **memory safety** (NULL
name into CCF).

Verified CCF behavior in this tree (`drivers/clk/clk.c`):
- `kstrdup_const(NULL)` → `kstrdup(NULL)` returns NULL (`mm/util.c:84`)
- `__clk_register` then fails with `-ENOMEM` if `core->name` is NULL
  (`clk.c:4435-4438`)
- NULL **parent** name hits `WARN(!parent_names[i], ...)` then
  `clk_cpy_name(..., true)` returns `-EINVAL` (`clk.c:4347-4351,
  4307-4309`)
- `zynq_clk_setup()` then does `if (IS_ERR(clks[i])) BUG();`
  (`clkc.c:570-575`)

So a fully failed registration already `BUG()`s. The remaining hole is
mixed failure (mux `kasprintf` fails, div succeeds): mux/div
registration fails, gate may still register with a valid DT name and a
never-created parent → no `BUG()`, broken UART/SDIO/SPI/LQSPI/SMC/PCAP
clocks, and the spinlock can leak because `err` is not taken.
- Record: `[error-path leak + WARN + inconsistent clks[] / possible
  silent broken periph clocks]`

**Step 2.4: ASSESS THE FIX QUALITY**
- Matches the existing `zynq_clk_register_fclk()` pattern (present since
  `f8fe36f6083a70`, v3.13).
- `kfree(lock)` on this path is correct: no `clk_register_*` has run
  yet.
- Does not change the success path.
- Regression risk: very low. On failure, `clks[]` becomes
  `ERR_PTR(-ENOMEM)` and `zynq_clk_setup()` `BUG()`s — same policy this
  driver already uses for lock allocation / registration failure.
- Record: `[obviously correct, 8 lines, error-path only; risk very low]`

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
- Function introduced in `0ee52b157b8ed8` (“clk: zynq: Add clock
  controller driver”), 2013, contained in **v3.11-rc1**.
- `kasprintf` calls were unchecked from introduction until this fix.
- Record: `[0ee52b157b8ed8 / v3.11] [bug present for the life of this
  driver]`

**Step 3.2: FOLLOW THE FIXES: TAG**
- No `Fixes:` tag. Buggy commit is the original driver add, which **is**
  in this tree.
- Record: `[no Fixes tag; original driver commit is in this tree]`

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
- `f8fe36f6083a70` (v3.13): same goto-cleanup for
  `zynq_clk_register_fclk()` kasprintf/kmalloc
- `7938e9ce39d67` (2024, in this tree): “Prevent null pointer
  dereference caused by kmalloc failure” in `zynq_clk_setup()`
- `a6aa462c3efc1`: parameter update to this function — not a
  prerequisite for these checks
- Standalone; not patch N/M
- Record: `[standalone; sibling already had the pattern; related kmalloc
  NPD fix already here]`

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
- Only this clk/zynq commit from William Theesfeld in this tree
- Weight comes from reviewers: Michal Simek (Zynq) and Brian Masney
  (clk)
- Record: `[author not subsystem maintainer; both relevant maintainers
  reviewed]`

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
- Uses existing `kasprintf`, `kfree`, `goto err` — all present
- Mainline context uses `kmalloc_obj`; this tree still uses
  `kmalloc(sizeof(*lock), GFP_KERNEL)`. The hunk does not touch that
  line, so no `kmalloc_obj` dependency.
- Record: `[no prerequisites; applies standalone against this tree’s
  kmalloc() form]`

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
- `b4 dig -c d4d0d335e8d37c6c7e1c5664c7664288eca5a09b` →
  https://patch.msgid.link/20260601203500.658135-1-william@theesfeld.net
- `b4 dig -a`: **v1 only** (2026-06-01)
- Thread saved to mbox: Michal Simek Reviewed-by (2026-06-02); Brian
  Masney Reviewed-by (2026-06-15). No NAK, no requested respin, no Cc:
  stable in review.
- Lore WebFetch returned 403; discussion read from `b4 dig -m` instead
- Record: `[lore msgid 20260601203500.658135-1-william@theesfeld.net]
  [v1 applied] [no NAKs] [no stable nomination in thread]`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
- `b4 dig -w` recipients: Turquette, Boyd, Masney, Simek, linux-clk,
  linux-arm-kernel, linux-kernel
- Record: `[clk maintainers + Zynq maintainer were on To/Cc; both
  Reviewed-by]`

**Step 4.3: SEARCH FOR THE BUG REPORT**
- No Reported-by / Link / syzbot
- Record: `[no external bug report; found by code inspection]`

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
- Standalone v1 patch, not a series
- Record: `[standalone]`

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
- `lore.kernel.org/stable/` fetch returned 403
- Record: `[UNVERIFIED: stable-list discussion; not used for the
  verdict]`

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS**
- Record: `[zynq_clk_register_periph_clk (modified); zynq_clk_setup
  (caller)]`

**Step 5.2: TRACE CALLERS**
Call sites in `zynq_clk_setup()` (CLK_OF_DECLARE `"xlnx,ps7-clkc"`,
every Zynq boot):
- lqspi, smc, pcap (single gate)
- sdio0/sdio1, uart0/uart1, spi0/spi1 (two gates)
- Record: `[boot-time OF clock init for Zynq PS peripherals]`

**Step 5.3: TRACE CALLEES**
- `kasprintf`, `kmalloc`/`kfree`, `clk_register_mux/divider/gate`
- Record: `[name alloc + CCF register; gate clocks stored in clks[]]`

**Step 5.4: FOLLOW THE CALL CHAIN**
- `CLK_OF_DECLARE` → `zynq_clk_setup` → `zynq_clk_register_periph_clk`
  during early boot on `CONFIG_ARCH_ZYNQ`
- `CONFIG_ARCH_ZYNQ=y` in `arch/arm/configs/multi_v7_defconfig`
- Not a syscall path; unprivileged users cannot trigger it except by
  booting the platform (possibly under memory pressure)
- Record: `[reachable on every Zynq boot; not userspace-triggerable
  later]`

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
- `zynq_clk_register_fclk()` already checks every `kasprintf`
- After this patch, no remaining unchecked `kasprintf` in
  `drivers/clk/zynq/clkc.c`
- Record: `[sibling already fixed; this was the remaining hole]`

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
- `git describe HEAD` → **v6.18.53-5049-g0f0bdc2b0dffb**
- `make kernelversion` → **6.18.53**
- Parent of the candidate still has unchecked `kasprintf` in
  `zynq_clk_register_periph_clk`
- Driver built as `obj-$(CONFIG_ARCH_ZYNQ) += zynq/`
- Record: `[yes, buggy code exists in 6.18.y zynq clkc; bug since
  v3.11]`

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
- Surrounding function matches; only the 8 check/label lines are needed
- `kmalloc_obj` in the mainline diff context is **not** used in this
  file here
- Record: `[clean apply / trivial context]`

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
- `7938e9ce39d67` (kmalloc NPD in `zynq_clk_setup`) is already in this
  tree — different allocation
- fclk kasprintf checks already present
- No earlier equivalent of this periph_clk check besides the candidate
  itself
- Record: `[no substitute fix for this function’s kasprintf]`

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
- `drivers/clk/zynq/` — platform clock provider for Xilinx Zynq-7000
- Criticality: **IMPORTANT** for Zynq (UART/SDIO/SPI clocks);
  **PERIPHERAL** vs core kernel
- Record: `[clk/zynq] [IMPORTANT for affected SoC, not universal]`

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
- File is mature (2013); recent commits are small correctness fixes, not
  refactors
- Record: `[mature/stable platform driver]`

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
- Record: `[platform-specific: CONFIG_ARCH_ZYNQ / xlnx,ps7-clkc]`

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
- `kasprintf(GFP_KERNEL, "%s_mux"/"%s_div", clk_name0)` during `__init`
  (~tens of bytes)
- Trigger: allocation failure at boot (rare, but same class this file
  already treats as fatal via `BUG()`)
- Not triggerable later from unprivileged userspace
- Record: `[rare boot OOM; not a syscall race]`

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Verified, not just the commit text:
- NULL clock **name**: CCF fails `-ENOMEM` (no debugfs NPD on that path
  in 6.18)
- NULL **parent** name: `WARN()` then `-EINVAL`
- Some combinations: `clks[i]` is `ERR_PTR` → existing `BUG()` in
  `zynq_clk_setup`
- Mixed success: possible boot with broken peripheral clocks + spinlock
  leak
- Author’s debugfs-NPD example is **overstated for this CCF**, but WARN
  / leak / inconsistent init are real
- Record: `[WARN + leak + possible BUG() or silently broken
  UART/SDIO/SPI] [severity HIGH on trigger, trigger rare]`

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
- Benefit: correct OOM handling for clocks used on every Zynq boot;
  closes leak; avoids WARN and half-registered trees
- Risk: 8 lines, error path only, same pattern already in-tree
- Record: `[benefit medium-high if it fires; risk very low; ratio favors
  backport]`

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real missing error handling on `kasprintf` in a boot clock path that
  already `BUG()`s on `IS_ERR(clks[i])`
- Also a spinlock leak and a `WARN()` on NULL parent names
- 8-line, obviously correct, mirrors in-tree sibling
- Code and bug exist in this 6.18 tree since v3.11
- Applies without `kmalloc_obj` or other prereqs
- Reviewed by Zynq maintainer and clk maintainer
- Same file already received a 2024 allocation-failure NPD fix

AGAINST:
- Trigger is a tiny boot-time allocation failure (rare)
- No user/syzbot report
- Debugfs NPD claim is not how 6.18 CCF handles a NULL `init.name`
  (fails `-ENOMEM` first)
- Platform-specific, not core

UNRESOLVED:
- Stable mailing list search (lore 403)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — matches existing fclk
   pattern; two maintainer Reviewed-by
2. Fixes a real bug that affects users? **PASS** — unchecked alloc,
   leak, WARN, inconsistent `clks[]` on Zynq boot
3. Important issue? **PASS** — boot `WARN`/`BUG()`/broken UART-SDIO-SPI
   clocks; same class as the in-tree kmalloc NPD fix
4. Small and contained? **PASS** — +8 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — function and bug present;
   context is `kmalloc(sizeof)`, not `kmalloc_obj`

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
- Not a device ID / quirk / DT / build / docs exception
- Record: `[none; qualifies as a normal small bugfix]`

**Step 9.4: MAKE YOUR DECISION**
The patch is a small, maintainer-reviewed error-path fix for code this
6.18 tree has had since v3.11. It does not add features. Risk is
confined to the allocation-failure path. That is appropriate for this
stable tree.

===============================================================
What problem it solves for this tree
===============================================================
`zynq_clk_register_periph_clk()` builds mux/divider names with
`kasprintf()` and, on failure, still calls into the clock framework.
That can `WARN` on a NULL parent, leak the per-clock spinlock, and
either `BUG()` in `zynq_clk_setup()` or leave UART/SDIO/SPI/LQSPI clocks
half-registered. The fix stops before `clk_register_*`, frees the
lock/name, and reports `-ENOMEM` the way lock allocation already does.

===============================================================
Verification
===============================================================
- [Phase 1] Parsed tags: Reviewed-by Masney + Simek; no Fixes/Reported-
  by/Cc stable; ignored pipeline Upstream/Sasha SOB
- [Phase 1] Subject/body: handle kasprintf failure; claimed NPD; sibling
  fclk pattern
- [Phase 2] Diff: +8 in `zynq_clk_register_periph_clk`; parent still
  unchecked (git show e3b8b15^)
- [Phase 2] CCF: `kstrdup(NULL)` returns NULL (`mm/util.c:84`);
  `__clk_register` `-ENOMEM` on NULL name (`clk.c:4435-4438`); NULL
  parent `WARN` + `-EINVAL` (`clk.c:4347-4351`)
- [Phase 2] `zynq_clk_setup` `BUG()`s on `IS_ERR(clks[i])`
  (`clkc.c:570-575`)
- [Phase 3] blame: function from `0ee52b157b8ed8` (v3.11-rc1); fclk
  checks from `f8fe36f6083a70` (v3.13)
- [Phase 3] related `7938e9ce39d67` kmalloc NPD fix is ancestor of HEAD
- [Phase 3] no Fixes tag; original driver commit is in this tree
- [Phase 4] `b4 dig -c d4d0d335…`: lore msgid
  20260601203500.658135-1-william@theesfeld.net
- [Phase 4] `b4 dig -a`: v1 only
- [Phase 4] `b4 dig -w`: clk + Zynq maintainers on Cc
- [Phase 4] mbox: Simek and Masney Reviewed-by; no NAK
- [Phase 4] lore WebFetch 403; stable-list search UNVERIFIED
- [Phase 5] callers: lqspi/smc/pcap/sdio/uart/spi from `zynq_clk_setup`;
  `CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc")`
- [Phase 5] `CONFIG_ARCH_ZYNQ=y` in multi_v7_defconfig;
  `obj-$(CONFIG_ARCH_ZYNQ) += zynq/`
- [Phase 6] `git describe HEAD` = v6.18.53-5049-g0f0bdc2b0dffb;
  kernelversion 6.18.53
- [Phase 6] buggy kasprintf present without this patch; no kmalloc_obj
  in this file
- [Phase 8] failure mode verified against CCF (debugfs NPD overstated);
  WARN/leak/BUG/broken periph clocks verified
- UNVERIFIED: whether this hash was discussed on stable@ (lore 403)

The fix is small, surgical, present in the affected 6.18 code, and meets
the stable criteria.

**YES**

 drivers/clk/zynq/clkc.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index c28d3dacf0fb2..db40a9e7dd3d9 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -186,7 +186,11 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
 	spin_lock_init(lock);
 
 	mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
+	if (!mux_name)
+		goto err_mux_name;
 	div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
+	if (!div_name)
+		goto err_div_name;
 
 	clk_register_mux(NULL, mux_name, parents, 4,
 			CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock);
@@ -205,6 +209,10 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
 
 	return;
 
+err_div_name:
+	kfree(mux_name);
+err_mux_name:
+	kfree(lock);
 err:
 	clks[clk0] = ERR_PTR(-ENOMEM);
 	if (two_gates)
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] media: cec: stm32: return an error when log-address wait times out
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (29 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: zynq: handle kasprintf() failure in periph_clk registration Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Sasha Levin
                   ` (17 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Hans Verkuil, Sasha Levin, hverkuil, mchehab,
	mcoquelin.stm32, alexandre.torgue, linux-media, linux-stm32,
	linux-arm-kernel, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 3bc2e4a26465386332ee1a40219d8dafba335b0b ]

stm32_cec_adap_log_addr() waits for TXSOM to clear before disabling CEC
and updating the logical address registers. The wait result is ignored,
so a timeout can still be reported as a successful logical address
update.

Return the polling error before touching the address registers. Compute
the address mask only for valid logical addresses so the invalid-address
path does not evaluate a shift based on CEC_LOG_ADDR_INVALID.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.18.53** (`v6.18.53-5049-g0f0bdc2b0dffb`, branch
`autosel`). The verdict is only for this checkout: the STM32 CEC
timeout/shift bugs are present at `v6.18.53`, and the patch applies
cleanly.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: `[media/cec/stm32] [return] return an error when log-address
wait times out`

Subsystem prefix `media: cec: stm32`. Verb `return` is error-propagation
language (equivalent to “handle/fix”). Intent: stop treating a timed-out
TXSOM wait as a successful logical-address update.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
- `Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>` (CEC
  framework maintainer; also the committer of upstream `3bc2e4a26465`)
- Ignored pipeline tags: `[Upstream commit
  3bc2e4a26465386332ee1a40219d8dafba335b0b]`, `Signed-off-by: Sasha
  Levin`
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, `Link:`, or `Cc: stable` (absence expected for this review)

Notable: maintainer SOB, no syzbot/user report.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `stm32_cec_adap_log_addr()` polls for TXSOM to clear, then
  ignores the poll result and still disables CEC, writes OAR, re-enables
  CEC, and returns 0.
- **Symptom:** userspace/CEC core can be told a logical address was
  programmed when the wait timed out and the registers may not have been
  updated safely.
- **Second issue:** address mask `(1 << logical_addr) << 16` is computed
  before the `CEC_LOG_ADDR_INVALID` check, so the invalid-address path
  still evaluates a shift of `0xff`.
- **Root cause:** missing return-value check; mask computed too early.
- **Version info:** none in the message. Poll wait was added in 2019
  (`1a726df6078c2f`, v5.2-rc1).

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not disguised. It is an explicit error-path and UB fix (“return
the polling error”, “does not evaluate a shift”).

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/media/cec/platform/stm32/stm32-cec.c` — **+11 / −5**
  (16 lines in one function)
- Function: `stm32_cec_adap_log_addr()` only
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record (verified against `v6.18.53` and the candidate diff):

**Before** (at `v6.18.53`):
```c
u32 oar = (1 << logical_addr) << 16;
regmap_read_poll_timeout(...);  /* return value discarded */
regmap_update_bits(..., CECEN, 0);
if (logical_addr == CEC_LOG_ADDR_INVALID)
    clear OAR;
else
    set oar bits;
re-enable CECEN;
return 0;
```

**After:**
- Capture poll result; if nonzero, return it immediately (no CFGR
  write).
- Compute `BIT(logical_addr) << 16` only in the valid-address branch.

Affected path: CEC logical-address claim and unconfigure
(`adap_log_addr`), not probe/IRQ hot path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **(a) Error path:** ignored `regmap_read_poll_timeout()` result.
  Typical returns: `-ETIMEDOUT` or `-EFAULT`.
- **(g) Logic/correctness:** false success (`return 0`) after a failed
  wait.
- **(f/UBSAN):** `(1 << logical_addr)` with `logical_addr ==
  CEC_LOG_ADDR_INVALID` (`0xff` in `include/uapi/linux/cec.h`) is an
  oversized shift (UB). Result is unused on that branch, but the
  expression is always evaluated first.

Hardware context (from `1a726df6078c2f`): CFGR/OAR must be written only
with CECEN=0, after TXSOM clears. On timeout the old code still toggled
CECEN and wrote CFGR.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Obviously correct: check the value the wait already returned; don’t
  shift `0xff`.
- Minimal; `1 <<` → `BIT()` is local to the valid-LA branch (`BIT` comes
  from `linux/kernel.h` → `bitops.h` → `vdso/bits.h`, already included).
- Regression risk: low. On timeout, `cec_config_log_addr()` already does
  `if (err) return err`. On unconfigure, `cec_adap_unconfigure()` does
  `WARN_ON(call_op(..., CEC_LOG_ADDR_INVALID))`, so a stuck TXSOM can
  now warn instead of silently returning 0. That is the existing core
  contract for a failed clear, not a new API. Timeout budget is
  `CEC_XFER_TIMEOUT_MS` = 2100 ms, so this is a stuck-TX path, not a
  normal claim.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Function and `return 0` / CECEN/OAR writes: `d69ae57453c80a` (“[media]
  cec: add STM32 cec driver”, 2017) — first in **v4.13-rc1**.
- Poll without checking the result: `1a726df6078c2f` (“media: platform:
  stm32: wait end of transmission”, 2019) — first in **v5.2-rc1**.
- Buggy pattern has been in this line of kernels for years, including
  6.18.y.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No `Fixes:` tag. Buggy poll commit `1a726df6078c2f` **is** an
ancestor of HEAD and of `v6.18.53`. Intermediate related work on this
file: `0c260d3f97e52` (RX overflow OOB) is a separate bug, not a
prerequisite.

**Step 3.3: CHECK FILE HISTORY**

Record: Recent file commits are cleanup/moves plus the RX OOB fix. This
is standalone, not “patch X/Y”. No later follow-up on this function
after the candidate.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Pengpeng Hou is not the CEC maintainer. In this tree, the other
hit under `drivers/media/cec/` is unrelated (`tegra`
MODULE_DEVICE_TABLE). Weight comes from **Hans Verkuil** (CEC FRAMEWORK
maintainer in `MAINTAINERS`) signing off and committing upstream.

**Step 3.5: DEPENDENT/PREREQUISITE COMMITS**

Record: None. Uses existing `regmap_read_poll_timeout`, `BIT()`,
`CEC_LOG_ADDR_INVALID`. Can apply standalone. Confirmed `1a726df6078c2f`
and `d69ae57453c80a` are in `v6.18.53`.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c 3bc2e4a26465` →
  https://patch.msgid.link/20260624144015.63929-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only**, 2026-06-24, no later revisions
- lore.kernel.org fetches returned 403; discussion recovered from
  LKML/Openwall/Patchew mirrors. Patch body matches the commit. No
  replies on those archives.
- No reviewer NAK found. Hans Verkuil applied it (CommitDate Mon Jun 29
  2026).

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): To/Cc included Hans Verkuil, Mauro Chehab, Maxime
Coquelin, Alexandre Torgue, `linux-media`, `linux-stm32`, `linux-arm-
kernel`, `lkml`. Right maintainers were on the submission. No extra
Reviewed-by in the committed message.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No `Reported-by` / bugzilla / syzbot. Static/code-correctness
fix, not a user crash report.

**Step 4.4: RELATED PATCHES AND SERIES**

Record: Standalone `[PATCH]`, not a series. Sibling STM32 change
`0c260d3f97e52` is a different RX OOB bug and already has `Cc: stable`.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: No usable stable-list hit for this subject (lore/stable blocked
by anti-bot). UNVERIFIED that nobody previously rejected it for stable.
No evidence of a known NAK.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**

Record: `stm32_cec_adap_log_addr` only. Registered as `.adap_log_addr`
in `stm32_cec_adap_ops`.

**Step 5.2: TRACE CALLERS**

Record (`call_op` in `drivers/media/cec/core/cec-priv.h`):
- `cec_config_log_addr()` in `cec-adap.c` — claim path; error is
  returned to the config thread.
- `cec_adap_unconfigure()` — `WARN_ON(call_op(...,
  CEC_LOG_ADDR_INVALID))`; then core still marks the adapter
  unconfigured.

Called with `adap->lock` held from the CEC kthread / ioctl configuration
path, not IRQ context.

**Step 5.3: TRACE CALLEES**

Record: `regmap_read_poll_timeout`, `regmap_update_bits`. Sleeps up to
~2.1 s. No alloc/new locks.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Userspace CEC ioctls (`CEC_ADAP_S_LOG_ADDRS` / adapter enable-
disable) → CEC core → `adap_log_addr`. Reachable on STM32 HDMI CEC
(`CONFIG_CEC_STM32`, `st,stm32-cec`) without extra privilege beyond
access to the CEC device node. Not a generic syscall bug on x86.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Other platform CEC drivers (tegra, meson) check
`CEC_LOG_ADDR_INVALID` before building a shift mask. Tegra still uses `1
<< logical_addr` only in the else branch. This STM32 driver was the one
evaluating the shift first.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes**, at `v6.18.53` in `stm32_cec_adap_log_addr()`.
Introduced 2017 (shift) / 2019 (ignored poll). Upstream fix
`3bc2e4a26465` is **not** an ancestor of HEAD (expected: it is a later
mainline commit being evaluated). The autosel cherry-pick
`a1157fd7d1e0f` is already on this branch; that is ignored as selection
evidence.

**Step 6.2: BACKPORT COMPLICATIONS**

Record: **Clean apply.** Surrounding function at `v6.18.53` matches the
pre-image exactly. No refactor of this callback on 6.18.y.

**Step 6.3: RELATED FIXES ALREADY HERE**

Record: No earlier timeout-return or shift-guard on this function. RX
OOB fix is independent.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**

Record: `drivers/media/cec/platform/stm32/` — STM32 HDMI CEC.
**PERIPHERAL** (SoC HDMI-CEC), but a supported in-tree driver (`CEC
FRAMEWORK` is Supported; Kconfig `CEC_STM32` depends on `ARCH_STM32 ||
COMPILE_TEST`).

**Step 7.2: SUBSYSTEM ACTIVITY**

Record: File is mature (2017), low churn aside from tree-wide media
cleanups and the recent RX OOB fix. This is an old bug, not a regression
in brand-new code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**

Record: Driver-specific / config-specific: STM32 boards with HDMI CEC
(`st,stm32-cec`). Not universal.

**Step 8.2: TRIGGER CONDITIONS**

Record:
- **Timeout bug:** TXSOM stuck for >2.1 s while claiming or clearing a
  LA. Uncommon, but that is exactly the failure the 2019 wait was meant
  to cover. Unprivileged users with CEC device access can hit the claim
  path.
- **Shift UB:** every unconfigure (`CEC_LOG_ADDR_INVALID` = 0xff), a
  normal path when disabling/reconfiguring CEC.

**Step 8.3: FAILURE MODE SEVERITY**

Record:
- False-success LA update + CFGR write while TXSOM still set: CEC
  misconfiguration / possible controller or bus glitch. **MEDIUM**
  (functional/hardware-constraint), not a kernel oops.
- Shift UB on unconfigure: UBSAN-class undefined behavior; result unused
  on that branch, so not a typical oops. **MEDIUM**.

Not panic/UAF/corruption in the usual sense. Still a real correctness
bug on a user-reachable path.

**Step 8.4: RISK-BENEFIT RATIO**

Record:
- **Benefit:** medium for STM32 CEC users — honest errors, no forbidden
  CFGR write after timeout, no `1 << 0xff`.
- **Risk:** very low — ~16 lines, one function, no API/locking/data-
  structure change.
- Ratio: favorable. The new `WARN_ON` on unconfigure-timeout is the main
  behavioral change and only fires if the wait already failed.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: EVIDENCE**

**FOR:**
- Real bugs: ignored poll error → false success and a CFGR write the
  driver itself documented as illegal during TX; UB shift of `0xff` on
  unconfigure.
- Small, obviously correct, maintainer-acked (Hans Verkuil).
- Buggy code exists in this 6.18.y tree; applies cleanly; no
  prerequisites.
- Matches stable error-handling / UBSAN-shift patterns.

**AGAINST:**
- Peripheral STM32 HDMI CEC, not a core path.
- No user/syzbot report; timeout is rare.
- Failure is not a documented oops/CVE/deadlock.
- Unconfigure timeout can now `WARN_ON` (honest, but user-visible in
  dmesg).

**UNRESOLVED:**
- Full lore thread (403); no public review comments beyond maintainer
  application.
- Stable-list history not searchable here.

**Step 9.2: STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — check existing return;
   maintainer merged it.
2. Fixes a real bug that affects users? **PASS** — false success and
   hardware-forbidden write; UB on unconfigure.
3. Important issue? **PASS** (medium) — not a panic, but incomplete
   timeout handling plus UBSAN-class shift on a normal unconfigure path.
   Driver fixes of this size are in-scope.
4. Small and contained? **PASS** — one function, +11/−5.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — pre-image matches `v6.18.53`.

**Step 9.3: EXCEPTION CATEGORIES**

Record: None (not a device ID, quirk, DT, build, or docs-only change).
Qualifies as a normal small bugfix.

**Step 9.4: DECISION**

Backport. The bugs exist in this 6.18 tree, the patch is surgical, and
the risk is far smaller than leaving a wait whose result is discarded
and a `1 << 0xff` on every unconfigure.

---

### What the commit solves for this tree

On 6.18.53, `stm32_cec_adap_log_addr()` waits for TXSOM then always
programs OAR and returns success. After a 2.1 s timeout that still
writes CFGR, which the 2019 change said must not happen during transmit,
and reports a successful LA update. Separately, unconfigure always
evaluates `(1 << 0xff) << 16` before the invalid-address check. The
patch returns the poll error first and only builds the mask for valid
LAs.

### Risk vs benefit

Benefit is correct CEC address programming and avoidance of a hardware-
illegal register update and a shift UB. Risk is a few lines in one STM32
CEC callback; the only extra symptom is `WARN_ON` if unconfigure hits a
stuck TXSOM.

---

### Verification

- **[Phase 1]** Parsed subject/tags from `git log -1` / `git show` of
  `a1157fd7d1e0f` and upstream `3bc2e4a26465`. No Fixes/Reported-by.
  Hans Verkuil SOB + committer.
- **[Phase 2]** Diff: +11/−5 in `stm32_cec_adap_log_addr`. Pre-image
  confirmed via `git show
  v6.18.53:drivers/media/cec/platform/stm32/stm32-cec.c`.
  `CEC_LOG_ADDR_INVALID` is `0xff`.
- **[Phase 3]** `git blame` on the function: `d69ae57453c80a` (v4.13),
  poll `1a726df6078c2f` (v5.2). `git merge-base --is-ancestor` of both
  vs `v6.18.53` and HEAD: present. No `Fixes:` tag. No follow-ups after
  the candidate on this file.
- **[Phase 3]** `git merge-base --is-ancestor 3bc2e4a26465 HEAD` → not
  in this branch (mainline-only). Local cherry-pick is on autosel;
  ignored as selection evidence.
- **[Phase 4]** `b4 dig -c/-a/-w`: v1-only, msgid
  `20260624144015.63929-1-pengpeng@iscas.ac.cn`, correct maintainers
  CCed. lore.kernel.org 403; LKML/Openwall/Patchew matched the committed
  diff; no NAK found.
- **[Phase 4]** Stable-list search unusable (anti-bot). UNVERIFIED:
  prior stable discussion.
- **[Phase 5]** Callers: `cec_config_log_addr`, `cec_adap_unconfigure`
  in `cec-adap.c`. `call_op` in `cec-priv.h`. Kconfig `CEC_STM32`.
- **[Phase 6]** `git describe HEAD` → `v6.18.53-5049-g0f0bdc2b0dffb`;
  `make kernelversion` → 6.18.53. Buggy code at v6.18.53. Clean pre-
  image.
- **[Phase 7]** Peripheral STM32 CEC; maintainer Hans Verkuil.
- **[Phase 8]** Failure: false success + illegal CFGR write (MEDIUM);
  shift UB on unconfigure (MEDIUM). Risk very low.
- **UNVERIFIED:** live review comments on lore (403); whether UBSAN has
  actually fired on this shift in the field.

**YES**

 drivers/media/cec/platform/stm32/stm32-cec.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
index 8c2fc232202de..29418966a98ef 100644
--- a/drivers/media/cec/platform/stm32/stm32-cec.c
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -194,18 +194,24 @@ static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
 static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
 {
 	struct stm32_cec *cec = adap->priv;
-	u32 oar = (1 << logical_addr) << 16;
 	u32 val;
+	int ret;
 
 	/* Poll every 100µs the register CEC_CR to wait end of transmission */
-	regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
-				 100, CEC_XFER_TIMEOUT_MS * 1000);
+	ret = regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
+				       100, CEC_XFER_TIMEOUT_MS * 1000);
+	if (ret)
+		return ret;
+
 	regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
 
-	if (logical_addr == CEC_LOG_ADDR_INVALID)
+	if (logical_addr == CEC_LOG_ADDR_INVALID) {
 		regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
-	else
+	} else {
+		u32 oar = BIT(logical_addr) << 16;
+
 		regmap_update_bits(cec->regmap, CEC_CFGR, oar, oar);
+	}
 
 	regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Check pm_runtime_resume_and_get() return in probe
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (30 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] media: cec: stm32: return an error when log-address wait times out Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] drm/rockchip: dw_hdmi: Use resume_early pm ops for system suspend Sasha Levin
                   ` (16 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Mukesh Ojha, Konrad Dybcio, Will Deacon, Sasha Levin, robin.clark,
	joro, iommu, linux-arm-msm, linux-arm-kernel, linux-kernel

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit e910315ae08a23bc953daed10b1c518abac1df49 ]

The SMMU_INTR_SEL_NS register write in qcom_iommu_device_probe() uses
pm_runtime_get_sync() without checking the return value. If runtime
resume fails the subsequent writel_relaxed() would access hardware with
clocks potentially disabled.

Switch to pm_runtime_resume_and_get() which handles the usage-count
cleanup on failure, check the return value, and unwind the already
registered iommu device on error.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have the tree version, the probe path, series context, and review
thread. Compiling the nine-phase analysis and verdict next.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[iommu/qcom]** **[Check]** Check `pm_runtime_resume_and_get()`
return in probe. “Check” here is a missing-error-handling fix, not a
feature.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Reviewed-by:** Konrad Dybcio \<konrad.dybcio@oss.qualcomm.com\>
  (Qualcomm reviewer)
- **Signed-off-by:** Mukesh Ojha \<mukesh.ojha@oss.qualcomm.com\>
  (author)
- **Signed-off-by:** Will Deacon \<will@kernel.org\> (IOMMU/SMMU
  maintainer who applied it)
- **No Fixes:** tag (expected for this review pipeline)
- **No Cc: stable** (expected)
- **No Reported-by / Tested-by / Link / Acked-by**
- Ignore any pipeline “Signed-off-by: Sasha Levin” / “[Upstream commit
  …]” markers (none in the real commit)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `qcom_iommu_device_probe()` does `pm_runtime_get_sync()` then
  `writel_relaxed()` to `SMMU_INTR_SEL_NS` without checking the PM call.
- **Symptom:** If runtime resume fails, MMIO is written with clocks
  possibly off. On Qualcomm that can hang the interconnect / SError, and
  probe still returns success so interrupt routing may be wrong.
- **Root cause:** ignored `pm_runtime_get_sync()` return; that API also
  leaves the usage count up on failure (the new API drops it).
- **Fix:** `pm_runtime_resume_and_get()`, check `ret`, unwind
  `iommu_device_unregister` + existing sysfs remove.
- **Version info:** none in the message. Code dates to the original
  driver (v4.14).

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not disguised. Explicit error-path / unclocked-access fix. The
“usage-count cleanup” wording is slightly overstated at this site
because the old code always called `pm_runtime_put_sync()` after the
write; the real bugs are the unclocked `writel` and probe succeeding
after a failed resume.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/iommu/arm/arm-smmu/qcom_iommu.c` (+5 / −1)
- Function: `qcom_iommu_device_probe()`
- Scope: single-file surgical probe error path

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record: Before (only when `qcom_iommu->local_base` is set):
`pm_runtime_get_sync` → always `writel_relaxed(0xffffffff, local_base +
SMMU_INTR_SEL_NS)` → `pm_runtime_put_sync` → return 0. After:
`pm_runtime_resume_and_get`; on failure `goto err_iommu_unregister`
(unregister IOMMU, remove sysfs, return error); on success same write +
put as before.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** (a) error-path unwind + (g) missing return check, which
  prevents unclocked MMIO.
- **Mechanism:** `qcom_iommu_resume()` enables iface/bus/tbu clocks via
  `clk_bulk_prepare_enable()`. If that (or SCM restore) fails, the old
  path still wrote `SMMU_INTR_SEL_NS`. Switch to
  `pm_runtime_resume_and_get()` is required: `pm_runtime_get_sync()` can
  return `1` (already active), so `if (ret)` on get_sync would mis-
  handle success.

**Step 2.4: ASSESS THE FIX QUALITY**

Record: Minimal and correct. `pm_runtime_resume_and_get()` returns 0 or
negative (`include/linux/pm_runtime.h`). Unwind matches
`qcom_iommu_device_remove()`. Regression risk is low: only the RPM-
failure path starts failing probe instead of succeeding after a possibly
unclocked write. If clocks cannot be enabled, failing probe is the right
outcome.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record: The `if (qcom_iommu->local_base)` write was added in
**0ae349a0f33fb0** (“iommu/qcom: Add qcom_iommu”, Rob Clark,
2017-08-09), first in **v4.14-rc1**. Present in this tree (`git merge-
base --is-ancestor 0ae349a0f33fb0 HEAD`). Long-lived bug, not new code.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No Fixes: tag. Buggy code is the original 2017 driver, not a
recent regression.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record: Same-day IOMMU pull (Will Deacon, 2026-07-22):
- `c579f18e79599` — adds `err_sysfs_remove` (**soft prerequisite** for
  the new goto)
- `bf69e515b1802` — `devm_pm_runtime_enable()` (series 2/6; changes
  nearby error labels)
- **`e910315ae08a2`** — this commit (series 3/6)
- Later 4/6–6/6 are other bugs in the same file, not needed for this
  hunk

Standalone for the probe RPM check, but the hunk assumes
`err_sysfs_remove` exists. That label is in this tree.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Mukesh Ojha (Qualcomm) sent the “iommu/qcom: Misc Fixes” series.
Not the file’s listed maintainer (Rob Clark); Konrad reviewed, Will
applied. Related author commits on this file are the rest of that
series.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: Needs `err_sysfs_remove` from `c579f18e79599` (cover letter:
series sits on Haoxiang Li’s sysfs cleanup).
`pm_runtime_resume_and_get()` exists in this tree. Can apply standalone
**on this checkout**. Does not need 4/6–6/6.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- **b4 dig:** v2 3/6, https://patch.msgid.link/20260717144608.3216274-4-
  mukesh.ojha@oss.qualcomm.com
- **Revisions:** v1 3/8 (2026-06-23) → v2 3/6 (2026-07-17). Same hunk;
  v1 still had `err_pm_disable` (removed by 2/6).
- Konrad R-b on v1 with no requested changes: Message-ID
  `f636b144-807f-4a10-bf44-d06b169fce21@oss.qualcomm.com`
- Will applied the whole v2 series 2026-07-22; no NAKs
- No reviewer asked for Cc: stable

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record: To/Cc included Rob Clark, Will Deacon, Joerg Roedel, Robin
Murphy, `iommu@lists.linux.dev`, `linux-arm-msm`. Konrad R-b; Will
merged.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No Reported-by, syzbot, or bugzilla. Author analysis of the
error path, not a user crash report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Cover: “[PATCH v2 0/6] iommu/qcom: Misc Fixes”. Independent
fixes in one file. This patch does not need 4/6 (pgtbl leak), 5/6 (mutex
publish), or 6/6 (ctx_probe clocks). 2/6 only shifts nearby labels.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: gnuweeb `/stable/?q=qcom_iommu+pm_runtime_resume_and_get` had no
discussion of this fix. Not previously rejected for stable.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**

Record: `qcom_iommu_device_probe()`; new label `err_iommu_unregister`
calling `iommu_device_unregister()`.

**Step 5.2: TRACE CALLERS**

Record: `.probe = qcom_iommu_device_probe` on `qcom-iommu`. Triggered by
DT `qcom,msm-iommu-v1` / `v2` during boot (or bind). Not a syscall.
`local_base` is optional (first MEM resource); the RPM get/write runs
only if that resource exists.

**Step 5.3: TRACE CALLEES**

Record: `pm_runtime_resume_and_get` → `qcom_iommu_resume` →
`clk_bulk_prepare_enable` and possibly `qcom_scm_restore_sec_cfg`. Then
`writel_relaxed` to `SMMU_INTR_SEL_NS` (0x2000), `pm_runtime_put_sync`.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Boot/device probe on MSM8916-class SoCs. Unprivileged users can
rebind if they can unbind the driver; typical trigger is boot. Path is
real on those boards.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Same file still uses unchecked `pm_runtime_get_sync` in
`domain_free`, `attach_dev`, `identity_attach`, `unmap`,
`flush_iotlb_all`. Comments there already warn about unclocked TLB
access. This commit only fixes probe. Sibling 6/6 adds a checked resume
around ctx-bank FSR access.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: Local tree is **v7.3-rc4** (`git describe HEAD` =
`v7.3-rc4-27-gf0100363d8c37`, `VERSION=7 PATCHLEVEL=3 SUBLEVEL=0
EXTRAVERSION=-rc4`). Driver is present. The unclocked-write pattern
existed here from v4.14 until `e910315ae08a2`. HEAD already has the
fixed form in `qcom_iommu_device_probe()` (lines 866–880). Evaluation is
technical merit for this tree’s code, not “already landed.”

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** on this tree: `err_sysfs_remove` and
`devm_pm_runtime_enable` are present. Hunk matches current/pre-fix
context.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No alternate fix for this probe RPM check. Sysfs unwind
(`c579f18e79599`) is here and is what this goto chains into.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **IOMMU / Qualcomm legacy SMMU** (`drivers/iommu/arm/arm-
smmu/qcom_iommu.c`). **IMPORTANT** for MSM8916/8917/8937/8939/8953/8976
(DT still uses `qcom,msm-iommu-v1`). Not core MM/VFS; IOMMU failures
break DMA/display/modem on those SoCs.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Mature “legacy qcom_iommu” (author’s words). Occasional
correctness fixes in 2026, not heavy churn. Long-lived bug, more
relevant for stable.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver/platform-specific**, `CONFIG_QCOM_IOMMU`, older
Qualcomm ARM64 boards listed above. Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record: Probe, and only if `local_base` is mapped **and** runtime resume
fails (`clk_bulk_prepare_enable` or SCM restore). Uncommon on healthy
hardware; realistic on clock/GDSC/SCM failure. Not a normal userspace
trigger.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: Unclocked MMIO → possible **bus hang / SError** (**HIGH** if it
fires). Otherwise probe succeeds with `SMMU_INTR_SEL_NS` not programmed
(**MEDIUM** functional). Trigger rarity → overall **MEDIUM–HIGH**, still
a real hang class, not cosmetic.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** Avoid hang/abort and false-successful probe when clocks
  cannot come up; fail cleanly and unwind registration.
- **Risk:** Very low (6-line error path, reviewed, standard API).
- **Ratio:** Favorable.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real unclocked MMIO on a documented-sensitive Qualcomm path
- Small (+5/−1), obviously correct
- `pm_runtime_resume_and_get` is the right API (get_sync’s `1` is
  success)
- Konrad R-b, Will merged; no NAKs
- Driver in this tree since v4.14; DT still ships for several SoCs
- Same-file comments treat unclocked access as a real hang risk
- Prerequisites (`err_sysfs_remove`, `pm_runtime_resume_and_get`) are in
  this tree
- Matches stable’s “oops, hang, … or some ‘oh, that’s not good’ issue”

**AGAINST:**
- No user/syzbot report; error path is uncommon
- Series patch 3/6 (but functionally independent)
- Other `get_sync` sites in the file remain unchecked
- Usage-count leak at this site was already balanced by `put_sync`

**UNRESOLVED:** lore.kernel.org HTTP 403; discussion recovered via `b4
dig` mbox, gnuweeb, and openwall. No evidence of a field crash, only
code-path analysis.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — API contract matches;
   maintainer applied after R-b
2. Fixes a real bug that affects users? **PASS** — unclocked write and
   successful probe after failed resume on shipped MSM8916-class IOMMU
3. Important issue? **PASS** — hang/SError class; trigger is rare but
   severity is not “trivial”
4. Small and contained? **PASS** — 6 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — code and labels exist here

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: None (not a device ID, quirk table, DT, build, or doc fix).
Qualifies as a normal small bugfix.

**Step 9.4: MAKE YOUR DECISION**

This is a small, reviewed probe-path fix that stops a `writel` to SMMU
MMIO when runtime resume (clocks) has failed, and fails probe instead of
continuing. That is a real stability bug on a still-used Qualcomm IOMMU,
the change is contained, and this checkout has the driver plus the sysfs
unwind label the hunk uses. Benefit outweighs risk.

---

### What the commit solves for this tree

`qcom_iommu_device_probe()` programmed `SMMU_INTR_SEL_NS` after
`pm_runtime_get_sync()` with no check. Resume enables the IOMMU clocks;
on failure the write can hit unclocked hardware (hang/SError) and probe
still returned 0. The fix uses `pm_runtime_resume_and_get()`, returns
the error, and unregisters the IOMMU device.

It meets stable rules: obviously correct, real hang-class bug, ~6 lines,
no new API. Risk is confined to the already-broken clock-failure path.

---

### Verification

- **[Phase 1]** Parsed `e910315ae08a2`: R-b Konrad Dybcio; SOB Mukesh
  Ojha, Will Deacon; no Fixes/Reported-by/stable Cc
- **[Phase 2]** Diff: +5/−1 in `qcom_iommu_device_probe()`;
  `pm_runtime_get_sync` → checked `pm_runtime_resume_and_get` +
  `err_iommu_unregister`
- **[Phase 2]** Confirmed `pm_runtime_resume_and_get()` returns 0 or
  negative (`include/linux/pm_runtime.h`); `get_sync` may return 1
- **[Phase 2]** Confirmed resume path: `qcom_iommu_resume()` →
  `clk_bulk_prepare_enable()`
- **[Phase 3]** Blame: write from `0ae349a0f33fb0` (v4.14-rc1); `merge-
  base --is-ancestor` true
- **[Phase 3]** `c579f18e79599` and `bf69e515b1802` are ancestors of
  HEAD
- **[Phase 4]** `b4 dig -c e910315ae08a2`: v2 3/6 of “Misc Fixes”; v1
  3/8 same hunk
- **[Phase 4]** `b4 dig -a/-w/-m`: Konrad R-b, Will applied 1/6–6/6;
  recipients were IOMMU/QCOM lists; no NAK
- **[Phase 4]** Stable-list search: no prior discussion of this fix
- **[Phase 5]** Probe is platform driver for `qcom,msm-iommu-v1/v2`; DT
  hits in msm8916/8917/8937/8939/8953/8976
- **[Phase 6]** `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
  Makefile 7.3.0-rc4; driver present; hunk matches
- **[Phase 8]** Failure mode: unclocked MMIO hang/SError if RPM resume
  fails at probe; severity HIGH if hit, trigger uncommon
- **UNVERIFIED:** lore.kernel.org 403 (mbox/mirrors used instead); no
  field reproducer found

The fix is small, surgical, and meets the stable criteria for this tree.

**YES**

 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 9bee85259c69e..fbe4bd3ec0c42 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -863,13 +863,17 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 	}
 
 	if (qcom_iommu->local_base) {
-		pm_runtime_get_sync(dev);
+		ret = pm_runtime_resume_and_get(dev);
+		if (ret)
+			goto err_iommu_unregister;
 		writel_relaxed(0xffffffff, qcom_iommu->local_base + SMMU_INTR_SEL_NS);
 		pm_runtime_put_sync(dev);
 	}
 
 	return 0;
 
+err_iommu_unregister:
+	iommu_device_unregister(&qcom_iommu->iommu);
 err_sysfs_remove:
 	iommu_device_sysfs_remove(&qcom_iommu->iommu);
 err_pm_disable:
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] drm/rockchip: dw_hdmi: Use resume_early pm ops for system suspend
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (31 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] rtc: brcmstb-waketimer: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (15 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Jonas Karlman, Heiko Stuebner, Sasha Levin, hjc, andyshrk,
	maarten.lankhorst, mripard, tzimmermann, airlied, simona,
	dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel

From: Jonas Karlman <jonas@kwiboo.se>

[ Upstream commit af3a9eadc11896f6677bcb7102bfb7c84be48d2d ]

rockchip_drm_sys_resume()/drm_mode_config_helper_resume() is called
before the resume pm ops of dw-hdmi. This result in an atomic_enable()
before dw_hdmi_rockchip_resume()/dw_hdmi_resume() is called.

Resume (without changes):
- rockchip_drm_sys_resume()
  - drm_mode_config_helper_resume()
    - atomic_enable()
- dw_hdmi_rockchip_resume()
  - dw_hdmi_resume()
    - dw_hdmi_init_hw()

Change to use resume_early pm ops for system suspend to ensure pm ops
for dw-hdmi is run before rockchip-drm pm ops. Also fix a possible NULL
pointer dereference timing issue while at it.

Resume (with changes):
- dw_hdmi_rockchip_resume_early()
  - dw_hdmi_resume()
    - dw_hdmi_init_hw()
- rockchip_drm_sys_resume()
  - drm_mode_config_helper_resume()
    - atomic_enable()

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Tested-by: Heiko Stuebner <heiko@sntech.de> #rk3328
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260518193748.2482823-12-jonas@kwiboo.se
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have the 6.18.y picture: the buggy resume path is in v6.18.53, the
patch is self-contained, and the DSI sibling already uses the same
late/early PM ordering. Compiling the full nine-phase verdict next.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [drm/rockchip: dw_hdmi] [Use] [switch HDMI system-resume
callback to resume_early so dw-hdmi re-inits before rockchip-drm
atomic_enable]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Tested-by: Heiko Stuebner <heiko@sntech.de> #rk3328 (Rockchip DRM
  maintainer; hardware-tested)
- Signed-off-by: Jonas Karlman <jonas@kwiboo.se> (author)
- Signed-off-by: Heiko Stuebner <heiko@sntech.de> (subsystem maintainer
  applied it)
- Link:
  https://patch.msgid.link/20260518193748.2482823-12-jonas@kwiboo.se
- No Fixes:, Reported-by, Reviewed-by, Acked-by, or Cc: stable (absence
  expected)
- Ignore pipeline tags: [Upstream commit
  af3a9eadc11896f6677bcb7102bfb7c84be48d2d], Signed-off-by: Sasha Levin

Notable: maintainer Tested-by on real RK3328 hardware.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: on system resume, `rockchip_drm_sys_resume()` →
  `drm_mode_config_helper_resume()` → atomic enable runs before
  `dw_hdmi_resume()` → `dw_hdmi_init_hw()`.
- Symptom: HDMI hardware (DDC I2C, HPD, interrupt mutes) is restored
  after DRM has already tried to re-enable the display pipeline.
- Secondary: “possible NULL pointer dereference timing issue” — resume
  can run with NULL drvdata.
- No stack trace, syzbot report, or CVE. Author gave simulated-suspend
  (`pm_test`) and `rtcwake` test steps in the mailing-list version.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not disguised. It is an explicit PM-ordering fix plus a NULL
check. It was patch 11/11 of a series titled “Misc cleanup and propagate
bus format”, and was added in v2; the other patches are unrelated
cleanups/prep. This hunk is a standalone bug fix.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c` (+4/-3, 7 lines)
- Functions: `dw_hdmi_rockchip_resume` renamed to
  `dw_hdmi_rockchip_resume_early`; `dw_hdmi_rockchip_pm` table
- Scope: single-file surgical PM-ops change

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: `.resume` (normal phase) unconditionally calls
  `dw_hdmi_resume(hdmi->hdmi)`.
- After: `.resume_early` (early phase) calls it only if
  `dev_get_drvdata()` is non-NULL.
- `SET_SYSTEM_SLEEP_PM_OPS(NULL, resume)` →
  `SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, resume_early)`.
- Suspend remains NULL. Hibernation thaw/restore move from thaw/restore
  to thaw_early/restore_early, matching the same ordering intent.

Resume phase order is resume_noirq → resume_early → resume. HDMI
therefore always re-inits before rockchip-drm’s `.resume`.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- Primary: logic/correctness + hardware resume ordering. Sibling `dw-
  mipi-dsi-rockchip.c` already uses `SET_LATE_SYSTEM_SLEEP_PM_OPS` with
  the comment that it must run before `rockchip_drm_drv` re-enables
  panels.
- Secondary: memory safety — NULL check before `hdmi->hdmi` dereference
  when the platform device has probed (`component_add`) but not bound
  (`platform_set_drvdata` is in bind, not probe).

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: Linux PM runs all `resume_early` callbacks before
  any `.resume`. That is the standard way to order a component ahead of
  the DRM master.
- Minimal; no API or data-structure change.
- Regression risk low: same pattern as the in-tree DSI sibling; only
  resume is registered; `dw_hdmi_init_hw()` only re-inits mutes, DDC
  I2C, and HPD.
- NULL check does not cover `hdmi->hdmi` being `ERR_PTR` after a failed
  bind; that is a leftover hole, not a regression from this patch.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Buggy resume path introduced by `27c9130baef543` (“drm/rockchip:
  dw_hdmi: Handle suspend/resume”, Douglas Anderson, 2019-06-04), first
  in v5.3-rc1.
- That commit is an ancestor of this tree.
- That commit already documented the failure on rk3288 Chromebooks (HDMI
  HPD and DDC I2C stop working after suspend) and that Chrome OS 3.14
  used late/early PM ops because VOP sometimes resumed before dw-hdmi.
  Mainline used normal `.resume` because the author could not reproduce
  it then. This patch is the proper late/early fix for that known issue.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. The introducing commit is `27c9130baef543`,
present here.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Only two resume-related commits on this file: 27c9130baef543 (add
  resume) and this one.
- Recent 6.18.y file history is unrelated (SCLIN mask, FIELD_PREP,
  whitespace).
- Series-local neighbors (output_port, whitespace, empty helpers) are
  not functional prerequisites of this hunk.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Jonas Karlman is a regular Rockchip HDMI/dw-hdmi contributor.
Heiko Stuebner (maintainer) applied the series and tested it on rk3328.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record:
- Series v2 11/11; cover letter says patches 1–10 are cleanup / YCbCr-
  Deep Color prep. Patch 11 only changes PM ops.
- `SET_LATE_SYSTEM_SLEEP_PM_OPS` exists in this tree’s
  `include/linux/pm.h`.
- `dw_hdmi_resume()` exists in `drivers/gpu/drm/bridge/synopsys/dw-
  hdmi.c`.
- Applies standalone. No missing helpers.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- b4 dig:
  https://patch.msgid.link/20260518193748.2482823-12-jonas@kwiboo.se
- v1 (2026-05-10): 10 patches, no resume_early change
- v2 (2026-05-18): this patch added (“v2: New patch”)
- Applied by Heiko 2026-06-02 as
  `af3a9eadc11896f6677bcb7102bfb7c84be48d2d`
- No NAK. No reviewer asked for further revisions of this hunk.
- Author included CONFIG_PM_DEBUG / rtcwake test instructions and noted
  a separate RK356x EHCI/OHCI clock issue, not this bug.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: Recipients included Heiko Stuebner, Sandy Huang, Andy Yan, DRM
maintainers, dri-devel, linux-rockchip. Heiko tested and applied. No
other Acked-by/Reviewed-by on this patch.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla link. Real-world grounding is the 2019
Chromebook report in 27c9130baef543 plus Heiko’s rk3328 Tested-by.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone vs the rest of the v2 series. DSI sibling
`e584cdc154993` (“drm/rockchip: dsi: Reconfigure hardware on resume()”)
used the same late PM ops and had Cc: stable.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: UNVERIFIED. lore.kernel.org/stable returned an Anubis bot-check
page; WebFetch to lore returned 403.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `dw_hdmi_rockchip_resume_early` (was `dw_hdmi_rockchip_resume`);
`dw_hdmi_rockchip_pm`.

Step 5.2: TRACE CALLERS
Record: Invoked by the PM core as `dev_pm_ops.resume_early` on the
`dwhdmi-rockchip` platform driver. Triggered by system suspend/resume
(and freeze/thaw/restore via LATE_SYSTEM_SLEEP_PM_OPS). Not a syscall
hot path; it is the Chromebook/SBC sleep path.

Step 5.3: TRACE CALLEES
Record: `dev_get_drvdata` → `dw_hdmi_resume` → `dw_hdmi_init_hw` →
`initialize_hdmi_ih_mutes`, `dw_hdmi_i2c_init`, optional
`phy.ops->setup_hpd`.

Step 5.4: FOLLOW THE CALL CHAIN
Record:
- Userspace: `echo mem > /sys/power/state` / rtcwake / systemd suspend.
- DRM side: `rockchip_drm_sys_resume` → `drm_mode_config_helper_resume`
  → `drm_atomic_helper_resume` (atomic commit / enable).
- HDMI platform device is a component, not a child of the DRM device;
  sibling `.resume` order is not guaranteed. `platform_set_drvdata` is
  in `dw_hdmi_rockchip_bind`, while probe only does `component_add`, so
  resume-before-bind can see NULL drvdata.
- Reachable on any Rockchip board with this HDMI IP and CONFIG_PM_SLEEP
  (RK3288/RK3328/RK3399/RK3568, including Chromebooks).

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record:
- `dw-mipi-dsi-rockchip.c` already uses
  `SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_mipi_dsi_rockchip_resume)` in
  this tree for the same reason.
- `dw_hdmi_qp-rockchip.c` still uses `SET_SYSTEM_SLEEP_PM_OPS`
  (different HDMI QP IP, not this patch).
- imx8mp and meson dw-hdmi glue still use normal SYSTEM_SLEEP PM ops.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- Local tree: `git describe HEAD` = v6.18.53-5049-g0f0bdc2b0dffb; `make
  kernelversion` = 6.18.53 (6.18.y).
- v6.18.53 still has:
  `SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume)`
  and `dw_hdmi_resume(hdmi->hdmi)` with no NULL check
  at `drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c`.
- Bug present since v5.3 (2019), long before 6.18 branched.
- Upstream commit `af3a9eadc11896` is not an ancestor of HEAD (`git
  merge-base --is-ancestor` failed); this is a backport candidate, not
  already in 6.18.y proper.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. The resume function in v6.18.53 is identical to the
parent of this change. `SET_LATE_SYSTEM_SLEEP_PM_OPS` and
`dw_hdmi_resume()` already exist here. Surrounding unbind/bridge-ref
changes from later series patches are not required.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: No other resume-ordering fix on this file. DSI already has the
analogous LATE PM ops. No earlier version of this HDMI fix in 6.18.53.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: DRM Rockchip HDMI glue (`drivers/gpu/drm/rockchip/`). IMPORTANT
(common SoC display, not core mm/fs). Affects
RK3288/RK3328/RK3399/RK356x HDMI (Chromebooks, SBCs, TV boxes).

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver (HDMI glue since ~2015). Resume path untouched
from 2019 until this patch. Low churn on the PM ops themselves.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific / platform-specific. Users of Rockchip dw-hdmi
who suspend the system. CONFIG_PM_SLEEP. Not universal, but a well-used
platform class in Android, Chromebook, and ARM SBCs.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: system suspend/resume with this HDMI driver bound (and the
  NULL path if probed but unbound).
- Common on laptops/Chromebooks; less so on always-on appliances.
- Unprivileged users typically cannot suspend; the HPD/I2C break is
  still a real admin/user-visible failure after lid-close/sleep.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- Primary: HDMI HPD and DDC I2C not restored before DRM atomic enable →
  hotplug/EDID/output broken after resume. HIGH for affected hardware
  (display not coming back is a serious functional bug), not a kernel
  panic.
- Secondary: NULL deref if resume runs before bind → oops. Less common.
  HIGH if hit, MEDIUM likelihood.
- Overall: HIGH (suspend/resume display breakage on real hardware).

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: high for Rockchip HDMI suspend users; restores the ordering
  Chrome OS already needed.
- Risk: very low (7 lines, established LATE PM pattern already in the
  same DRM driver).
- Ratio: favor backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real resume-ordering bug: DRM atomic enable before
  `dw_hdmi_init_hw()`.
- User-visible: HDMI HPD/DDC broken after sleep (documented on rk3288
  Chromebooks in 2019; re-tested on rk3328 in 2026).
- Same fix already used by dw-mipi-dsi-rockchip in this tree, and that
  DSI change went to stable with Cc: stable.
- Possible NULL deref on resume before bind.
- 7-line surgical change; applies cleanly to v6.18.53.
- Maintainer Tested-by and Signed-off-by.
- Buggy code has been in this tree since v5.3; no missing prerequisites.

AGAINST:
- No Fixes:/Cc: stable (expected for this pipeline; not a negative).
- Buried as 11/11 in a cleanup series (but the hunk is independent and
  was added specifically in v2).
- Not a panic/corruption/CVE; display-after-suspend rather than a crash.
- No extra Reviewed-by besides maintainer apply/test.
- UNVERIFIED whether stable@ already discussed rejecting it.

UNRESOLVED:
- lore.kernel.org/stable search blocked (Anubis/403).
- Incomplete NULL check if bind failed and left `hdmi->hdmi` as ERR_PTR
  (pre-existing).

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — PM phase ordering is well-
   defined; Heiko tested on rk3328.
2. Fixes a real bug that affects users? PASS — HDMI not correctly re-
   inited before DRM resume; Chromebook-class hardware.
3. Important issue (crash, security, corruption, deadlock)? PASS —
   suspend/resume display breakage plus a possible oops; hardware resume
   workaround, same class as the DSI stable fix.
4. Small and contained? PASS — 7 lines, one file.
5. No new features or APIs? PASS.
6. Can apply to the local tree? PASS — v6.18.53 has the old resume
   function and the LATE PM macro.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Hardware suspend/resume workaround on an existing driver (quirk-
class). Not a new driver, ID, or API.

Step 9.4: MAKE YOUR DECISION
This belongs on 6.18.y. The buggy `.resume` path is in this checkout,
the switch to `resume_early` is the same proven pattern as the in-tree
DSI sibling, and the patch is tiny with maintainer hardware testing.

What it solves for stable users: after system sleep on Rockchip dw-hdmi
boards, DRM can re-enable the pipeline before HDMI DDC/HPD/init, so
hotplug and HDMI output fail. Moving the callback to `resume_early`
forces `dw_hdmi_init_hw()` first, and skips a NULL drvdata deref if the
component never bound.

Risk is low; benefit is a real resume fix on shipping SoCs. No series
dependencies are required for this hunk.

Verification:
- [Phase 1] Parsed tags: Tested-by Heiko (rk3328), SOB Jonas + Heiko,
  Link msgid ...-12; no Fixes/Reported-by/Cc:stable
- [Phase 1] Cover letter via b4 mbox: patch 11/11 of v2 “Misc cleanup”;
  “v2: New patch”; Heiko “Series: Tested-by” and Applied
- [Phase 2] Diff: rename resume→resume_early, add `if (hdmi)`,
  SET_SYSTEM_SLEEP→SET_LATE_SYSTEM_SLEEP; +4/-3
- [Phase 2] Confirmed LATE_SYSTEM_SLEEP_PM_OPS maps resume_fn to
  `.resume_early` in include/linux/pm.h:321-327,350-351
- [Phase 2] Confirmed rockchip_drm_drv.c:260-262 still uses
  SET_SYSTEM_SLEEP_PM_OPS for sys_resume
- [Phase 2] drm_mode_config_helper_resume() calls
  drm_atomic_helper_resume() (drm_modeset_helper.c:250)
- [Phase 3] git blame parent: resume added in 27c9130baef543 (Douglas
  Anderson, 2019)
- [Phase 3] git show 27c9130baef543: documented Chromebook HPD/I2C break
  and Chrome OS late/early PM ops
- [Phase 3] git describe --contains 27c9130baef543 → v5.3-rc1; git
  merge-base --is-ancestor 27c9130baef543 HEAD → yes
- [Phase 3] git log --oneline --grep resume_early --
  drivers/gpu/drm/rockchip/ → only this commit
- [Phase 4] b4 dig -c af3a9eadc11896: lore thread found; v1 had no this
  patch; v2 added it; applied as af3a9eadc11896
- [Phase 4] b4 dig -a: v1 2026-05-10, v2 2026-05-18
- [Phase 4] b4 dig -w: Heiko, dri-devel, linux-rockchip CC’d
- [Phase 4] b4 dig -m /tmp/thread.mbox: no NAKs; Heiko tested+applied
- [Phase 4] lore.kernel.org WebFetch 403; stable search Anubis-blocked →
  UNVERIFIED stable@ discussion
- [Phase 5] Callers: PM core resume_early on dwhdmi-rockchip; callees
  dw_hdmi_resume→dw_hdmi_init_hw
- [Phase 5] platform_set_drvdata in bind (line 580), probe only
  component_add — NULL drvdata on unbound resume is real
- [Phase 5] Sibling dw-mipi-dsi-rockchip.c:1346 already
  SET_LATE_SYSTEM_SLEEP_PM_OPS in this tree; introduced by e584cdc154993
  with Cc: stable
- [Phase 6] git describe HEAD: v6.18.53-5049-g0f0bdc2b0dffb; make
  kernelversion 6.18.53
- [Phase 6] git show v6.18.53:dw_hdmi-rockchip.c has
  SET_SYSTEM_SLEEP_PM_OPS + unchecked dw_hdmi_resume
- [Phase 6] git merge-base --is-ancestor af3a9eadc11896 HEAD → no (not
  in 6.18.y proper)
- [Phase 6] Resume hunk in v6.18.53 identical to parent of this change;
  SET_LATE and dw_hdmi_resume exist in v6.18.53
- [Phase 8] Failure mode: HDMI broken after suspend (HIGH); possible
  NULL oops (HIGH if hit)
- UNVERIFIED: whether stable@ previously rejected this patch (lore
  blocked)

**YES**

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 727cdf768161a..ff34aeef3a6ff 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -635,17 +635,18 @@ static void dw_hdmi_rockchip_remove(struct platform_device *pdev)
 	component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
 }
 
-static int __maybe_unused dw_hdmi_rockchip_resume(struct device *dev)
+static int __maybe_unused dw_hdmi_rockchip_resume_early(struct device *dev)
 {
 	struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
 
-	dw_hdmi_resume(hdmi->hdmi);
+	if (hdmi)
+		dw_hdmi_resume(hdmi->hdmi);
 
 	return 0;
 }
 
 static const struct dev_pm_ops dw_hdmi_rockchip_pm = {
-	SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume_early)
 };
 
 struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] rtc: brcmstb-waketimer: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (32 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] drm/rockchip: dw_hdmi: Use resume_early pm ops for system suspend Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] net: stmmac: use dma_addr_t for DMA addresses Sasha Levin
                   ` (14 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Alexandre Belloni, Sasha Levin, florian.fainelli,
	linux-rtc, linux-arm-kernel, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 402c89d28fecd28652a4bfe997f08f6544836381 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260704121734.54941-1-pengpeng@iscas.ac.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.12.111** (`pending-6.12`). The one-line OF alias
publication is missing here, the match table is present, and the
original mailed hunk applies cleanly.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[rtc / brcmstb-waketimer] [add] [publish missing OF
MODULE_DEVICE_TABLE so the module can autoload]**

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- **Link:**
  https://patch.msgid.link/20260704121734.54941-1-pengpeng@iscas.ac.cn
- **Signed-off-by:** Pengpeng Hou (author)
- **Signed-off-by:** Alexandre Belloni (RTC maintainer; applied)
- **No Fixes:** (expected for this review)
- **No Cc: stable** (expected)
- **No Reported-by / Tested-by / Reviewed-by / Acked-by / syzbot**
- Pipeline markers (`[Upstream commit ...]`, Sasha Levin SOB) ignored
  per instructions

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** OF match table is wired to `.of_match_table` but not exported
  with `MODULE_DEVICE_TABLE()`, so modpost never emits
  `of:N*T*Cbrcm,brcmstb-waketimer` aliases.
- **Symptom:** When `CONFIG_RTC_DRV_BRCMSTB=m`, udev/kmod cannot
  autoload `rtc-brcmstb-waketimer.ko` from the DT compatible string. The
  wake-timer/RTC does not bind unless the module is loaded by hand.
- **Version info:** none in the message. Driver has been in tree since
  v4.13.
- **Root cause (author):** missing module-alias publication, evidenced
  by the driver-owned table and its use by the platform driver.
  Explicitly a source-level finding, not a live hardware repro.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: **Not disguised.** It is a real autoload bug, same class as
adding/publishing a device ID. Not style-only.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/rtc/rtc-brcmstb-waketimer.c` (+1 / −0)
- **Function/site:** after `brcmstb_waketmr_of_match[]` (not inside a
  function)
- **Scope:** single-file, one-line surgical change
- **Upstream SHA (verified):**
  `402c89d28fecd28652a4bfe997f08f6544836381`

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** table exists and is assigned to `.of_match_table` via
  `of_match_ptr()`. Built-in matching still works. Modular autoload does
  not, because file2alias never sees the table.
- **After:** `MODULE_DEVICE_TABLE(of, brcmstb_waketmr_of_match)` creates
  `__mod_of__brcmstb_waketmr_of_match_device_table` as an alias when
  `MODULE` is set (`include/linux/module.h`). `scripts/mod/file2alias.c`
  `do_of_entry_multi()` then emits `MODULE_ALIAS("of:N*T*Cbrcm,brcmstb-
  waketimer")`.
- **Path affected:** module install / depmod / udev autoload only.
  Probe, PM, and built-in bind paths are unchanged. When `!MODULE`, the
  macro is empty.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **[Hardware enablement / missing device ID publication]**
- Category (h): OF alias not published, so modular bind fails.
- Not UAF, leak, race, NULL deref, or crash.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- **Quality:** obviously correct; this is the standard pattern (dozens
  of RTC drivers already have `MODULE_DEVICE_TABLE(of, ...)` in this
  tree).
- **Regression risk:** very low. Compile-time alias only.
  `__maybe_unused` on the table remains valid: built-in + `!CONFIG_OF`
  still has no C reference; as a module the alias references the table,
  which is intended.
- **No API, locking, or data-structure changes.**

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Match table and `.of_match_table` introduced in **`c4f07ecee22ec7`**
  (“rtc: brcmstb-waketimer: Add Broadcom STB wake-timer”, Brian Norris,
  2017) — first appears **v4.13-rc1**. Present in this tree (`git merge-
  base --is-ancestor` succeeded).
- `__maybe_unused` added in **`ae1247f79ddf8`** (v5.12 era) for
  `!CONFIG_OF` compile-test. That did not add `MODULE_DEVICE_TABLE`.
- Bug has been present for the entire life of the driver.

Step 3.2: FOLLOW THE FIXES: TAG
Record: **No Fixes: tag.** The introducing commit is `c4f07ecee22ec7`,
which is in this tree. No later intermediate autoload fix on this file.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record (this tree, path-limited):
- `e005a9b35b464` level alarm_irq
- `d64906b320ce6` `.remove` → `.remove_new`
- `24304a87158aa` non-wake alarm
- None of these publish OF aliases.
- **Standalone** one-line patch; not “X/Y” of a series that this file
  depends on. Parent of upstream `402c89d28fec` is a sibling RTC
  autoload fix (`rtc: s32g`), not a prerequisite for this driver.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Pengpeng Hou is not the RTC maintainer. In this tree the only
other `drivers/rtc/` commit from that author is unrelated (`rtc: zynqmp:
Return optional clock lookup errors`). Alexandre Belloni (RTC
maintainer) applied the patch. Florian Fainelli / Broadcom were on
To/Cc.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: **None.** Needs only `MODULE_DEVICE_TABLE` and the existing
`of_device_id` table, both present since the driver was added. **Can
apply standalone.**

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- **b4 dig -c 402c89d28fec:**
  https://patch.msgid.link/20260704121734.54941-1-pengpeng@iscas.ac.cn
- **b4 dig -a:** single **v1**, 2026-07-04; no v2/v3.
- Thread (3 messages): original patch; Sashiko bot “no issues”;
  Alexandre Belloni **“Applied, thanks!”** pointing at
  `https://git.kernel.org/abelloni/c/402c89d28fec`.
- **No NAK, no stable nomination, no reviewer risk flags.** WebFetch to
  lore returned 403; thread recovered via `b4 mbox`.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (b4 dig -w): To/Cc included Alexandre Belloni (RTC maintainer),
Florian Fainelli, bcm-kernel-feedback-list, linux-rtc, linux-arm-kernel,
linux-kernel. Maintainer applied it. No human Reviewed-by.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: **No user/syzbot/bugzilla report.** Author states it is source-
level. Severity from reporters: N/A. Users affected: anyone building
this driver as a module on DT platforms with `brcm,brcmstb-waketimer`.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Wave of the same one-line OF-alias pattern. This 6.12 tree
already contains:
- `330fdd1fb7d09` drm/tve200: add OF module alias for autoloading
- `2260191fbf7c6` crypto: keembay - publish OF module alias for OCS
  AES/SM4
Those are the same bug class, already accepted here. This brcmstb patch
does not depend on them.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable search via WebFetch returned 403.
**UNVERIFIED** whether this exact patch was discussed on stable@. No
local evidence it was rejected.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: **No function body changed.** Site is `brcmstb_waketmr_of_match`
/ `brcmstb_waketmr_driver`. Related runtime function:
`brcmstb_waketmr_probe`.

Step 5.2: TRACE CALLERS
Record: `brcmstb_waketmr_probe` is only referenced as `.probe` on
`brcmstb_waketmr_driver`, registered via `module_platform_driver()`.
Called from platform/OF device bind (kernel boot or module load), not
from a syscall directly. Userspace trigger is: DT node present + module
autoload (or manual `modprobe`).

Step 5.3: TRACE CALLEES
Record: Probe ioremaps, allocates an RTC device, requests IRQs,
`device_init_wakeup()`. The new line calls nothing at runtime.

Step 5.4: FOLLOW THE CALL CHAIN
Record: DT `compatible = "brcm,brcmstb-waketimer"` (in-tree on several
BMIPS boards, e.g. `arch/mips/boot/dts/brcm/bcm7435.dtsi`) → OF match →
probe. **Reachable on real STB hardware.** Autoload is the broken hop
when `=m`.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Many RTC drivers already export OF tables (`rtc-zynqmp.c`, `rtc-
mt7622.c`, …). Historical RTC fixes of the same kind: `206e04ec7539e`
(mxc_v2), `3fc990a5dbfff` (mt7622). Systematic missing-alias class, not
a one-off.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.** `drivers/rtc/rtc-brcmstb-waketimer.c:413-424` has the
table and `.of_match_table` and **no** `MODULE_DEVICE_TABLE`. `git
merge-base --is-ancestor 402c89d28fec HEAD` failed (fix not here).
Introduced v4.13, long before 6.12.

Kconfig in this tree (`drivers/rtc/Kconfig`):
```
config RTC_DRV_BRCMSTB
        tristate "Broadcom STB wake-timer"
        depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
        default ARCH_BRCMSTB || BMIPS_GENERIC
```
Explicitly modular. Default `y` on the SoCs that have the IP, so the
common defconfig path is built-in; `=m` is still a supported and
documented config.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Clean apply.** Original mailed hunk (3 lines of context
through `.probe`) — `git apply --check` **rc 0** on this tree. `.remove`
vs `.remove_new` is later in the struct and is not in the original hunk.
No rework needed.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: **No** commit on this file adds `MODULE_DEVICE_TABLE`. Sibling
OF-alias backports exist for other drivers (tve200, keembay), not a
substitute for this one.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **[drivers/rtc — Broadcom STB wake-timer] [PERIPHERAL]** for
most 6.12 users; **IMPORTANT** on BCM7xxx set-top boxes (alarm/S2/S3/S5
wake). Not mm/net/block core.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Driver is mature (2017). Recent local commits are PM/IRQ and
platform-remove conversion, not a rewrite. Low churn around the match
table.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Driver-specific / config-specific.** Users of Broadcom STB
wake-timer with `CONFIG_RTC_DRV_BRCMSTB=m`. In-tree DT nodes are on
BMIPS boards (`bcm7346/7358/7360/7362/7425/7435`). `ARCH_BRCMSTB` also
exists on ARM and arm64; this tree’s ARM/arm64 dtsi files do not contain
the compatible string (vendor DTs may). Built-in (`=y`, the Kconfig
default on those arches) is unaffected.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: modular driver + OF device present + reliance on autoload
  (normal distro/udev path).
- Commonness: uncommon vs default `=y`; real whenever someone chooses
  `=m` (help text documents that).
- Unprivileged userspace cannot exploit this; it is bind/enablement, not
  a crash primitive.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: **[RTC/wake-timer never binds when built as a module] [MEDIUM]**
- Not oops/deadlock/corruption/CVE.
- On affected boxes, RTC alarm and suspend wake from this block can fail
  to be available until a manual `modprobe`.
- Fits stable-rules “device ID” / “oh, that’s not good” more than
  “oops”.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** medium for modular STB configs (hardware actually gets
  its driver); low for default `=y` defconfigs.
- **Risk:** very low (1 line, modpost alias, no runtime behavior change
  for built-in).
- **Ratio:** favorable. Same class already merged in this 6.12.y tree.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
**FOR:**
- Real autoload bug: OF table used, aliases never generated.
- One line, obviously correct, maintainer-applied.
- Driver and buggy code exist in 6.12.111 since v4.13.
- Original patch applies cleanly here.
- Device-ID / hardware-enablement exception; wake-timer matters for STB
  suspend/resume.
- Identical OF-alias one-liners already in this tree (tve200, keembay).
- Zero runtime regression path for the default built-in config.

**AGAINST:**
- Not a crash, UAF, deadlock, or security hole.
- No user report; source-level scan.
- Kconfig default is built-in on the SoCs that have the hardware, so
  many production images never hit autoload.
- Peripheral driver, not core.

**UNRESOLVED:**
- Whether this SHA was already discussed on stable@ (lore 403).
- Whether vendor ARM/arm64 brcmstb DTs (not in this tree) also use this
  compatible.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — standard macro; RTC
   maintainer applied v1 with no objections.
2. Fixes a real bug that affects users? **PASS** — modular OF autoload
   does not work; Kconfig allows `=m`.
3. Important issue? **PASS** (device-ID / hardware-enablement class;
   functional miss for modular STB RTC/wake). Severity MEDIUM, not
   CRITICAL.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — publishes an alias for an
   existing match table.
6. Can apply to the local tree? **PASS** — `git apply --check`
   succeeded; code present; no missing prereqs.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: **Device ID / OF module alias publication for an existing
driver** (stable-rules: “or just add a device ID”). Closest match to the
documented ID-addition exception.

Step 9.4: MAKE YOUR DECISION
Backport. The bug is in this tree, the fix is the usual one-line alias
export, it applies cleanly, and it matches both the written device-ID
exception and OF-alias fixes already on 6.12.y. Default-y only reduces
how often it bites; it does not make the modular path fictional.

------------------------------------------------
What the commit solves for this tree
The 6.12 `rtc-brcmstb-waketimer` driver matches `brcm,brcmstb-waketimer`
but never asks modpost to emit that alias. Built as a module, the wake-
timer will not autoload. Adding `MODULE_DEVICE_TABLE(of, ...)` is the
complete fix.

Risk vs benefit
Benefit is restoring bind on modular STB configs; risk is essentially
nil. Context around `.remove_new` does not affect the original hunk.

------------------------------------------------
Verification:
- [Phase 1] Parsed tags: Link to msgid, SOB Pengpeng Hou + Alexandre
  Belloni; no Fixes/Cc stable/Reported-by
- [Phase 1] Body: missing OF alias; source-level, no hardware repro
  claimed
- [Phase 2] Diff: +1 line `MODULE_DEVICE_TABLE(of,
  brcmstb_waketmr_of_match)` after the match table
- [Phase 2] `include/linux/module.h`: macro is alias-for-modpost if
  `MODULE`, empty otherwise
- [Phase 2] `scripts/mod/file2alias.c` `do_of_entry_multi()`: emits
  `of:N*T*C<compatible>`
- [Phase 3] `git blame`: table from `c4f07ecee22ec7` (v4.13-rc1);
  `__maybe_unused` from `ae1247f79ddf8`
- [Phase 3] `git merge-base --is-ancestor c4f07ecee22ec HEAD`: intro
  commit is in this tree
- [Phase 3] `git merge-base --is-ancestor 402c89d28fec HEAD`: fix is
  **not** in this tree
- [Phase 3] `git show 402c89d28fec`: confirmed same +1 line,
  author/date/message
- [Phase 3] `git log --oneline -20 -- drivers/rtc/rtc-brcmstb-
  waketimer.c`: no prior MODULE_DEVICE_TABLE on this file
- [Phase 4] `b4 dig -c 402c89d28fec`: lore URL + v1-only series
- [Phase 4] `b4 dig -a`: only v1, 2026-07-04
- [Phase 4] `b4 dig -w`: Belloni, Fainelli, bcm-kernel-feedback-list,
  linux-rtc CC’d
- [Phase 4] `b4 mbox`: Belloni “Applied, thanks!”; Sashiko no issues; no
  NAK
- [Phase 4] WebFetch lore: 403; used b4 instead
- [Phase 4] UNVERIFIED: stable@ thread for this exact subject
- [Phase 5] Probe only used as platform `.probe`; DT compatible present
  in `arch/mips/boot/dts/brcm/*.dtsi`
- [Phase 6] `make kernelversion` / Makefile: **6.12.111**; `git describe
  HEAD`: p-6.12-3-gc504cf0baa3d8
- [Phase 6] Local file lines 413–424: table present, MODULE_DEVICE_TABLE
  absent
- [Phase 6] `git apply --check` of original hunk: **success (rc 0)**
- [Phase 6] Same-class already in tree: `330fdd1fb7d09`, `2260191fbf7c6`
- [Phase 7] MAINTAINERS: RTC subsystem maintained by Alexandre Belloni
- [Phase 8] Kconfig tristate + `default y` on ARCH_BRCMSTB/BMIPS_GENERIC
  verified via blame
- [Phase 8] Failure mode: missing modular bind, not a crash

**YES**

 drivers/rtc/rtc-brcmstb-waketimer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index fb47c32ab5ff4..55c15aad42cff 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -413,6 +413,7 @@ static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
 	{ .compatible = "brcm,brcmstb-waketimer" },
 	{ /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, brcmstb_waketmr_of_match);
 
 static struct platform_driver brcmstb_waketmr_driver = {
 	.probe			= brcmstb_waketmr_probe,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net: stmmac: use dma_addr_t for DMA addresses
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (33 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] rtc: brcmstb-waketimer: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
                   ` (13 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Alex Elder, Sashiko, Maxime Chevallier, Jakub Kicinski,
	Sasha Levin, andrew+netdev, davem, edumazet, pabeni,
	mcoquelin.stm32, alexandre.torgue, netdev, linux-stm32,
	linux-arm-kernel, linux-kernel

From: Alex Elder <elder@riscstar.com>

[ Upstream commit 0c1f9020d2ada55aed8a2e055903ad9cd5d49dab ]

In jumbo_frm() (implemented in both "chain_mode.c" and "ring_mode.c"),
an unsigned integer local variable is used to hold the value returned
by dma_map_single().  On systems where a dma_addr_t is 64 bits, the
subsequent dma_mapping_error() check of the returned value operates
only on the low 32 bits (whose high bit won't be sign-extended).  In
this case, dma_mapping_error() would return 0 (no error) even if there
were one.

Fix this in both spots by using a dma_addr_t for the local variable.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/linux-devicetree/20260606010122.21A211F00899@smtp.kernel.org/
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
Link: https://patch.msgid.link/20260812163832.271742-2-elder@riscstar.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.12.111** (`pending-6.12`). The buggy `unsigned int
des2` path is present here, and this type-correctness fix should be
backported.

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[net: stmmac] [use] [store dma_map_single() results as
dma_addr_t in jumbo_frm()]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reported-by: Sashiko <sashiko-bot@kernel.org>` — static-analysis bot,
  not a user crash
- `Link: https://lore.kernel.org/linux-
  devicetree/20260606010122.21A211F00899@smtp.kernel.org/` — Sashiko
  report
- `Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>` —
  stmmac/netdev reviewer
- `Signed-off-by: Alex Elder <elder@riscstar.com>` — author
- `Link:
  https://patch.msgid.link/20260812163832.271742-2-elder@riscstar.com` —
  v2 1/2 of a net-next series
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` — net maintainer
- No `Fixes:` tag (expected)
- No `Cc: stable` (expected)
- Ignore pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit ...]`
  if present on a candidate wrapper

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `jumbo_frm()` in `chain_mode.c` and `ring_mode.c` stores
  `dma_map_single()` in `unsigned int des2`. On 64-bit `dma_addr_t`,
  `dma_mapping_error()` only sees the low 32 bits.
- **Symptom:** a failed mapping is treated as success
  (`dma_mapping_error()` returns 0).
- **Root cause:** `DMA_MAPPING_ERROR` is `~(dma_addr_t)0`
  (`0xFFFFFFFFFFFFFFFF` on 64-bit). Truncating to `unsigned int` yields
  `0xFFFFFFFF`, which promotes to `0x00000000FFFFFFFF` and does not
  match all-ones.
- **Version info:** none in the message. The pattern dates to at least
  2016 (`f8be0d78be6e7`).

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. It is an explicit correctness fix for a truncated
DMA error check. Changing `des2` to `dma_addr_t` also stops truncating
the address stored in `tx_skbuff_dma[].buf` (`dma_addr_t`) used for
later unmap.

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- `drivers/net/ethernet/stmicro/stmmac/chain_mode.c`: +2/−1
- `drivers/net/ethernet/stmicro/stmmac/ring_mode.c`: +2/−1
- Functions: `jumbo_frm()` in both files
- Scope: single-function surgical type change in two parallel
  implementations (4 insertions, 2 deletions)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `unsigned int des2 = dma_map_single(...)`; then
  `cpu_to_le32(des2)`, `dma_mapping_error(..., des2)`,
  `tx_skbuff_dma[entry].buf = des2`.
- **After:** `dma_addr_t des2` so the error check and `buf` store use
  the full DMA address.
- Path: jumbo TX mapping in `stmmac_xmit()` when `enh_desc` is set and
  the frame is large enough (`>= 4KiB` ring / `> 8KiB` chain).
- Same local is reused for later `dma_map_single()` calls in those
  functions, so all mapping sites in `jumbo_frm()` are fixed.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** type / width bug that breaks error detection (and
  truncates unmap addresses).
- **Mechanism:** 32-bit truncation of a 64-bit `dma_addr_t` so
  `dma_mapping_error()` never sees `DMA_MAPPING_ERROR`.
- Verified in this tree:

```92:98:include/linux/dma-mapping.h
static inline int dma_mapping_error(struct device *dev, dma_addr_t
dma_addr)
{
        debug_dma_mapping_error(dev, dma_addr);

        if (unlikely(dma_addr == DMA_MAPPING_ERROR))
                return -ENOMEM;
        return 0;
}
```

`DMA_MAPPING_ERROR` is `~(dma_addr_t)0`. The current buggy locals:

```23:41:drivers/net/ethernet/stmicro/stmmac/chain_mode.c
        unsigned int bmax, buf_len, des2;
        ...
        des2 = dma_map_single(priv->device, skb->data,
                              buf_len, DMA_TO_DEVICE);
        desc->des2 = cpu_to_le32(des2);
        if (dma_mapping_error(priv->device, des2))
                return -1;
        tx_q->tx_skbuff_dma[entry].buf = des2;
```

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct: use the type `dma_map_single()` actually returns.
- Minimal; no API or behavior change on the success path with a 32-bit
  DMA mask.
- Regression risk is low. `desc->des2` is still `__le32`, so hardware
  still gets the low 32 bits (same as before). Maxime asked to make that
  truncation explicit; that is the follow-up `c11c497af866c`
  (`lower_32_bits()`), not required for this fix to be correct.
- `cpu_to_le32()` already casts to `__u32` on little-endian; standalone
  apply should not break the build.

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `unsigned int ... des2` in ring_mode: `f8be0d78be6e7` (2016-11-15,
  “change dma descriptors to `__le32`”).
- chain_mode declaration last touched by `2c91b39912278` (already in
  this tree: “fix integer underflow in chain mode”); that commit kept
  `unsigned int des2`.
- `jumbo_frm()` itself: `286a837217204` (2011).
- Bug is long-standing, not new in 6.12.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Introducer is the 2011/2016 DMA-descriptor
code, present in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record (this tree):
- `2c91b39912278` net: stmmac: fix integer underflow in chain mode
  (already here)
- `133160135a6d7` STMMAC_GET_ENTRY rename
- Mainline follow-up: `c11c497af866c` net: stmmac: convert DMA address
  to lower 32 before assignment (clarity; not in this tree; not a
  functional prerequisite)
- This is standalone 1/2 of “DMA address handling fixes”; 2/2 is
  style/clarity.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Alex Elder is not the stmmac maintainer; two origin stmmac
commits are this pair. Reviewed by Maxime Chevallier; applied by Jakub
Kicinski.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: No new helpers. `dma_addr_t` and `dma_mapping_error()` exist
here. `git apply --check` of `0c1f9020d2ada` succeeded on this tree.
Parent-tree vs this tree only differs in `is_jumbo_frm()` (untouched).
Standalone apply: yes.

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 0c1f9020d2ada` →
  https://patch.msgid.link/20260812163832.271742-2-elder@riscstar.com
- Series: v1 2026-08-11; v2 2026-08-12 `[PATCH net-next v2 0/2] net:
  stmmac: DMA address handling fixes`
- Applied to **net-next** (not `net`) by Jakub on 2026-08-17
- Cover: “ensure DMA errors don't get lost due to casting the result to
  an integer of the wrong size”
- No NAKs. Maxime: “I think this is good as-is” + `Reviewed-by`
- Maxime noted `cpu_to_le32(des2)` still truncates into `__le32` and
  doubted jumbo on true 64-bit descriptor addresses; that is pre-
  existing hardware-descriptor width, not a regression from this patch
- No reviewer `Cc: stable`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): netdev maintainers (Kicinski, Dal, Pabeni, Lunn),
STM32/stmmac (Torgue, Coquelin), Maxime Chevallier. Appropriate
audience.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: Sashiko static analysis, not syzbot and not a user oops. The
lore `linux-devicetree` link is a bot dump; no independent user
reproduction was found. The bug is still visible in the code.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Companion 2/2 (`c11c497af866c`) only wraps
`cpu_to_le32(lower_32_bits(des2))`. This commit is the actual fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org returned HTTP 403 via WebFetch. `b4` thread has
no stable discussion. UNVERIFIED: whether this hash was already
requested on stable@; that does not change the technical verdict.

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `jumbo_frm()` in `chain_mode.c` and `ring_mode.c`.

**Step 5.2: TRACE CALLERS**
Record:
- `stmmac_jumbo_frm()` macro → `hw->mode->jumbo_frm`
- Only call site: `stmmac_xmit()` when `priv->plat->enh_desc` and
  `is_jumbo_frm(skb->len)`
- Context: process / NAPI TX, not IRQ
- `dwmac4_ring_mode_ops` (DWMAC ≥ 4.00) has no `jumbo_frm`; those chips
  do not use this path
- Affected: DWMAC100 / DWMAC1000 (and early DWMAC4 that still install
  `ring_mode_ops`/`chain_mode_ops`) with enhanced descriptors

**Step 5.3: TRACE CALLEES**
Record: `dma_map_single()`, `dma_mapping_error()`, `cpu_to_le32()`,
`stmmac_prepare_tx_desc()`. On error, `return -1` → `stmmac_xmit` `goto
dma_map_err`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: userspace send / jumbo MTU → `ndo_start_xmit` = `stmmac_xmit` →
`jumbo_frm`. TSO/GSO with `priv->tso` uses `stmmac_tso_xmit` instead.
Reachable from userspace on jumbo MTU. Mapping failure is an error path
(IOMMU / swiotlb pressure).

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: non-jumbo TX in `stmmac_xmit` already uses `dma_addr_t des`.
This is leftover jumbo-path width mismatch. Historical related fix in-
tree: `06a80a7d09cc3` (descriptor addresses >32-bit).

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. Local tree is **6.12.111** (`p-6.12-3-gc504cf0baa3d8`).
Both files still have `unsigned int ... des2`. Introduced no later than
2016; present since this series branched. `git merge-base --is-ancestor
0c1f9020d2ada HEAD` is false (fix not here).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Expected **clean apply**. `git show 0c1f9020d2ada | git apply
--check` succeeded. Only unrelated `is_jumbo_frm()` signature drift vs
mainline parent.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No `dma_addr_t` jumbo_frm fix in this tree. `2c91b39912278` is a
different jumbo underflow fix and left `des2` as `unsigned int`.

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/ethernet/stmicro/stmmac` — Synopsys DWMAC, used on
STM32, Rockchip, Allwinner, i.MX, Qualcomm, Intel, etc. Criticality:
**IMPORTANT** (common Ethernet), this path **PERIPHERAL-to-IMPORTANT**
(older GMAC + jumbo).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Actively maintained, but `chain_mode.c`/`ring_mode.c` jumbo
logic is mature (2011). This is an old bug, not churn from new code.

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific, config `CONFIG_STMMAC_ETH`, older DWMAC with
`enh_desc`, jumbo frames, **and** 64-bit `dma_addr_t` (typical
arm64/x86_64). 32-bit `dma_addr_t` already compared equal to
`DMA_MAPPING_ERROR`.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Jumbo TX (`skb->len >= 4KiB` ring / `> 8KiB` chain) plus
`dma_map_single()` failure. Not every packet. Unprivileged users can
send jumbo frames if MTU allows; they cannot force IOMMU exhaustion
easily. Mapping failure is uncommon but real.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record:
- Failed mapping treated as success
- Descriptor programmed with `0xFFFFFFFF`
- NIC DMAs from that address (wrong memory / bus error / possible leak
  of physical memory onto the wire)
- `tx_skbuff_dma[].buf` also truncated, so unmap can be wrong
- Severity: **HIGH** (wrong DMA address / potential corruption). Not a
  guaranteed panic on every jumbo packet.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** medium-high for affected 64-bit DWMAC jumbo users; closes
  a real DMA error-handling hole
- **Risk:** very low (2-line type change per file, no locking/API
  change)
- **Ratio:** favorable

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, verifiable type bug: truncated `dma_mapping_error()` on 64-bit
  `dma_addr_t`
- Failure can program the NIC with a bogus DMA address
- Also stores a full address in `tx_skbuff_dma[].buf`
- ~6 lines, obviously correct, reviewed, applied by net maintainer
- Buggy code is in this 6.12 tree and has been for years
- Patch applies cleanly
- Same driver already uses `dma_addr_t` on the normal TX path

AGAINST:
- Submitted to **net-next**, not `net` (not treated as an urgent
  regression)
- Sashiko/static analysis, no user oops
- Jumbo + older GMAC + mapping failure is a narrow trigger
- Reviewer noted 32-bit descriptors cannot represent full 64-bit
  addresses (pre-existing)
- Companion `lower_32_bits()` patch is not included (optional clarity)

UNRESOLVED:
- Stable@ archives not readable via WebFetch (403)
- Exact Sashiko warning text in the large 47-message dump was not
  isolated beyond the type issue this patch names

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — type matches DMA API;
   reviewed; in mainline since 2026-08-17
2. Fixes a real bug that affects users? **PASS** — missed DMA mapping
   errors on 64-bit `dma_addr_t`
3. Important issue? **PASS** — wrong DMA address on mapping failure
   (corruption / crash / possible leak), even if the window is uncommon
4. Small and contained? **PASS** — 6 lines, two files, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — `git apply --check` clean on
   6.12.111

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/docs exception). Qualifies
as a normal small bugfix.

**Step 9.4: MAKE YOUR DECISION**
The local 6.12 tree still truncates `dma_map_single()` to `unsigned int`
in `jumbo_frm()`, so `dma_mapping_error()` cannot see
`DMA_MAPPING_ERROR` on 64-bit `dma_addr_t`. That is a real DMA
correctness bug, the fix is surgical, and it applies here without
prerequisites. Narrow trigger does not outweigh the severity of
programming a failed mapping into the NIC.

### What the commit solves and why it matters to stable users
On 64-bit `dma_addr_t` platforms, a failed jumbo TX mapping is
misclassified as success, and the MAC may DMA using `0xFFFFFFFF`. 6.12
users of DWMAC1000-class stmmac with jumbo MTU on arm64/x86_64 are
exposed.

### Stable rules / risk
Meets the stable bar: real bug, small, no new API, clean apply. Risk is
a type change of a local. Benefit is correct mapping-error handling and
a full-width unmap address.

### Concerns
Optional follow-up `c11c497af866c` only makes 32-bit descriptor
truncation explicit; not required. No need to wait for other series
patches.

## Verification
- [Phase 1] Parsed tags: Sashiko Reported-by, Maxime Reviewed-by, Jakub
  SOB; no Fixes/Cc stable
- [Phase 1] Body: truncated `dma_mapping_error()` on 64-bit `dma_addr_t`
- [Phase 2] Diff: `unsigned int des2` → `dma_addr_t des2` in both
  `jumbo_frm()` implementations (+4/−2)
- [Phase 2] `include/linux/dma-mapping.h`: `dma_mapping_error()`
  compares to `DMA_MAPPING_ERROR` (`~(dma_addr_t)0`)
- [Phase 2] Local `chain_mode.c`/`ring_mode.c` still use `unsigned int
  des2`; `tx_skbuff_dma[].buf` is `dma_addr_t`
- [Phase 3] Blame: `f8be0d78be6e7` (2016) / `286a837217204` (2011); in
  this tree
- [Phase 3] Mainline SHA `0c1f9020d2ada`; follow-up `c11c497af866c` is
  clarity-only
- [Phase 3] `git merge-base --is-ancestor 0c1f9020d2ada HEAD` → not in
  this tree
- [Phase 4] `b4 dig -c 0c1f9020d2ada`: lore/msgid v2 1/2 net-next
  series; applied to netdev/net-next
- [Phase 4] `b4 dig -a`: v1 then v2; Maxime suggested `lower_32_bits()`,
  still Reviewed-by on the type fix
- [Phase 4] `b4 dig -w`: netdev + STM32/stmmac CCs
- [Phase 4] mbox cover: “DMA errors don't get lost due to casting”
- [Phase 4] UNVERIFIED: stable@ mailing list (lore 403)
- [Phase 5] Callers: `stmmac_xmit()` → `stmmac_jumbo_frm()`; DWMAC4 ≥
  4.00 ops have no `jumbo_frm`
- [Phase 5] Non-jumbo TX already uses `dma_addr_t des`
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111
- [Phase 6] `git apply --check` of `0c1f9020d2ada`: success
- [Phase 6] `git diff 0c1f9020d2ada^ -- chain_mode.c ring_mode.c`: only
  `is_jumbo_frm()` drift
- [Phase 8] Failure mode: missed mapping error → NIC DMA at
  `0xFFFFFFFF`; severity HIGH
- UNVERIFIED: isolated full text of the original Sashiko diagnostic line

**YES**

 drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 3 ++-
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c  | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index 2515608878235..5b0bab33ce4b6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -20,9 +20,10 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb,
 	unsigned int nopaged_len = skb_headlen(skb);
 	struct stmmac_priv *priv = tx_q->priv_data;
 	unsigned int entry = tx_q->cur_tx;
-	unsigned int bmax, buf_len, des2;
+	unsigned int bmax, buf_len;
 	unsigned int i = 1, len;
 	struct dma_desc *desc;
+	dma_addr_t des2;
 
 	desc = tx_q->dma_tx + entry;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
index 88a8d22812f5d..1e6541937cb27 100644
--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -20,8 +20,9 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb,
 	unsigned int nopaged_len = skb_headlen(skb);
 	struct stmmac_priv *priv = tx_q->priv_data;
 	unsigned int entry = tx_q->cur_tx;
-	unsigned int bmax, len, des2;
+	unsigned int bmax, len;
 	struct dma_desc *desc;
+	dma_addr_t des2;
 
 	if (priv->extend_desc)
 		desc = (struct dma_desc *)(tx_q->dma_etx + entry);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (34 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] net: stmmac: use dma_addr_t for DMA addresses Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] firmware: imx: scu: manage mailbox channels and global handle Sasha Levin
                   ` (12 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Devin Wittmayer, 0072a70, Felix Fietkau, Sasha Levin, lorenzo,
	ryder.lee, matthias.bgg, angelogioacchino.delregno,
	linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek

From: Devin Wittmayer <lucid_duck@justthetip.ca>

[ Upstream commit ddae0bcb01e71c1184bb3f526f9622e31dc38f3b ]

When the fcsfail filter is enabled the hardware passes frames with a bad
FCS up to the driver, but mt76x02_mac_process_rx() never checks
MT_RXINFO_CRCERR and hands them to mac80211 without
RX_FLAG_FAILED_FCS_CRC. In monitor mode the radiotap flags byte then
never gets IEEE80211_RADIOTAP_F_BADFCS set and corrupted frames cannot be
told apart from clean ones.

Set RX_FLAG_FAILED_FCS_CRC from the descriptor CRC error bit, matching
mt7603, mt7615, mt7915, mt7921, mt7925 and mt7996.

Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Closes: https://github.com/morrownr/mt76/issues/38
Tested-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613002544.27750-3-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
- Record: `[wifi: mt76: mt76x02]` `[report]` `[report rx FCS errors to
  mac80211]`
- Subsystem is MediaTek mt76, mt76x02 family (mt76x0 / mt76x2 PCI and
  USB). “Report” here is a correctness fix: the driver already receives
  CRC-failed frames and must mark them.

**Step 1.2 — Tags**
- Record:
  - `Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>` —
    real user hit
  - `Closes: https://github.com/morrownr/mt76/issues/38`
  - `Tested-by:` same reporter, on real hardware
  - `Signed-off-by: Devin Wittmayer` (author)
  - `Link: https://patch.msgid.link/20260613002544.27750-3-
    lucid_duck@justthetip.ca`
  - `Signed-off-by: Felix Fietkau` (mt76 maintainer)
  - No `Fixes:` tag (expected for this review)
  - No `Cc: stable` (expected; not a negative)
  - Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
    ...]`

**Step 1.3 — Body**
- Record:
  - **Bug:** With the `fcsfail` filter enabled, hardware delivers frames
    with `MT_RXINFO_CRCERR` set. `mt76x02_mac_process_rx()` never reads
    that bit, so mac80211 never gets `RX_FLAG_FAILED_FCS_CRC`.
  - **Symptom:** In monitor mode, radiotap never sets
    `IEEE80211_RADIOTAP_F_BADFCS`; corrupted frames look identical to
    clean ones.
  - **Root cause:** Missing descriptor-bit → `rx_status` translation.
    Other mt76 chips already do this.
  - **Version info in the message:** none. Reporter used kernel 7.0.x;
    the code path is much older (see Phase 3).

**Step 1.4 — Hidden bug fix?**
- Record: Not disguised. It is an explicit missing-flag fix that
  implements the documented mac80211 contract for `FIF_FCSFAIL`.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
- Record: one file, `drivers/net/wireless/mediatek/mt76/mt76x02_mac.c`.
  Three lines added, none removed. Function: `mt76x02_mac_process_rx()`.
  Surgical single-file change.

**Step 2.2 — Flow**
- Record: After the existing `MT_RXINFO_L2PAD` check, if `rxinfo &
  MT_RXINFO_CRCERR`, set `status->flag |= RX_FLAG_FAILED_FCS_CRC`.
  Normal RX is unchanged for clean frames. Error/monitor path for CRC-
  failed frames is now marked.

**Step 2.3 — Bug mechanism**
- Record: **Logic / correctness** (driver contract). Hardware already
  passes CRC-failed frames when `FIF_FCSFAIL` is on
  (`MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR)` in
  `mt76x02_configure_filter()`). The driver failed to set the flag
  mac80211 requires (`include/net/mac80211.h`: *“pass frames with failed
  FCS (but you need to set RX_FLAG_FAILED_FCS_CRC for them)”*).

Verified mac80211 consequences in this tree:
- `ieee80211_add_rx_radiotap_header()` sets
  `IEEE80211_RADIOTAP_F_BADFCS` only if that flag is present
  (`net/mac80211/rx.c`).
- `should_drop_frame()` treats `RX_FLAG_FAILED_FCS_CRC` as drop-from-
  cooked-path. Without it, `ieee80211_rx_monitor()` copies the frame to
  monitor and **returns the original skb** to
  `__ieee80211_rx_handle_packet()`. FCS-failed frames can therefore
  enter the cooked RX path whenever `fcsfail` is enabled (including
  concurrent monitor + STA/AP).

**Step 2.4 — Fix quality**
- Record: Obviously correct; same pattern as
  `mt7603`/`mt7615`/`mt7915`/`mt7921`/`mt7996` in this tree. Minimal.
  Regression risk is low: only CRCERR frames get a flag they should
  already have. Clean frames are untouched. Does not add APIs or change
  locking.

## Phase 3: Git history

**Step 3.1 — Blame**
- Record: Insertion point is the 2018 `mt76x02_mac_process_rx()` body
  from `d9f8934ed147b3` (“mt76: move mt76x02_mac_process_rx in
  mt76x02-lib module”), 2018-10-04, first contained in **v4.20-rc1**.
  `MT_RXINFO_CRCERR` is defined in `mt76x02_mac.h:54` since
  `5327b5ea13910d` (2018-09-04). The bit has been defined for years and
  never consumed in RX processing.

**Step 3.2 — Fixes: tag**
- Record: None. The omission dates to the original mt76x02 RX path, not
  a later regression.

**Step 3.3 — File history**
- Record: Same-function sibling from the same series is already in this
  tree: `b6e7958602bd1` (“do not WARN on invalid rx descriptor length”).
  That is patch 1/2 of `[PATCH 0/2] wifi: mt76: mt76x02: rx fixes for
  fcsfail monitor mode`. This candidate is patch 2/2. They touch
  different lines; this one does not depend on patch 1. `git apply
  --check` of this hunk on HEAD is **clean**. No other FCS reporting
  commit exists on this file.

**Step 3.4 — Author**
- Record: Devin Wittmayer; not the subsystem maintainer. Maintainer
  Felix Fietkau signed off. Author also submitted the sibling WARN fix.
  Related author commits in this tree: `b6e7958602bd1`, plus unrelated
  mt7615/mt7921 TXRX_NOTIFY drops.

**Step 3.5 — Prerequisites**
- Record: None beyond symbols already in 6.6: `MT_RXINFO_CRCERR`,
  `RX_FLAG_FAILED_FCS_CRC`, `status->flag`. Commit text mentions mt7925;
  that chip need not exist here — it is comparison only. Standalone
  apply: yes.

## Phase 4: Mailing list / external research

**Step 4.1 — Original discussion**
- Record: `b4 dig -c <sha>` cannot match because this commit is not in
  the local history. Fallback: `b4 mbox
  20260613002544.27750-3-lucid_duck@justthetip.ca`.
  - Cover: https://patch.msgid.link/20260613002544.27750-1-
    lucid_duck@justthetip.ca
  - Series: v1 only (`b4 am --check-newer-revisions`: no later
    revision).
  - Two patches; this is 2/2.
  - Cover: tested on MT7612U and MT7610U; fcsfail monitor captures get
    BADFCS on corrupted frames, clean frames unchanged.
  - No NAKs in the retrieved thread (cover + 2 patches, no review
    replies). Applied by Felix Fietkau.
  - Lore HTTP fetch returned 403; b4 was used instead.

**Step 4.2 — Recipients**
- Record: To Felix Fietkau, Lorenzo Bianconi; Cc Ryder Lee, Shayne Chen,
  Sean Wang, linux-wireless, linux-kernel. Right maintainers/lists.

**Step 4.3 — Bug report**
- Record: GitHub issue #38 (closed). Hardware: Alfa AWUS036ACM, mt7612u,
  driver mt76x2u. With `iw set monitor fcsfail`, radiotap flags were
  always `0x00`; `radiotap.flags.badfcs == 1` matched 0 of 2978 frames.
  After this exact three-line change: 956/7353 frames had BADFCS `0x40`,
  clean frames stayed `0x00`. Confirmed on-list/issue by the reporter
  (`Tested-by`).

**Step 4.4 — Series context**
- Record: Patch 1 (WARN on bogus MPDU length under fcsfail) is already
  in this 6.6 tree. Patch 2 is the functional reporting fix.
  Independent; both target the same user-visible fcsfail path.

**Step 4.5 — stable@ discussion**
- Record: lore.kernel.org/stable HTTP 403. No separate stable-thread
  evidence retrieved. Absence is not a negative for this review.

## Phase 5: Semantic / call-chain analysis

**Step 5.1 — Functions**
- Record: `mt76x02_mac_process_rx()`.

**Step 5.2 — Callers**
- Record: Only `mt76x02_queue_rx_skb()` in `mt76x02_txrx.c` (data RX,
  not MCU queue). That is the USB/PCI RX completion path for mt76x0 and
  mt76x2.

**Step 5.3 — Callees (relevant)**
- Record: Sets `struct mt76_rx_status` in `skb->cb`, then `mt76_rx()` →
  mac80211. `mt76_rx()` already counts `RX_FLAG_FAILED_FCS_CRC` for
  testmode FCS stats (`mac80211.c`).

**Step 5.4 — Reachability**
- Record: Userspace-reachable: `iw set type monitor` + `iw set monitor
  fcsfail` (nl80211 `NL80211_MNTR_FLAG_FCSFAIL` →
  `ieee80211_adjust_monitor_flags()` → `fif_fcsfail` → `FIF_FCSFAIL` →
  hardware CRC filter cleared). Common on USB adapters used for capture
  (Alfa AWUS036ACM and similar).

**Step 5.5 — Similar patterns**
- Record: Same `status->flag |= RX_FLAG_FAILED_FCS_CRC` already present
  in this tree for mt7603, mt7615, mt7915, mt7921, mt7996. mt76x02 is
  the gap. `MT_RXINFO_ICVERR` / `MT_RXINFO_MICERR` are also unused here;
  out of scope for this patch.

## Phase 6: This tree (6.6.157 / pending-6.6)

**Step 6.1 — Does the buggy code exist?**
- Record: Yes. `mt76x02_mac_process_rx()` at `mt76x02_mac.c:794–797` has
  L2PAD then DECRYPT; no CRCERR check. `MT_RXINFO_CRCERR` is defined.
  `git merge-base --is-ancestor d9f8934ed147b3 HEAD` succeeded. Bug
  present since ~v4.20, so it is in 6.6.y.

Local tree identity:
- `git describe HEAD` → `p-6.6-3-g04810563abb71`
- `make kernelversion` → **6.6.157**
- Branch: `pending-6.6`

**Step 6.2 — Backport difficulty**
- Record: **Clean apply.** Context matches; `git apply --check`
  succeeded. Surrounding code is the same as the patch’s index.

**Step 6.3 — Related fixes already here**
- Record: No existing CRCERR → `RX_FLAG_FAILED_FCS_CRC` translation.
  Sibling WARN fix `b6e7958602bd1` is present (different hunk).
  `63fe66f102837` (mt7996 FCS bit in wrong RXD word) is a different
  chip.

## Phase 7: Subsystem context

**Step 7.1**
- Record: `drivers/net/wireless/mediatek/mt76` — **IMPORTANT** (widely
  used WiFi, not core mm/vfs). Covers MT76x0U/E and MT76x2U/E (`Kconfig`
  MT7610/MT7612 USB and PCIe). Peripheral relative to core kernel, but
  these USB NICs are common in the field.

**Step 7.2**
- Record: mt76 is active; mt76x02 RX processing itself has been stable
  for years. This is a long-standing omission, not churn from a new
  subsystem.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
- Record: Users of mt76x0/mt76x2 (USB and PCIe) who enable monitor
  `fcsfail`. Normal STA/AP-only operation keeps the hardware CRC filter
  on, so those users are not on this path. Mixed monitor+managed on the
  same phy is affected for cooked RX.

**Step 8.2 — Trigger**
- Record: Explicit monitor `fcsfail` (and typically a busy channel). Not
  every boot. Unprivileged users cannot enable monitor without
  privileges, so this is not a generic local-priv-esc path; it is a
  privileged capture/correctness bug.

**Step 8.3 — Failure mode**
- Record:
  - Monitor: corrupted frames indistinguishable from good ones (broken
    advertised filter). **MEDIUM** for dedicated capture.
  - Cooked path: FCS-failed frames can be processed as valid 802.11 when
    `fcsfail` is on. That is frame-integrity / stack-correctness, not a
    panic. **MEDIUM–HIGH** in mixed-iface setups; not a guaranteed oops.
  - Overall severity: **MEDIUM**, with a real user-visible functional
    break and a documented driver-API violation.

**Step 8.4 — Risk vs benefit**
- Record: **Benefit: medium** (correct FCS reporting; stop garbage
  frames leaking into cooked RX). **Risk: very low** (3 lines, same
  pattern as sibling chips, no lock/API change). Ratio favors backport.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

For:
- Real, reproduced bug (GitHub #38; Tested-by on MT7612U; author also
  tested MT7610U).
- Violates mac80211 `FIF_FCSFAIL` contract; radiotap BADFCS never set.
- FCS-failed frames can continue into `__ieee80211_rx_handle_packet()`
  without the flag.
- Three-line, obviously correct, matches every other mt76 MAC in this
  tree.
- Applies cleanly to 6.6.157; symbols and call path exist.
- Maintainer SOB (Felix Fietkau).
- Popular USB hardware (e.g. Alfa AWUS036ACM).

Against:
- Not a crash/UAF/deadlock; mainly monitor-mode correctness plus cooked-
  path leakage only when `fcsfail` is enabled.
- No `Fixes:` (omission from original driver, not a later regression).
- Affects a subset of mt76x02 users, not all machines.

Unresolved:
- Direct lore.kernel.org HTTP was 403; discussion recovered via b4.
- No independent stable@ thread found.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — 3 lines, hardware-tested,
   maintainer-acked.
2. Real bug affecting users? **PASS** — reporter could not tell bad-FCS
   frames apart; contract violation is in-tree.
3. Important issue? **PASS** (medium) — broken advertised monitor filter
   plus cooked-path delivery of CRC-failed frames. Not a panic, but it
   is a real correctness/integrity bug, not a feature.
4. Small and contained? **PASS** — +3 lines, one function.
5. No new features/APIs? **PASS** — sets an existing `rx_status` flag
   other mt76 chips already set.
6. Can apply to this tree? **PASS** — clean apply on 6.6.157.

**Step 9.3 — Exception category**
- Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
  driver correctness fix.

**Step 9.4 — Decision**
This tree is **6.6.157**. The buggy RX path, `MT_RXINFO_CRCERR`, and
mac80211 flag handling are all present. The patch is a tiny, tested,
maintainer-accepted fix for a user-visible bug on hardware this driver
supports. Benefit clearly outweighs risk.

---

### What the commit solves for 6.6 users

mt76x02 already programs the hardware to deliver CRC-failed frames when
monitor `fcsfail` is set, but never tells mac80211. Users of
MT7610/MT7612 USB and PCIe adapters then see every frame as clean in
radiotap, and those frames can also continue into the normal RX
handlers. The fix sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`,
which is what this tree already does for later mt76 chips.

### Stable-rule fit

Small, obviously correct, no new API, applies cleanly, real user-visible
bug. Importance is monitor/FCS integrity rather than a panic; that is
still within what stable takes for driver contract bugs of this size.

### Risk vs benefit

Very low risk (three lines, clean frames unchanged). Medium benefit for
mt76x02 monitor users and mixed-iface setups.

### Concerns

No functional dependencies. Series mate (WARN drop) is already in this
tree but is not required for this hunk. mt7925 in the commit message is
comparison only.

---

Verification:
- [Phase 1] Parsed tags: Reported-by/Tested-by 0072a70, Closes
  github.com/morrownr/mt76/issues/38, Link msgid `...27750-3...`, SOB
  Felix Fietkau; no Fixes/Cc:stable
- [Phase 2] Diff: +3 lines in `mt76x02_mac_process_rx()` after L2PAD;
  sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`
- [Phase 2] Confirmed `mt76x02_configure_filter()` maps `FIF_FCSFAIL` →
  clear `MT_RX_FILTR_CFG_CRC_ERR`
- [Phase 2] Confirmed mac80211 `should_drop_frame()` / radiotap BADFCS /
  `ieee80211_rx_monitor()` cooked-path return behavior in this tree
- [Phase 3] `git blame`: insertion region from `d9f8934ed147b3` (2018);
  `git merge-base --is-ancestor` true; `git describe --contains` →
  v4.20-rc1
- [Phase 3] `MT_RXINFO_CRCERR` defined at `mt76x02_mac.h:54`; `git grep`
  shows it is unused in `.c` files in this tree
- [Phase 3] Sibling `b6e7958602bd1` already in HEAD; this hunk
  independent; `git apply --check` CLEAN
- [Phase 4] `b4 mbox` saved 3-message series; cover tested
  MT7612U/MT7610U; `b4 am --check-newer-revisions` = v1 only, no NAKs
- [Phase 4] WebFetch of GitHub issue #38: reproduced 0 BADFCS; after
  patch 956/7353 frames flagged
- [Phase 4] lore.kernel.org WebFetch: 403 — UNVERIFIED via HTTP;
  recovered via b4
- [Phase 5] Only caller: `mt76x02_queue_rx_skb()`; chips: MT76x0U/E,
  MT76x2U/E
- [Phase 5] Same flag already set in mt7603/mt7615/mt7915/mt7921/mt7996
  in this checkout
- [Phase 6] `git describe HEAD` p-6.6-3-g04810563abb71; `make
  kernelversion` 6.6.157; buggy code present; fix not applied
- [Phase 8] Failure mode: wrong radiotap + possible cooked-path delivery
  of CRC-failed frames; not a panic
- UNVERIFIED: stable@ mailing-list thread content (HTTP 403)

**YES**

 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 06f17da2c0106..17c9782915315 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -792,6 +792,9 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
 	if (rxinfo & MT_RXINFO_L2PAD)
 		pad_len += 2;
 
+	if (rxinfo & MT_RXINFO_CRCERR)
+		status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
 	if (rxinfo & MT_RXINFO_DECRYPT) {
 		status->flag |= RX_FLAG_DECRYPTED;
 		status->flag |= RX_FLAG_MMIC_STRIPPED;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] firmware: imx: scu: manage mailbox channels and global handle
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (35 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (11 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Frank Li, Sasha Levin, imx, linux-arm-kernel,
	linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 55c748d596f841a18cf659ce0999f64029a5c88c ]

imx_scu_probe() requests mailbox channels with the non-managed
mbox_request_channel_byname() helper and then publishes sc_ipc through
the global imx_sc_ipc_handle.  Later probe failures, including child
population failure, can leave the channels and global handle live after
the probe has failed.

Register devres actions to free each mailbox channel and clear the global
handle.  Also depopulate partially created child devices when
devm_of_platform_populate() reports an error.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1:** Record: `[firmware/imx SCU] [manage] Register managed
cleanup for mailbox channels and the global IPC handle, and depopulate
children if probe fails.`

**Step 1.2:** Tags present:
- `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
- `Signed-off-by: Frank Li <Frank.Li@nxp.com>` (i.MX maintainer who
  applied it)

No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-by:`,
`Link:`, or `Cc: stable`. Absence of those tags is expected for this
review and is not treated as a negative signal.

**Step 1.3:** Record:
- **Bug:** `imx_scu_probe()` uses unmanaged
  `mbox_request_channel_byname()` and then publishes `sc_ipc` via the
  global `imx_sc_ipc_handle`. Later probe failures, including
  `devm_of_platform_populate()`, leave channels allocated and the global
  handle set.
- **Symptom:** Leaked mailbox channels after a failed probe; a live
  global handle to an object that `devm_kzalloc` then frees; partial
  child devices left behind.
- **Version info:** None in the message. Driver originated in v4.20
  (`edbee095fafb4`).
- **Root cause:** Non-devm mailbox requests plus a global pointer with
  no rollback on the remaining error paths.

**Step 1.4:** Record: This is an explicit probe-error-path resource-leak
/ dangling-pointer fix, not a disguised cleanup. The wording matches the
diff.

## Phase 2: Diff analysis

**Step 2.1:** Record:
- File: `drivers/firmware/imx/imx-scu.c` (+24 / −1)
- Functions added: `imx_scu_free_mbox_chan()`, `imx_scu_clear_handle()`
- Function modified: `imx_scu_probe()`
- Scope: single-file surgical fix

**Step 2.2:** Before → after:
1. After a successful `mbox_request_channel_byname()`, the channel was
   never registered with devres. Mid-loop failure (`-EPROBE_DEFER`,
   `-ENOMEM` from `kasprintf`, later channel failure) returned without
   `mbox_free_channel()`. After: each channel is wrapped in
   `devm_add_action_or_reset(..., imx_scu_free_mbox_chan, ch)`.
2. `imx_sc_ipc_handle = sc_ipc` was published with no undo. After: a
   matching `devm_add_action_or_reset(..., imx_scu_clear_handle,
   sc_ipc)` NULLs it on unwind if it still points at this object.
3. `return devm_of_platform_populate(dev)` could fail after
   `of_platform_populate()` had already created some children
   (`devm_of_platform_populate()` does **not** depopulate on failure; it
   only `devres_free()`s the tracking pointer). After: explicit
   `of_platform_depopulate(dev)` on that error.

**Step 2.3:** Record: `[error-path resource leak + dangling global
pointer]`
- Mailbox leak: unmanaged `mbox_request_channel_byname()` with no free
  on later probe failure.
- Retry hazard: `__mbox_bind_client()` returns `-EBUSY` if `chan->cl` is
  already set, so a later probe retry can stick forever.
- Handle leak / UAF: `sc_ipc` is `devm_kzalloc`’d; probe failure
  releases it while `imx_sc_ipc_handle` still points at it. Other i.MX
  drivers call `imx_scu_get_handle()`.
- Child leak: failed `of_platform_populate()` still sets
  `OF_POPULATED_BUS` and can leave partial children.

**Step 2.4:** Record: The mailbox and handle `devres` actions are
obviously correct (`devm_add_action_or_reset` runs the action
immediately if registration fails). Calling `of_platform_depopulate()`
only on populate failure is the right API:
`devm_of_platform_depopulate()` would `WARN` because the managed
resource was never added. Regression risk is low. Remaining related
leaks (`gip3`, `soc_device`, secondary static handles) are pre-existing
and not introduced here.

## Phase 3: Git history

**Step 3.1:** Record: Unmanaged `mbox_request_channel_byname()` and
`imx_sc_ipc_handle = sc_ipc` come from `edbee095fafb4` (“firmware: imx:
add SCU firmware driver support”, 2018-10-08), first contained in
**v4.20-rc1**. The bug is long-standing.

**Step 3.2:** No `Fixes:` tag. Not applicable.

**Step 3.3:** Related commits on this file:
- `89f12d6509bff` — kasprintf leak in the same probe loop (same class of
  bug)
- `fbf10b86f6057` — OF node leak in probe
- `97a07dd2b559d` — `devm_mutex_init` (adjacent context; not a
  functional prerequisite)
- `ff79af939d847` — `suppress_bind_attrs = true`

This is a standalone v1 patch, not part of a series. No follow-ups to
this file after `55c748d596f84`.

**Step 3.4:** Pengpeng Hou has only this commit in
`drivers/firmware/imx/`. Frank Li (NXP i.MX maintainer) applied it.
Author is a contributor; the applying maintainer is the subsystem owner.

**Step 3.5:** No hard dependencies. `devm_add_action_or_reset()` is in
`include/linux/device/devres.h` in this tree. Applies standalone.

## Phase 4: Mailing list and external research

**Step 4.1:** Record:
- Lore / msgid:
  https://patch.msgid.link/20260616005902.11634-1-pengpeng@iscas.ac.cn
- Series: v1 only (`b4 dig -a`)
- Maintainer apply: Frank Li, “Applied, thanks!” (24 Jul 2026), commit
  `55c748d596f84`
- No NAK. No `Cc: stable` suggestion in the thread.
- Sashiko bot flagged **pre-existing** incomplete cleanup (`gip3`,
  `soc_device`, secondary handles, RPC timeout). Those are not
  regressions from this patch.

**Step 4.2:** Recipients (`b4 dig -w`): Frank Li, Sascha Hauer,
Pengutronix, Fabio Estevam, `imx@lists.linux.dev`, `linux-arm-kernel`,
`linux-kernel`. Appropriate i.MX maintainers were on To/Cc.

**Step 4.3:** No bugzilla / syzbot / user `Reported-by`. Bug is from
code inspection of the probe error path.

**Step 4.4:** Standalone 1/1 patch. No series dependencies.

**Step 4.5:** Record: UNVERIFIED for lore.kernel.org/stable (Anubis bot
wall). Original imx thread has no stable discussion.

## Phase 5: Code semantic analysis

**Step 5.1:** Record: `imx_scu_free_mbox_chan`, `imx_scu_clear_handle`,
`imx_scu_probe`.

**Step 5.2:** `imx_scu_probe()` is the platform probe for `fsl,imx-scu`.
`imx_scu_get_handle()` is called from clk-scu, scu-pd, thermal, rtc,
pinctrl, nvmem, GPIO, reset, FEC, FlexCAN, remoteproc, DRM, SOF, and
others. Impact is every i.MX8QM/QXP SCU consumer.

**Step 5.3:** Probe allocates `sc_ipc`, requests MU mailbox channels,
publishes the global handle, then populates child devices. Callees:
`mbox_request_channel_byname`, `mbox_free_channel`,
`devm_of_platform_populate`, `of_platform_depopulate`.

**Step 5.4:** Reachable at boot on SCU SoCs (`subsys_initcall_sync`).
Not a syscall, but it is the firmware IPC path those boards need to
bring up clocks, power domains, and peripherals. Unprivileged userspace
cannot poke it directly.

**Step 5.5:** Same driver already had a kasprintf leak fix in this
probe. `imx_scu_enable_general_irq_channel()` still requests unmanaged
`gip3` (pre-existing, not this patch).

## Phase 6: Local tree

**Step 6.1:** Local tree is **7.3.0-rc4** (`git describe HEAD` =
`v7.3-rc4-27-gf0100363d8c37`). Buggy pattern was introduced in v4.20 and
is in this lineage. `git merge-base --is-ancestor 55c748d596f84 HEAD`
succeeds. Pre-fix probe is in `55c748d596f84^`.

**Step 6.2:** Expected apply: clean on this tree (`devm_mutex_init`
context matches).

**Step 6.3:** No alternate fix for mailbox/handle cleanup. Prior leak
fixes (`89f12d6509bff`, `fbf10b86f6057`) do not cover this.

## Phase 7: Subsystem context

**Step 7.1:** Record: `[drivers/firmware/imx] [IMPORTANT]` — i.MX8QM/QXP
System Controller IPC. Not core mm/net, but it is the firmware bus those
SoCs use for clocks, PD, pinmux, thermal, RTC.

**Step 7.2:** Mature driver (2018), occasional probe-correctness fixes.
Not a new subsystem.

## Phase 8: Impact and risk

**Step 8.1:** i.MX8QM/QXP (and similar SCU) users with `CONFIG_IMX_SCU`.
Driver-specific / SoC-specific.

**Step 8.2:** Trigger is probe failure **after** some channels were
requested: mid-loop `kasprintf` `-ENOMEM`, a later
`mbox_request_channel_byname()` failure, `devm_mutex_init()` failure, or
`devm_of_platform_populate()` failure. First-channel `-EPROBE_DEFER`
does **not** leak (nothing held yet). Not userspace-triggerable except
via boot / driver bind.

**Step 8.3:** Failure mode:
- Leaked MU channels → retry gets `-EBUSY` → SCU never probes →
  clocks/PD/peripherals fail (**HIGH**, can make the board unusable)
- Dangling `imx_sc_ipc_handle` after `devm` frees `sc_ipc` (**HIGH** UAF
  if another driver then calls `imx_scu_get_handle()`)
- Orphan child devices after failed populate (**MEDIUM**)

Happy-path probe is unchanged.

**Step 8.4:** Benefit: prevents stuck SCU probe and a global-handle UAF
on real error paths. Risk: ~24 lines, probe error path only, standard
`devres` pattern. Ratio: favorable.

## Phase 9: Synthesis

**Evidence FOR:**
- Real leak of exclusive mailbox channels; `__mbox_bind_client()`
  returning `-EBUSY` can permanently break SCU probe retry.
- Global handle left pointing at `devm`-freed `sc_ipc` after populate
  failure (UAF for every `imx_scu_get_handle()` caller).
- `of_platform_depopulate()` on failed `devm_of_platform_populate()` is
  correct (verified against `drivers/of/platform.c`).
- Small, single-file, no new API.
- Applied by the i.MX maintainer; v1 accepted as-is.
- Same probe function already needed leak fixes; this is the
  mailbox/handle analogue.
- Code and helpers exist in this 7.3-rc4 tree; no missing prerequisites.

**Evidence AGAINST:**
- No user/syzbot report; author-found error-path bug.
- Trigger is uncommon (not the first-channel `-EPROBE_DEFER` case).
- Incomplete: `gip3`, `soc_device`, and secondary IPC statics still leak
  (pre-existing).
- Affects SCU i.MX8 platforms only.

**Unresolved:** lore.kernel.org/stable search blocked (Anubis). Thread
via `b4 dig` had no stable nomination.

**Stable rules:**
1. Obviously correct and tested? **PASS** — standard `devres` unwind;
   maintainer applied it; no NAK.
2. Real bug affecting users? **PASS** — leaked exclusive channels and a
   dangling global IPC handle on failed probe.
3. Important (crash/security/corruption/deadlock)? **PASS** — `-EBUSY`
   probe stall can prevent SCU bring-up; dangling handle is a UAF.
   Severity HIGH, not a happy-path panic.
4. Small and contained? **PASS** — 24 insertions, one file.
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** — context matches; helpers present.

**Exception category:** none; this is a normal error-path leak/UAF fix.

The local tree is 7.3-rc4. The SCU driver and the buggy unmanaged
mailbox/handle pattern are in this lineage (since v4.20). The fix is a
small, correct rollback of probe resources. Remaining gip3/soc_dev gaps
are not a reason to keep the main channel/handle leak.

Verification:
- [Phase 1] Parsed tags: only author + Frank Li SOBs; no Fixes/Reported-
  by/Cc: stable
- [Phase 2] Diff: +24/−1 in `imx_scu_probe()`;
  `devm_add_action_or_reset` for mbox + handle; `of_platform_depopulate`
  on populate failure
- [Phase 2] `devm_of_platform_populate()` on failure does
  `devres_free(ptr)` without depopulate; `of_platform_populate()` still
  sets `OF_POPULATED_BUS` — explicit depopulate is required and not a
  double-free
- [Phase 2] `__mbox_bind_client()` returns `-EBUSY` if `chan->cl` is set
  — verified in `drivers/mailbox/mailbox.c`
- [Phase 3] Blame: bug from `edbee095fafb4` (v4.20-rc1); `git merge-base
  --is-ancestor 55c748d596f84 HEAD` true
- [Phase 3] No Fixes: tag; no follow-up commits on this file
- [Phase 4] `b4 dig -c 55c748d596f84`:
  https://patch.msgid.link/20260616005902.11634-1-pengpeng@iscas.ac.cn
- [Phase 4] `b4 dig -a`: v1 only; `b4 dig -w`: Frank Li / Sascha Hauer /
  imx list CC’d
- [Phase 4] mbox: Frank Li “Applied, thanks!”; Sashiko noted pre-
  existing gaps, no NAK
- [Phase 4] lore.kernel.org/stable: UNVERIFIED (bot challenge)
- [Phase 5] Callers of `imx_scu_get_handle()` span clk, pd, net,
  thermal, rtc, drm, etc.
- [Phase 6] `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion`: 7.3.0-rc4; buggy probe exists in parent of this commit
- [Phase 8] Failure mode: mailbox leak → stuck probe / dangling handle
  UAF; severity HIGH

**YES**

 drivers/firmware/imx/imx-scu.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index 8c28e25ddc8a6..28d745ae06067 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -82,6 +82,17 @@ static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = {
 
 static struct imx_sc_ipc *imx_sc_ipc_handle;
 
+static void imx_scu_free_mbox_chan(void *data)
+{
+	mbox_free_channel(data);
+}
+
+static void imx_scu_clear_handle(void *data)
+{
+	if (imx_sc_ipc_handle == data)
+		imx_sc_ipc_handle = NULL;
+}
+
 static inline int imx_sc_to_linux_errno(int errno)
 {
 	if (errno >= IMX_SC_ERR_NONE && errno < IMX_SC_ERR_LAST)
@@ -321,6 +332,11 @@ static int imx_scu_probe(struct platform_device *pdev)
 		dev_dbg(dev, "request mbox chan %s\n", chan_name);
 		/* chan_name is not used anymore by framework */
 		kfree(chan_name);
+
+		ret = devm_add_action_or_reset(dev, imx_scu_free_mbox_chan,
+					       sc_chan->ch);
+		if (ret)
+			return ret;
 	}
 
 	sc_ipc->dev = dev;
@@ -328,6 +344,9 @@ static int imx_scu_probe(struct platform_device *pdev)
 	init_completion(&sc_ipc->done);
 
 	imx_sc_ipc_handle = sc_ipc;
+	ret = devm_add_action_or_reset(dev, imx_scu_clear_handle, sc_ipc);
+	if (ret)
+		return ret;
 
 	ret = imx_scu_soc_init(dev);
 	if (ret)
@@ -340,7 +359,11 @@ static int imx_scu_probe(struct platform_device *pdev)
 
 	dev_info(dev, "NXP i.MX SCU Initialized\n");
 
-	return devm_of_platform_populate(dev);
+	ret = devm_of_platform_populate(dev);
+	if (ret)
+		of_platform_depopulate(dev);
+
+	return ret;
 }
 
 static const struct of_device_id imx_scu_match[] = {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (36 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] firmware: imx: scu: manage mailbox channels and global handle Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.15] net: stmmac: raise TX completion interrupt at the end of an xmit burst Sasha Levin
                   ` (10 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Brian Masney, Sasha Levin, y.oudjana, sboyd,
	bmasney+clk, jbrunet+clk, matthias.bgg, angelogioacchino.delregno,
	linux-clk, linux-mediatek, linux-kernel, linux-arm-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 096ab64a0e69460bfb3557d09e17d2933280a1c6 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
vdecsys driver is present here; the change is a one-line
`MODULE_DEVICE_TABLE(of, ...)` so OF module aliases are generated.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: [clk: mediatek] [add] [missing MODULE_DEVICE_TABLE() for
mt6735-vdecsys]

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: Pengpeng Hou \<pengpeng@iscas.ac.cn\> (author)
- Reviewed-by: Brian Masney \<bmasney@redhat.com\> (clk co-maintainer;
  also committed the patch)
- Signed-off-by: Brian Masney \<bmasney@redhat.com\>
- No Fixes:, Reported-by:, Tested-by:, Link:, or Cc: stable
- Ignore any pipeline-added Sasha Levin SOB (none on this commit)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- Bug: OF match table is wired to `.of_match_table` but not exported
  with `MODULE_DEVICE_TABLE()`, so modpost does not emit `of:` aliases.
- Symptom: when `CONFIG_COMMON_CLK_MT6735_VDECSYS=m`, udev/kmod cannot
  autoload `clk-mt6735-vdecsys.ko` from the DT compatible string;
  vdecsys clocks/resets never register unless the module is loaded by
  hand.
- Version info: none in the message. Driver introduced in
  `0bd9b1211f741` (contained in v6.13-rc1); this fix is contained in
  v7.3-rc1.
- Root cause: omission at driver introduction, not a later regression.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. It is an explicit autoload/alias publication fix.
Author calls it a “source-level fix” with no hardware reproduction; that
is accurate (the missing macro is visible in the file) and does not make
the bug theoretical.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/clk/mediatek/clk-mt6735-vdecsys.c` (+1 / -0)
- Function/data: file-scope after `of_match_mt6735_vdecsys[]`
- Scope: single-file, one-line surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Before: match table exists and is used for in-kernel platform
matching, but no module alias is published. After:
`MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)` aliases the table for
`file2alias`/modpost. Affects the modular autoload path only;
probe/remove logic is unchanged.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: [Hardware enablement / module autoload] `MODULE_DEVICE_TABLE` is
the OF analog of exporting PCI/USB IDs. Without it, `modules.alias`
lacks `of:N*T*Cmediatek,mt6735-vdecsys`. Platform matching still works
if the module is already loaded or built-in.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct; matches the established MediaTek clk pattern
(`65c9ad77cbc0e` “Add MODULE_DEVICE_TABLE() where appropriate”).
Compile-time alias generation only; no locking, no API, no runtime path
change. Regression risk is negligible. Sibling `clk-mt6735-imgsys.c` /
`clk-mt6735-mfgcfg.c` still lack the macro in this tree; that does not
make this hunk wrong.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: Match table from `0bd9b1211f741` (Yassine Oudjana, 2024-11-06;
contained in v6.13-rc1). `MODULE_DEVICE_TABLE` line is this commit
`096ab64a0e694`. Bug present from first introduction of the driver.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag on this commit. A later unrelated series (`[PATCH
07/32] clk: mediatek: mt6735: Add missing MODULE_DEVICE_TABLE()`) cited
`Fixes: 0bd9b1211f74` for the same omission across four files. Intro
commit is an ancestor of HEAD.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Only two commits on this file: intro + this fix. Sibling same-
day commit `36cf8d279ff90` does the same for vencsys. Standalone for
vdecsys; no prerequisite refactor.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Pengpeng Hou is not the MT6735 clk maintainer (that is Yassine
Oudjana). Same-day vencsys twin plus several other `MODULE_DEVICE_TABLE`
additions (rtc, vdpa, watchdog). Brian Masney, clk co-maintainer,
reviewed and applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None. Macro has long existed in `include/linux/module.h`.
Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore/msgid:
  https://patch.msgid.link/20260704124450.11035-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: v1 only, applied as submitted
- Thread (mbox): author post + Brian Masney `Reviewed-by:` on
  2026-07-06. No NAK, no stable nomination, no requested revisions.
- WebFetch of lore/spinics: 403/500; thread recovered via `b4 dig -m`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): linux-clk, linux-mediatek, Stephen Boyd, Brian
Masney, AngeloGioacchino Del Regno, Matthias Brugger, Yassine Oudjana.
Review came from clk co-maintainer Brian Masney.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, no bugzilla/syzbot. Author states source-level
evidence only. No in-tree DTS uses `mediatek,mt6735-vdecsys` (binding
only in `Documentation/devicetree/bindings/clock/mediatek,syscon.yaml`).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Twin vencsys patch applied in the same pile. Later 07/32 series
(Akari Tsuyukusa, Aug 2026) would have covered
imgsys+mfgcfg+vdecsys+vencsys together; vdecsys/vencsys were already
fixed here. This commit does not depend on that series.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No dedicated stable thread found for this subject. UNVERIFIED
whether an AUTOSEL pick already exists; that must not drive the verdict.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: No function body changed. Added `MODULE_DEVICE_TABLE` next to
`of_match_mt6735_vdecsys`. Driver uses `mtk_clk_simple_probe` /
`mtk_clk_simple_remove` via `module_platform_driver`.

**Step 5.2: TRACE CALLERS**
Record: Probe is invoked by the platform core when a device matches
`mediatek,mt6735-vdecsys`. Autoload (udev/kmod) is the path that was
broken for `=m`. Built-in (`=y`) matching already worked via
`.of_match_table`.

**Step 5.3: TRACE CALLEES**
Record: `mtk_clk_simple_probe()` (`drivers/clk/mediatek/clk-mtk.c`)
registers the vdecsys gates and resets from `vdecsys_clks`. Unchanged by
this patch.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: DT node `compatible = "mediatek,mt6735-vdecsys"` → (modular)
udev alias lookup → `clk-mt6735-vdecsys.ko` → platform probe → video-
decoder clocks. Reachable on MT6735 boards that describe that syscon; no
in-tree board DTS. Unprivileged userspace cannot trigger it except by
loading the module.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Most MediaTek clk drivers already have `MODULE_DEVICE_TABLE`.
MT6735 core clocks (apmixedsys/infracfg/pericfg/topckgen) have it;
imgsys and mfgcfg in this tree still do not. Same class of omission as
the 2023 sweep `65c9ad77cbc0e`.

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. File exists; driver from `0bd9b1211f741` (v6.13-rc1).
Kconfig `COMMON_CLK_MT6735_VDECSYS` is **tristate**, Makefile maps it to
`clk-mt6735-vdecsys.o`. HEAD already contains `096ab64a0e694`
(v7.3-rc1); the pre-fix omission is the code this candidate addresses.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. One added line at a stable match-table site; no
refactor around it.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This exact line is present (commit `096ab64a0e694`). No
alternate fix. imgsys/mfgcfg still missing aliases — separate omissions.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: [drivers/clk/mediatek] [PERIPHERAL] — SoC-specific video-decoder
clock/reset driver for MT6735 (Helio T1 era). Not core mm/net/fs.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: MediaTek clk is actively developed; this file itself is quiet
(two commits). MT6735 clk is listed Maintained (Yassine Oudjana).

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Users of MT6735 with `CONFIG_COMMON_CLK_MT6735_VDECSYS=m`. No
in-tree defconfig enables `COMMON_CLK_MT6735`; no in-tree DTS
instantiates the node. Built-in builds are unaffected.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Boot/enumeration with the DT node while the driver is a module.
Not a race. Not unprivileged-exploitable. Workaround: `modprobe clk-
mt6735-vdecsys` or build `=y`.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Video-decoder clocks/resets never appear unless the module is
loaded manually → decode/VPU consumers fail clock lookup. Not
panic/UAF/corruption. Severity: MEDIUM for modular MT6735 vdec; LOW
overall population. Failure is “device feature does not come up,” same
class as missing device IDs.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: Benefit: modular autoload for this clock controller. Risk: very
low (one compile-time alias line). Ratio: favorable because risk is
essentially zero.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real autoload bug on a tristate, `module_platform_driver` clock driver
- One-line, obviously correct, clk co-maintainer Reviewed-by + applied
- Same class as device-ID / quirk enablement (OF alias publication)
- Established MediaTek clk precedent (`65c9ad77cbc0e`: “allow auto-load
  at boot”)
- Zero runtime/API/locking risk; applies cleanly
- Buggy driver exists in this 7.3 tree (since v6.13)

AGAINST:
- Not crash/security/corruption/deadlock
- No user report or hardware test
- Niche SoC; no in-tree DTS/defconfig
- Built-in configs already work
- Author framed it as source-level only

UNRESOLVED:
- Whether AUTOSEL/stable already discussed this hash (lore.kernel.org
  stable search not useful)
- Direct fetch of lore HTML (403)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one-line alias export;
   reviewed by clk co-maintainer. No HW test, but correctness does not
   depend on runtime.
2. Fixes a real bug that affects users? **PASS** — modular OF autoload
   is broken by construction when the table is not exported.
3. Important issue? **PASS** (MEDIUM) — hardware clocks do not come up
   on the intended modular path; same practical class as missing device
   IDs, not a panic.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — publishes an existing match
   table.
6. Can apply to the local tree? **PASS** — file and match table exist;
   hunk is identical.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Device-ID / module-alias publication for an existing driver (OF
`MODULE_DEVICE_TABLE`). That exception applies.

**Step 9.4: MAKE YOUR DECISION**
The bug is real for `=m` builds, the fix is trivial and already the
subsystem’s standard pattern, and this tree has the driver. Conservative
stable practice still takes this class because the downside is nil and
the upside is the driver actually binding.

===============================================================
What the commit solves, and why it matters here
===============================================================

Without `MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)`, modpost
never emits the `of:N*T*Cmediatek,mt6735-vdecsys` alias. On this tree
the Kconfig is tristate, so a modular vdecsys driver will not autoload;
video-decoder clocks and resets never register until someone loads the
module by name. Built-in matching via `.of_match_table` was already
fine.

It meets stable rules: obviously correct, one line, no new API, no
dependencies, and it is the OF equivalent of adding a device ID to an
existing driver. Risk is compile-time alias generation only.

Concerns: no in-tree board uses this compatible, no reporter, not a
crash. Those lower breadth of impact; they do not make the hunk unsafe
or non-bugfix.

Verification:
- [Phase 1] Parsed commit `096ab64a0e694`: SOB Pengpeng Hou; Reviewed-
  by/SOB Brian Masney; no Fixes/Reported-by/Cc: stable
- [Phase 2] Diff: +1 `MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)`
  in `clk-mt6735-vdecsys.c`
- [Phase 3] `git blame`: match table from `0bd9b1211f741`; `git describe
  --contains` intro v6.13-rc1, fix v7.3-rc1
- [Phase 3] `git merge-base --is-ancestor 0bd9b1211f741 HEAD` and
  `096ab64a0e694 HEAD`: both true
- [Phase 3] `git log --oneline -- drivers/clk/mediatek/clk-
  mt6735-vdecsys.c`: only intro + this fix
- [Phase 3] Sibling `36cf8d279ff90` vencsys same change; earlier sweep
  `65c9ad77cbc0e`
- [Phase 4] `b4 dig -c 096ab64a0e694`: msgid
  `20260704124450.11035-1-pengpeng@iscas.ac.cn`; v1 only
- [Phase 4] `b4 dig -m`: Brian Masney Reviewed-by; no NAK/stable
  discussion
- [Phase 4] WebFetch lore/spinics: 403/500; used mbox instead
- [Phase 5] Kconfig `COMMON_CLK_MT6735_VDECSYS` tristate; Makefile
  builds `clk-mt6735-vdecsys.o`; probe is `mtk_clk_simple_probe`
- [Phase 5] `MODULE_DEVICE_TABLE` in `include/linux/module.h` creates
  file2alias symbol
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` = 7.3.0-rc4
- [Phase 6] No in-tree dts/dtsi for mt6735-vdecsys; binding listed in
  `mediatek,syscon.yaml`
- [Phase 6] No defconfig sets `COMMON_CLK_MT6735`
- [Phase 6] imgsys/mfgcfg still lack MODULE_DEVICE_TABLE (verified by
  grep)
- [Phase 7] MAINTAINERS: COMMON CLK FRAMEWORK includes Brian Masney;
  MT6735 CLOCK maintained by Yassine Oudjana
- [Phase 8] Failure mode: modular autoload miss → vdec clocks absent;
  severity MEDIUM/narrow
- UNVERIFIED: whether stable@ already queued this hash; lore stable
  search did not return this commit

**YES**

 drivers/clk/mediatek/clk-mt6735-vdecsys.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt6735-vdecsys.c b/drivers/clk/mediatek/clk-mt6735-vdecsys.c
index 8817085fc1db4..d53ebf92e878d 100644
--- a/drivers/clk/mediatek/clk-mt6735-vdecsys.c
+++ b/drivers/clk/mediatek/clk-mt6735-vdecsys.c
@@ -63,6 +63,7 @@ static const struct of_device_id of_match_mt6735_vdecsys[] = {
 	{ .compatible = "mediatek,mt6735-vdecsys", .data = &vdecsys_clks },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys);
 
 static struct platform_driver clk_mt6735_vdecsys = {
 	.probe = mtk_clk_simple_probe,
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] net: stmmac: raise TX completion interrupt at the end of an xmit burst
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (37 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
                   ` (9 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Johan Alvarado, Jakub Kicinski, Sasha Levin, maxime.chevallier,
	andrew+netdev, davem, edumazet, pabeni, mcoquelin.stm32,
	alexandre.torgue, netdev, linux-stm32, linux-arm-kernel,
	linux-kernel

From: Johan Alvarado <contact@c127.dev>

[ Upstream commit d21a374995df9d7cfd193427748a19dcc87956a9 ]

The TX mitigation logic only sets the Interrupt on Completion bit once
every tx_coal_frames descriptors (STMMAC_TX_FRAMES = 25), with the
tx_coal_timer hrtimer (STMMAC_COAL_TX_TIMER = 5000 us) as the only
fallback. TX skbs are freed exclusively from the TX completion path,
so any flow that keeps fewer than 25 frames in flight has all of its
skbs held for up to 5 ms after transmission.

Paced flows never queue enough frames to reach the frame threshold:
TCP Small Queues caps the amount of unfreed data at roughly two pacing
intervals worth, which at moderate pacing rates is only a couple of
packets. Every small burst then stalls until the coalesce timer fires,
and throughput collapses to approximately tsq_limit / tx_coal_timer
regardless of link capacity.

This is easily reproducible with BBR, which paces its output and thus
keeps only a few frames in flight at a time. On a YT6801
(dwmac-motorcomm) equipped Orange Pi 5 Pro, a BBR upload over a ~23 ms
RTT path is capped at 5.24 Mbit/s, while CUBIC reaches 207 Mbit/s on
the same path. BBR measures the stalled send rate as the path
bandwidth and locks its estimate near the floor, so the connection
never recovers. Lowering the coalesce settings with ethtool -C
(tx-usecs 100 tx-frames 1) lifts the same transfer to 447 Mbit/s,
confirming the mechanism.

Fix this by setting the IC bit on the last descriptor of every xmit
burst, i.e. whenever netdev_xmit_more() reports that no further frames
are pending in the current dequeue batch. Frame-based coalescing still
applies within a burst, bulk traffic keeps batching through qdisc bulk
dequeue and NAPI polling, and the coalesce timer becomes a pure
fallback instead of the primary completion mechanism for lightly
queued flows.

tx-frames 0 keeps its meaning of timer-based mitigation only.

Signed-off-by: Johan Alvarado <contact@c127.dev>
Link: https://patch.msgid.link/20260731194522.55069-1-contact@c127.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.12.111**. The TX-coalesce stall is in this
checkout; the four-line IC-on-burst-end change is a real, tested fix for
a severe paced-TCP collapse on stmmac.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [net: stmmac] [raise] [set TX Interrupt-on-Completion on the
last descriptor of each xmit burst so lightly queued/paced flows are not
stuck on the 5 ms coalesce timer]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Link: https://patch.msgid.link/20260731194522.55069-1-contact@c127.dev
- Signed-off-by: Johan Alvarado \<contact@c127.dev\> (author)
- Signed-off-by: Jakub Kicinski \<kuba@kernel.org\> (netdev maintainer,
  applied)
- No Reported-by / Tested-by / Reviewed-by / Acked-by / Cc: stable in
  the committed message
- No Fixes: in the committed message (expected for this pipeline)

Original mailing-list submission (v1 and RESEND) DID carry:
- Fixes: da2024510031 ("net: stmmac: Tune-up default coalesce settings")
That tag is treated as technical evidence of the introducing commit, not
as a “already selected for stable” marker.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: TX IC is set only every `tx_coal_frames` descriptors (default
  25). The 5 ms `tx_coal_timer` is the only fallback. TX skbs are freed
  only from the completion path, so a flow with fewer than 25 frames in
  flight holds those skbs for up to 5 ms.
- Symptom: TCP Small Queues + pacing (BBR) never queues 25 frames. Each
  small burst waits for the timer. Throughput collapses to ~tsq_limit /
  tx_coal_timer. BBR then treats that stalled rate as path bandwidth and
  never recovers.
- Measured on Orange Pi 5 Pro / YT6801: BBR 5.24 Mbit/s vs CUBIC 207
  Mbit/s; ethtool `-C tx-usecs 100 tx-frames 1` raises the same transfer
  to 447 Mbit/s.
- Root cause: coalescing designed for deep queues; lightly queued flows
  only complete via the timer.
- Fix: set IC when `!netdev_xmit_more()` (end of current dequeue batch).
  Frame coalescing still applies inside a burst; `tx-frames 0` stays
  timer-only.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. Submitted as `[PATCH net]` (bugfix
tree, not net-next). It is a logic/correctness fix for TX completion
starvation interacting with TSQ, not a style change.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/net/ethernet/stmicro/stmmac/stmmac_main.c`
- +4 / −0 (two identical two-line insertions)
- Functions: `stmmac_tso_xmit()`, `stmmac_xmit()`
- Scope: single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before (both functions): set_ic if HW timestamp, else if
  `tx_coal_frames==0` never set IC, else if this skb’s descriptor count
  exceeds the threshold, else if the running modulo wrapped, else false.
  Then arm the 5 ms timer.
- After: same, plus `else if (!netdev_xmit_more()) set_ic = true`
  immediately after the `tx_coal_frames==0` check, so the last skb of a
  dequeue batch gets IC unless the user asked for timer-only (`tx-frames
  0`).
- Path: normal `ndo_start_xmit`, not an error/init path.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- Category: logic / correctness (TX completion starvation vs TCP Small
  Queues)
- Mechanism: IC density was bounded by frame count only. Paced flows
  never reach 25 in-flight frames, so completion waits for the hrtimer.
  TSQ will not queue more until skbs are freed, so send rate is timer-
  capped. Setting IC on burst end completes those skbs promptly; intra-
  burst coalescing and the timer remain as fallback.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: `netdev_xmit_more()` is the standard “more packets
  in this dequeue” signal; many other NIC drivers already use it this
  way. Placement after `!tx_coal_frames` preserves timer-only mode.
- Minimal: four lines, no API/data-structure change.
- Regression risk: more TX IRQs on short bursts. Author measured ~3.3k
  IRQs/s (~12 packets/IRQ) at 447 Mbit/s. Bulk traffic still coalesces
  inside qdisc bulk dequeue / TSO. XSK/XDP paths intentionally unchanged
  (`netdev_xmit_more()` is not meaningful there; no TSQ). Maciej
  Fijalkowski asked whether coalescing could be dropped entirely; the
  author kept the frame bound so a bulk batch larger than the ring
  cannot drain with zero IC bits. Low regression risk.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Core IC logic: c2837423cb5455 (“net: stmmac: Rework TX Coalesce
  logic”, 2019-11-14)
- `!tx_coal_frames` / per-queue threshold: db2f2842e6f560 (2021-03-17)
- Default TX_FRAMES 1→25: da2024510031 (v5.5-rc1, 2019-11) — this is
  what made “every frame gets IC” into “every 25 descriptors”
- Timer 1 ms→5 ms: 039550960a223 (2023-10-19), present in this tree —
  same stall, worse ceiling
- Buggy pattern has been in tree since ~v5.5; this is long-standing, not
  new-in-6.13+ code

Step 3.2: FOLLOW THE FIXES: TAG
Record:
- Original submission tagged Fixes: da2024510031
- `git merge-base --is-ancestor da2024510031 HEAD` → yes (exit 0)
- That commit only retuned defaults (`STMMAC_TX_FRAMES` 1→25). Combined
  with timer-only fallback, that is exactly the stall.
- Intermediate related work already in this tree: c2837423cb5455
  (rework), 2d1a42cf7f77c (timer arm vs NAPI, 2023), 039550960a223 (5 ms
  timer). None of those set IC at burst end.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Recent `stmmac_main.c` work is TSO descriptor checks, PTP lock init,
  XDP, etc. Nothing equivalent to this IC-on-burst-end change.
- `git log --grep=netdev_xmit_more --
  drivers/net/ethernet/stmicro/stmmac/` → empty; the helper is unused in
  stmmac here.
- Standalone 4-line fix, not patch N/M.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record:
- Johan Alvarado has no prior stmmac commits in this tree (end-user
  reporter/fixer, not the subsystem maintainer).
- Maintainers CC’d on the list: Alexandre Torgue, Jose Abreu. Applied by
  Jakub Kicinski.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record:
- Needs `netdev_xmit_more()` — present in `include/linux/netdevice.h`
  (this tree).
- Needs the existing `set_ic` / `stmmac_set_tx_ic` / `tx_coal_frames`
  block — present in both xmit paths.
- Mainline context uses `CIRC_CNT` / `stmmac_get_tx_desc`; those helpers
  are not required. The added lines sit in context that is identical
  here:
  `else if (!priv->tx_coal_frames[queue]) set_ic = false;`
- Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- b4 dig on the msgid did not resolve a local commit (this SHA is not in
  the 6.12 checkout). Fallback: openwall + patchew.
- v1: 2026-07-06, Message-ID `0100019f35ea26e0-42ad009c-01ab-4a8f-b126-
  fa65fbacae5c-000000@email.amazonses.com`
- RESEND: 2026-07-31, msgid `20260731194522.55069-1-contact@c127.dev`
  after netdev queue overflow (Jakub asked for a repost). Author: no
  code changes vs v1.
- Reviewer Maciej Fijalkowski: agreed each TX batch should get IC at the
  end; asked if coalescing could be dropped. Author explained why the
  frame bound must stay (ring-full with xmit_more set on every frame
  until the queue stops → zero IC → timer stall on the bulk path). Kept
  the patch minimal for `net`.
- No NAK. No reviewer concern that the change is unsafe for the IC-on-
  burst-end approach.
- No explicit “Cc: stable” in the thread. Submitted to `net` as a
  bugfix.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record:
- To/Cc: netdev maintainers (Kicinski, Abeni, Dumazet, Daleck, Lunn),
  stmmac (Torgue, Abreu, Coquelin), Pavel Machek (historical reporter),
  linux-stm32, linux-arm-kernel.
- Substantive review: Maciej Fijalkowski. Applied by Jakub Kicinski.

Step 4.3: SEARCH FOR THE BUG REPORT
Record:
- Concrete iperf3 numbers from the author on real hardware (Orange Pi 5
  Pro).
- Historical same class of bug: Pavel Machek 2016 UDP burst pauses (40
  ms low-res timer); his “disable coalescing” patch was rejected in
  favor of a real solution. hrtimer conversion later fixed resolution
  but left timer-as-only-completion for light flows.
- Severity from reporter: BBR unusable (~5 Mbit/s vs hundreds).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Single standalone patch. Author deferred any coalescing rework
to net-next. XSK/XDP IC logic deliberately not included.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable search returned 403. No evidence on
openwall/patchew that stable rejected this. UNVERIFIED that it was
discussed on stable@ specifically.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `stmmac_tso_xmit`, `stmmac_xmit`. Helper used:
`netdev_xmit_more`. Callee already present: `stmmac_set_tx_ic`.

Step 5.2: TRACE CALLERS
Record:
- `stmmac_xmit` is `ndo_start_xmit` (`stmmac_netdev_ops` at line 7155).
- `stmmac_tso_xmit` is called from `stmmac_xmit` for TSO/GSO packets
  (lines 4529/4531).
- Context: process / softirq xmit (BH off). Userspace sockets, not
  probe-only.

Step 5.3: TRACE CALLEES
Record: `stmmac_set_tx_ic` sets the hardware IC bit;
`stmmac_tx_timer_arm` still runs after xmit (lines 4461 and 4750). Timer
remains the fallback if IC is not set or NAPI is not scheduled.

Step 5.4: FOLLOW THE CALL CHAIN
Record: userspace send/write → TCP → qdisc → `ndo_start_xmit` →
`stmmac_xmit` / `stmmac_tso_xmit`. Reachable on every stmmac Ethernet
device. Unprivileged users who can send on the interface (typical
networked host) trigger it. BBR/pacing makes it easy to hit.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: `netdev_xmit_more()` is already used for doorbell/IC batching in
many drivers in this tree (r8169, mlx5, virtio_net, qede, ionic, sfc,
forcedeth, …). stmmac is the outlier. XSK/XDP in the same file still use
frame-count-only IC; that is intentional and not a missed copy of this
bug (no TSQ).

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. `stmmac_tso_xmit` ~4380–4390 and `stmmac_xmit` ~4645–4655:
same if/else IC logic, no `netdev_xmit_more()` branch. Defaults in this
tree: `STMMAC_TX_FRAMES` 25, `STMMAC_COAL_TX_TIMER` 5000 (`common.h`).
`git describe HEAD` → `p-6.12-2-gd38d58a4e0359`; `make kernelversion` →
6.12.111.

dwmac-motorcomm / YT6801 is not in this tree; that was only the
reporter’s NIC. The bug lives in common `stmmac_main.c`, which 6.12
already uses for dwmac-rk, dwmac-sunxi, dwmac-stm32, dwmac-intel, dwmac-
imx, dwmac-qcom-ethqos, dwmac-ipq806x, dwmac-meson, etc.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Expected apply: clean for the four added lines. Surrounding
mainline helpers (`CIRC_CNT`, `stmmac_get_tx_desc`) differ, but they are
not part of this hunk. Insertion context matches 6.12 exactly.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: 2d1a42cf7f77c (don’t re-arm timer while NAPI is scheduled) and
039550960a223 (5 ms timer) are in this tree. They do not set burst-end
IC. No equivalent fix present.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [net / stmmac Ethernet] [IMPORTANT — not mm/core, but the common
DWMAC driver for a large set of ARM/x86 embedded and laptop NICs]

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Actively maintained (recent TSO, XDP, PTP, FPE fixes). Coalesce
core has been stable since 2019 with only timer-arm tweaks in 2023.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific, but a widely used driver. Anyone using stmmac
with default coalescing and paced/TSQ-limited TCP (BBR is
`CONFIG_TCP_CONG_BBR` in this tree). CUBIC is less affected because it
queues more deeply (207 vs 5 Mbit/s in the report).

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Normal TCP upload with pacing/TSQ and default ethtool coalesce
(tx-frames 25, tx-usecs 5000). Common on WAN/RTT paths, not a rare error
path. Unprivileged users sending data can trigger it. Workaround exists
(`ethtool -C`) but is not discoverable for most users.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: [TCP TX completion stall / order-of-magnitude throughput
collapse; BBR bandwidth lock-in] [HIGH for affected workloads — not a
panic/UAF/corruption, but the NIC is effectively unusable for paced TCP]

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: high for stmmac + BBR/pacing (5 → 447 Mbit/s in the report);
  restores TSQ-friendly completion.
- Risk: low (4 lines, well-known helper, coalescing preserved in-burst,
  `tx-frames 0` unchanged). 2023 ipq806x pain was timer-arm frequency
  under bulk load; this patch does not change timer arming and keeps the
  25-descriptor IC bound so a full ring cannot drain with zero IC.
- Ratio: benefit clearly outweighs risk.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real, measured bug: BBR ~5 Mbit/s vs CUBIC ~207 Mbit/s; ethtool
  experiment confirms mechanism.
- TSQ/pacing vs delayed TX completion is a known correctness class, not
  a micro-optimization.
- Introducing change da2024510031 (TX_FRAMES 1→25) is in this tree since
  v5.5; 5 ms timer (039550960a223) is also here.
- Four-line, obviously correct change; `netdev_xmit_more()` already in
  this tree.
- Applies on identical context in `stmmac_xmit` / `stmmac_tso_xmit`.
- `[PATCH net]`, reviewed, applied by netdev maintainer; reviewer agreed
  IC belongs at batch end.
- Workaround requires non-default ethtool; default shipped settings are
  the broken ones.

AGAINST:
- Not a crash, UAF, deadlock, or security bug.
- Changes IRQ pattern (more interrupts on short bursts).
- Test NIC (dwmac-motorcomm) is not in 6.12 (common-path bug still is).
- Original thread did not Cc stable@.
- 2023 work raised the timer specifically to cut IRQ rate on some SoCs —
  theoretical regression if burst-end IC is too aggressive under bulk
  load. Mitigated by remaining in-burst coalescing and author’s IRQ
  measurements.

UNRESOLVED:
- Could not fetch lore.kernel.org (403) or spinics (500); used
  openwall/patchew instead.
- Could not search stable@ archives (403).
- No follow-up fix SHA in this tree (expected; this commit is not here).

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — 4 lines, list review,
   before/after iperf3, IRQ rate reported.
2. Fixes a real bug that affects users? PASS — paced TCP/TSQ stall with
   measured multi-10x drop.
3. Important issue? PASS — HIGH functional failure of a standard
   congestion controller on a common NIC; not a panic, but the device is
   unusable for that workload at default settings.
4. Small and contained? PASS — +4 lines, one file, two functions.
5. No new features or APIs? PASS — uses existing `netdev_xmit_more()` /
   IC bit.
6. Can apply to the local tree? PASS — buggy code and helper exist;
   insertion context matches.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None of device-ID / quirk / DT / build / docs. Qualifies as a
normal small net driver correctness fix.

Step 9.4: MAKE YOUR DECISION
This is a small, tested fix for a long-standing TX completion stall that
makes paced TCP (notably BBR) collapse on stmmac at default coalesce
settings. The buggy path and the only dependency (`netdev_xmit_more`)
are in 6.12.y. Benefit to stable users is large; regression risk is low.

Verification:
- [Phase 1] Parsed subject/body/tags from the candidate message; Link
  msgid used to find the original `[PATCH net]` / RESEND threads.
- [Phase 1] Original list post (openwall/patchew) still had Fixes:
  da2024510031; committed copy in the pipeline does not.
- [Phase 2] Diff is +4 lines in `stmmac_tso_xmit` and `stmmac_xmit`
  only; both insertions are `else if (!netdev_xmit_more()) set_ic =
  true` after the `tx_coal_frames==0` check.
- [Phase 2] Read local `stmmac_main.c` 4380–4390 and 4645–4667: same IC
  ladder, no xmit_more branch; timer still armed at 4461 and 4750.
- [Phase 2] `STMMAC_TX_FRAMES` 25 and `STMMAC_COAL_TX_TIMER` 5000
  confirmed in `common.h`.
- [Phase 3] `git blame` on those lines: c2837423cb5455 (2019) and
  db2f2842e6f560 (2021).
- [Phase 3] `git merge-base --is-ancestor da2024510031 HEAD` exit 0;
  `git show da2024510031` changed TX_FRAMES 1→25.
- [Phase 3] `git merge-base --is-ancestor 039550960a223 HEAD` exit 0 (5
  ms timer present).
- [Phase 3] `git log --grep=netdev_xmit_more --
  drivers/net/ethernet/stmicro/stmmac/` empty.
- [Phase 3] `git describe HEAD` → p-6.12-2-gd38d58a4e0359; kernelversion
  6.12.111.
- [Phase 4] b4 dig on msgid: no local matching commit (expected).
- [Phase 4] Openwall RESEND and patchew v1: Maciej Fijalkowski review,
  Jakub apply-after-RESEND, no NAK; author kept frame coalescing for
  ring-full IC bound.
- [Phase 4] lore.kernel.org and stable@ fetches: 403. UNVERIFIED on
  stable@ specifically.
- [Phase 5] `stmmac_xmit` is `ndo_start_xmit`; `stmmac_tso_xmit` called
  from it; `netdev_xmit_more()` defined in `include/linux/netdevice.h`
  4989–5002.
- [Phase 5] Grep: many other NIC drivers already use
  `netdev_xmit_more()`; stmmac does not.
- [Phase 6] Grep `netdev_xmit_more` under stmmac: no matches. Grep
  YT6801/dwmac-motorcomm: no matches. Glob `dwmac-*.c`: 25 platform
  files including dwmac-rk, dwmac-ipq806x, dwmac-intel, dwmac-stm32.
- [Phase 6] Insertion context in 6.12 matches the patch;
  CIRC_CNT/get_tx_desc differences are mainline-only context, not
  required.
- [Phase 7] MAINTAINERS: STMMAC ETHERNET DRIVER, Alexandre Torgue / Jose
  Abreu.
- [Phase 8] `CONFIG_TCP_CONG_BBR` exists in `net/ipv4/Kconfig`.
- UNVERIFIED: whether a later mainline follow-up refined this patch (not
  in this tree; lore search blocked).

The stall is in this 6.12 tree, the fix is four obviously correct lines,
and paced TCP is a real user-visible failure at default coalesce
settings.

**YES**

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 63c045616c9b7..7dbb5e9bcb54b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4400,6 +4400,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 		set_ic = true;
 	else if (!priv->tx_coal_frames[queue])
 		set_ic = false;
+	else if (!netdev_xmit_more())
+		set_ic = true;
 	else if (tx_packets > priv->tx_coal_frames[queue])
 		set_ic = true;
 	else if ((tx_q->tx_count_frames %
@@ -4687,6 +4689,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 		set_ic = true;
 	else if (!priv->tx_coal_frames[queue])
 		set_ic = false;
+	else if (!netdev_xmit_more())
+		set_ic = true;
 	else if (tx_packets > priv->tx_coal_frames[queue])
 		set_ic = true;
 	else if ((tx_q->tx_count_frames %
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (38 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.15] net: stmmac: raise TX completion interrupt at the end of an xmit burst Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE() Sasha Levin
                   ` (8 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin, lynxis,
	hkallweit1, davem, edumazet, pabeni, matthias.bgg,
	angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
	linux-mediatek

From: Daniel Golle <daniel@makrotopia.org>

[ Upstream commit 5cc65c01cdc577621d1320f4aa03a1382c5a4a45 ]

mtk_pcs_lynxi_get_state() ignores regmap_read()'s return value; a
failed read leaves bm and adv holding uninitialized stack values
which are then decoded into the reported link state. The regmaps
backing the MT7531 SGMII PCS instances sit on an MDIO bus where
reads can fail. Check both reads and report the link as down on
error; phylink presets state->link before the callback, so a bare
return would leave a failed read reported as link-up.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/fce70657fc03bbaf60a04c0fbf2f418531135c4f.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a real uninitialized-data bug in MediaTek LynxI PCS link
polling, and the buggy path exists in this 6.12 tree. It should be
backported.

## Phase 1: Commit message forensics

**Step 1.1:** Record: `[net: pcs: mtk-lynxi:]` `[check]` `[validate
regmap_read() in mtk_pcs_lynxi_get_state() so failed MDIO reads are not
decoded as link state]`

**Step 1.2:** Record: tags in the candidate message:
- `Signed-off-by: Daniel Golle <daniel@makrotopia.org>` (author; driver
  co-maintainer)
- `Reviewed-by: Andrew Lunn <andrew@lunn.ch>` (netdev/DSA reviewer)
- `Link: https://patch.msgid.link/fce70657fc03bbaf60a04c0fbf2f418531135c
  4f.1785811140.git.daniel@makrotopia.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer)
- No `Reported-by`, `Tested-by`, `Cc: stable` in the candidate text
  (absence is expected)
- Original mailing-list submission **did** include `Fixes: 4765a9722e09
  ("net: pcs: add driver for MediaTek SGMII PCS")`; that tag is not in
  the candidate body

**Step 1.3:** Record: `[Bug: ignored regmap_read() errors leave
`bm`/`adv` uninitialized and phylink decodes them as BMSR/LPA]`
`[Symptom: false or garbage link/speed/duplex; failed read can be
reported as link-up because phylink presets `state->link`]` `[Version:
bug dates to driver introduction]` `[Root cause: MDIO-backed MT7531
SGMII PCS regmaps can fail; output is not written on error]`

**Step 1.4:** Record: `[Not a disguised cleanup. This is an explicit
missing-check / uninitialized-use fix. v2 of the patch added
`state->link = false` after review, because a bare return left phylink's
preset link-up.]`

## Phase 2: Diff analysis

**Step 2.1:** Record: `[drivers/net/pcs/pcs-mtk-lynxi.c: +5 / -2 in
`mtk_pcs_lynxi_get_state()`]` `[single-file surgical fix]`

**Step 2.2:** Record: `[Before: two unchecked `regmap_read()`s, then
`phylink_mii_c22_pcs_decode_state()` on `bm`/`adv`. After: if either
read fails, set `state->link = false` and return; otherwise decode as
before. Error path only.]`

**Step 2.3:** Record: `[Category: initialization / missing return-value
check]` `[Mechanism: failed `regmap_read()` does not write `*val`;
`unsigned int bm, adv` stay uninitialized;
`phylink_mii_c22_pcs_decode_state()` does `state->link = !!(bmsr &
BMSR_LSTATUS)` on that garbage. Fix matches
`phylink_mii_c22_pcs_get_state()`, which already treats read errors as
link-down.]`

**Step 2.4:** Record: `[Obviously correct, 5-line change, no
API/locking/refcount changes.]` `[Regression risk: very low. Worst case
is reporting link-down on a failed register read, which is the intended
fail-safe.]`

## Phase 3: Git history

**Step 3.1:** Record: `[Buggy reads introduced in 4765a9722e0976 ("net:
pcs: add driver for MediaTek SGMII PCS", Daniel Golle, 2023-03-19)]`
`[First appeared in v6.4-rc1; present for the life of this driver]`

**Step 3.2:** Record: `[Fixes target 4765a9722e0976 is an ancestor of
HEAD. No later lynxi get_state error-handling in this tree.]`

**Step 3.3:** Record: `[File history on this tree: 4765a9722e097 (add
driver), 3b2de56a146f3 (neg_mode), 90308679c297f (pcs_disable),
be884c15de370 (MODULE_DESCRIPTION).]` `[Standalone functionally; series
patch 1/6, other patches touch `mt7530.c` only.]` `[Prerequisite already
here: 93d46870c5440 ("net: dsa: mt7530: check bus->read() errors in the
MDIO regmap backend") — after that, a failed MDIO read returns an error
and leaves the output unwritten instead of truncated garbage.]`

**Step 3.4:** Record: `[Daniel Golle is listed as maintainer of MEDIATEK
ETHERNET PCS DRIVER. Related MDIO error-propagation work on mt7530 is by
the same author.]`

**Step 3.5:** Record: `[No missing functions. This tree's
`mtk_pcs_lynxi_get_state()` still has the 6.12 signature (no
`neg_mode`); the check itself is independent. Can apply standalone with
a small context adaptation.]`

## Phase 4: Mailing list

**Step 4.1:** Record: `[Lore thread retrieved via b4 mbox: msgid fce7065
7fc03bbaf60a04c0fbf2f418531135c4f.1785811140.git.daniel@makrotopia.org]`
`[v1 of this remaining-errors series was `[PATCH net 1/4]`; v2 is
`[PATCH net v2 1/6]`. Applied version is v2.]` `[v2 change: set
`state->link = false` because phylink presets link-up (Sashiko
review).]` `[Andrew Lunn Reviewed-by on v1; author kept it on v2 for the
small in-spirit change. No NAKs.]` `[Patchwork bot: applied by Jakub
Kicinski as netdev commit 5cc65c01cdc5.]`

**Step 4.2:** Record: `[To/Cc included Andrew Lunn, Vladimir Oltean,
Russell King, netdev, linux-mediatek, DSA and MediaTek maintainers.
Right audience.]`

**Step 4.3:** Record: `[No syzbot/bugzilla user report. Found during
mt7530 MDIO error-handling review. Still a concrete, reachable bug:
`pcs.poll = true` so this runs from phylink's 1 Hz poll.]`

**Step 4.4:** Record: `[Series: "fix remaining swallowed MDIO access
errors". Patch 1 is the only pcs-mtk-lynxi change and does not depend on
patches 2–6.]` `[Earlier companion 93d46870c5440 / 96e0f5184af69 are
already in this tree.]`

**Step 4.5:** Record: `[UNVERIFIED: lore.kernel.org/stable search
blocked by Anubis. No stable-list discussion found via b4.]`

## Phase 5: Semantic analysis

**Step 5.1:** Record: `[Modified: `mtk_pcs_lynxi_get_state`. Wired as
`.pcs_get_state`.]`

**Step 5.2:** Record: `[Callers: `phylink_mac_pcs_get_state()` → in-band
resolve (`MLO_AN_INBAND`), ethtool `phylink_ethtool_ksettings_get()`,
and MII emulation. `mpcs->pcs.poll = true` so `phylink_fixed_poll` runs
`phylink_run_resolve()` every HZ.]`

**Step 5.3:** Record: `[Callees: `regmap_read`,
`phylink_mii_c22_pcs_decode_state`.]`

**Step 5.4:** Record: `[Reachable from userspace: ethtool link settings,
and continuously while the netdev is up in in-band
SGMII/1000Base-X/2500Base-X.]` `[Hardware: MT7531 DSA ports 5/6
(`mt7531_create_sgmii()` uses an MDIO-backed regmap) and MediaTek SoC
SGMII (`mtk_eth_soc` syscon/MMIO, rarely fails). The MDIO path is the
one that matters.]`

**Step 5.5:** Record: `[Same pattern already handled in
`phylink_mii_c22_pcs_get_state()` and `phylink_mii_c45_pcs_get_state()`
in this tree. Lynx PCS uses those helpers; lynxi did not.]`

## Phase 6: Local tree (6.12.111, `pending-6.12`)

**Step 6.1:** Record: `[Yes. `drivers/net/pcs/pcs-mtk-lynxi.c:98-99`
still has unchecked `regmap_read()` into uninitialized `bm`/`adv`.
Introduced v6.4, present here.]` `[Verified: `git describe HEAD` →
p-6.12-4-gbf6fcdf761abd; `make kernelversion` → 6.12.111.]`

**Step 6.2:** Record: `[Minor context rework, not a semantic fork. This
tree has no `mtk_pcs_lynxi_inband_caps`, no `neg_mode` argument, and
`phylink_mii_c22_pcs_decode_state(state, bmsr, lpa)` not the later 4-arg
form. The 5-line check ports 1:1 into the existing function body.]`

**Step 6.3:** Record: `[No lynxi get_state error-check already present.
Prerequisite MDIO backend error propagation is already here, which is
why this follow-up is needed: failed reads no longer write `*val`.]`

## Phase 7: Subsystem context

**Step 7.1:** Record: `[drivers/net/pcs + consumers in net/dsa/mt7530
and net/ethernet/mediatek]` `[IMPORTANT: common OpenWrt/router SGMII CPU
ports, not core mm/VFS, but production networking]`

**Step 7.2:** Record: `[Driver is mature since v6.4; this file has only
a handful of commits on this tree. Bug is long-standing, newly exposed
as true uninitialized use after the MDIO backend fix.]`

## Phase 8: Impact and risk

**Step 8.1:** Record: `[Driver-specific: MT7531 SGMII (MDIO) and
MediaTek SoC SGMII (MMIO).]`

**Step 8.2:** Record: `[Trigger: failed `regmap_read` on the PCS map.
Common on flaky/timeout MDIO; not every boot. Unprivileged userspace can
observe the result via ethtool/carrier; the poll path runs while the
interface is up.]`

**Step 8.3:** Record: `[Failure mode: uninitialized stack decoded as
link/speed/duplex; false carrier possible because phylink presets
`state->link = 1`.]` `[Severity: HIGH for wrong datapath/carrier on MDIO
error; not a panic. Uninitialized use is the same class as KMSAN-class
bugs.]`

**Step 8.4:** Record: `[Benefit: high for MT7531 in-band SGMII — stops
garbage link state after a bus error, especially now that the backend
returns real errors.]` `[Risk: very low — 5 lines, fail-closed to link-
down.]` `[Ratio: strongly favors backport.]`

## Phase 9: Synthesis

**For backporting:**
- Real bug: uninitialized `bm`/`adv` decoded into phylink link state
- User-visible: false/garbage carrier, speed, duplex; ethtool reports it
- Tiny, obviously correct, matches phylink's own C22 helper
- Reviewed by Andrew Lunn, applied by Jakub Kicinski, written by the PCS
  maintainer
- Buggy code has been in this driver since v6.4 and is in 6.12.111
- Companion to MDIO error-propagation already in this tree
  (93d46870c5440); without this, a failed MT7531 PCS read now leaves
  stack garbage instead of even truncated-but-defined data
- No new API/feature

**Against:**
- Not a crash/UAF/deadlock
- Raw upstream hunk will not apply cleanly (later `neg_mode` /
  `inband_caps` context)
- No external user/syzbot report
- Series 1/6, but this patch does not need 2–6

**Unresolved:** stable-list discussion (lore/stable fetch blocked)

**Stable rules:**
1. Obviously correct and tested? **PASS** — same pattern as
   `phylink_mii_c22_pcs_get_state()`; Reviewed-by Andrew Lunn; merged
2. Fixes a real bug that affects users? **PASS** — wrong link state /
   uninitialized data on MDIO failure for MT7531 SGMII
3. Important issue? **PASS** — uninitialized memory used as live link
   state on a 1 Hz poll; can keep carrier up after a failed read
4. Small and contained? **PASS** — 5 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to this tree? **PASS** — needs a trivial context backport,
   not missing code

**Exception category:** none (normal small correctness fix)

The problem for 6.12 users is that `mtk_pcs_lynxi_get_state()` still
consumes uninitialized stack as BMSR/LPA. Phylink presets `state->link =
1` (`phylink.c:1328`) and this PCS polls every second. After the
already-landed MT7530 MDIO backend fix, a failed read returns an error
and does not fill `*val`, so this is the necessary follow-up. Benefit is
preventing false/garbage link state; risk is a fail-closed link-down on
I/O error.

Verification:
- [Phase 1] Parsed candidate tags; original lore patch had `Fixes:
  4765a9722e09`
- [Phase 2] Diff is 5 lines in `mtk_pcs_lynxi_get_state()` wrapping two
  `regmap_read()`s
- [Phase 2] Confirmed `phylink_mac_pcs_get_state()` sets `state->link =
  1` before the callback
- [Phase 2] Confirmed `phylink_mii_c22_pcs_decode_state()` uses `bmsr`
  for `state->link` and that `phylink_mii_c22_pcs_get_state()` already
  sets `state->link = false` on read failure
- [Phase 3] `git blame` on lines 98–99: 4765a9722e0976; `git describe
  --contains` → v6.4-rc1
- [Phase 3] `git merge-base --is-ancestor 4765a9722e0976 HEAD` succeeded
- [Phase 3] `git merge-base --is-ancestor 93d46870c5440 HEAD` succeeded
  (MDIO backend now returns errors without writing `*val`)
- [Phase 4] `b4 mbox` on the msgid: 8-message thread; series v2 1/6;
  Andrew Lunn Reviewed-by; no NAK
- [Phase 4] Cover letter: this check was added because a failed read can
  now leave output unwritten
- [Phase 4] UNVERIFIED: lore.kernel.org/stable search (Anubis 403)
- [Phase 5] Callers: phylink in-band resolve, ethtool get, 1 Hz
  `link_poll`; consumers `mt7530-mdio.c` and `mtk_eth_soc.c`
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111 on
  `pending-6.12`; unchecked reads still at `pcs-mtk-lynxi.c:98-99`
- [Phase 6] Function signature here lacks `neg_mode`; backport is a
  local 5-line edit
- [Phase 8] Failure mode: uninitialized link state / possible false
  carrier, severity HIGH, not a panic
- UNVERIFIED: whether this SHA is already in some other stable series
  (decision is for this tree only)

**YES**

 drivers/net/pcs/pcs-mtk-lynxi.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 87df3a9dfc9bc..64fb17c189afc 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -110,8 +110,11 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
 	unsigned int bm, adv;
 
 	/* Read the BMSR and LPA */
-	regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	if (regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm) ||
+	    regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv)) {
+		state->link = false;
+		return;
+	}
 
 	phylink_mii_c22_pcs_decode_state(state, neg_mode,
 					 FIELD_GET(SGMII_BMSR, bm),
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (39 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] soc: ixp4xx: qmgr: " Sasha Levin
                   ` (7 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Frank Li, Brian Masney, Peng Fan, Abel Vesa,
	Sasha Levin, abelvesa, sboyd, bmasney+clk, jbrunet+clk, linux-clk,
	imx, linux-arm-kernel, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit e89485455ac49925565061733c0d73d568333fc0 ]

The driver has a match table for the of bus wired into its driver
structure, but the table is not exported with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE() entry so module alias information
is generated for automatic module loading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the driver registration structure, and the missing module alias
publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Link: https://patch.msgid.link/20260704150344.59563-1-pengpeng@iscas.ac.cn
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Local tree

This checkout is **v7.3-rc4-27-gf0100363d8c37** (`VERSION=7 PATCHLEVEL=3
SUBLEVEL=0 EXTRAVERSION=-rc4`). The candidate is `e89485455ac49` (`clk:
imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE()`). The file and
match table exist here; the one-line fix applies as written.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1 — Subject**
- Record: `[clk: imx: imx8qxp-lpcg] [add] [export OF match table via
  MODULE_DEVICE_TABLE so module aliases are generated]`

**Step 1.2 — Tags**
- Record:
  - `Reviewed-by: Frank Li <Frank.Li@nxp.com>` (i.MX)
  - `Reviewed-by: Brian Masney <bmasney@redhat.com>` (Red Hat / clk)
  - `Reviewed-by: Peng Fan <peng.fan@nxp.com>` (i.MX clk)
  - `Link: https://patch.msgid.link/20260704150344.59563-1-
    pengpeng@iscas.ac.cn`
  - `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
  - `Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>` (clk-imx
    maintainer, applied it)
  - No `Fixes:`, no `Reported-by:`, no `Cc: stable` (absence expected)
  - Ignore any Sasha Levin SOB if present (none on the real commit)

**Step 1.3 — Body**
- Record: The OF match table is wired into `platform_driver` but not
  published with `MODULE_DEVICE_TABLE()`. Without that, modpost does not
  emit `of:` aliases, so kmod/udev cannot autoload the module from DT
  compatible strings.
- Symptom: `CONFIG_CLK_IMX8QXP=m` → LPCG clock module does not load from
  DT; consumers never get those clocks unless the module is loaded by
  hand.
- Version info: none in the message.
- Root cause: missing alias publication, not a runtime logic bug. Author
  states it is a source-level finding, not a live hardware repro.

**Step 1.4 — Hidden bug fix?**
- Record: Not disguised. It is a real autoload/modalias bug stated
  plainly. The “source-level” wording means it was found by inspection,
  not that it is theoretical: the table is used and not exported.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1 — Inventory**
- Record: `drivers/clk/imx/clk-imx8qxp-lpcg.c` — **+1 / −0**. One line
  after `imx8qxp_lpcg_match[]`. Surgical, single-file.

**Step 2.2 — Flow**
- Record: Before: `imx8qxp_lpcg_match` is only `of_match_table` (used
  after the module is already loaded). After: same table is also a
  `MODULE_DEVICE_TABLE(of, …)` so file2alias/modpost emits aliases at
  build time. No probe/runtime path change.

**Step 2.3 — Bug mechanism**
- Record: **Hardware/module autoload (OF alias publication)**. Match
  table exists (`fsl,imx8qxp-lpcg-adma/conn/lsio` and `fsl,imx8qxp-
  lpcg`) but is not exported. Same class as adding device IDs: userspace
  cannot match hardware to the module.

**Step 2.4 — Fix quality**
- Record: Obviously correct; matches every other i.MX clk driver that
  already has `MODULE_DEVICE_TABLE(of, …)` (`clk-imx8qxp.c`, `clk-
  imx8mm.c`, etc.). No API, locking, or structural change. Regression
  risk is negligible: `=y` ignores aliases; `=m` only adds autoload.

---

## PHASE 3: GIT HISTORY

**Step 3.1 — Blame**
- Record: Match table from `1e3121bfe51a3` (“clk: imx: add imx8qxp lpcg
  driver”, 2018, in **v5.0-rc1**). Module metadata from `e0d0d4d86c766`
  (“Support building i.MX8QXP clock driver as module”, **v5.10-rc1**).
  `builtin_platform_driver` → `module_platform_driver` in
  `eee377b8f44e7` (2021, Fixes: that module-support commit). The hole
  has been there for the whole modular lifetime of the driver.

**Step 3.2 — Fixes: tag**
- Record: None. Buggy omission is the module-support work
  (`e0d0d4d86c766` / `eee377b8f44e7`). Both are in this tree.

**Step 3.3 — File history**
- Record: Recent file commits are unrelated (pm_runtime, ioremap).
  Sibling `cd21fdcbef3fb` does the same for `clk-imx8qxp.c`. Standalone;
  not “patch X/Y”.

**Step 3.4 — Author**
- Record: Pengpeng Hou also added the same fix for `clk-imx8qxp.c` and
  MediaTek mt6735 clocks. Not the clk-imx maintainer; Abel Vesa applied
  it with three subsystem/vendor reviews.

**Step 3.5 — Dependencies**
- Record: Needs `imx8qxp_lpcg_match`, `module_platform_driver`, and
  `<linux/module.h>`. All present here. Applies as a single line.

---

## PHASE 4: MAILING LIST / EXTERNAL

**Step 4.1 — Original thread**
- Record: `b4 dig -c e89485455ac49` →
  https://patch.msgid.link/20260704150344.59563-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only**, 2026-07-04.
- Review: Peng Fan, Brian Masney, Frank Li: Reviewed-by only. Abel Vesa:
  “Applied, thanks!” No NAK, no stable tag, no risk discussion.

**Step 4.2 — Recipients (`b4 dig -w`)**
- Record: Abel Vesa, Peng Fan, Michael Turquette, Stephen Boyd, Frank
  Li, Sascha Hauer, Fabio Estevam; `linux-clk`, `imx@lists.linux.dev`,
  `linux-arm-kernel`, `linux-kernel`. Right maintainers and lists.

**Step 4.3 — Bug report**
- Record: No Reported-by / bugzilla / syzbot. Inspection-only, as the
  commit says.

**Step 4.4 — Series**
- Record: Standalone 1/1. Related but independent sibling on `clk-
  imx8qxp.c`.

**Step 4.5 — Stable list**
- Record: Thread has no stable nomination. Direct lore.kernel.org
  fetches returned **403**; no separate stable-list discussion verified.

---

## PHASE 5: CODE SEMANTICS

**Step 5.1 — Functions**
- Record: No C function changed. Macro `MODULE_DEVICE_TABLE(of,
  imx8qxp_lpcg_match)` next to the existing `of_device_id` table. Driver
  still uses `module_platform_driver(imx8qxp_lpcg_clk_driver)`.

**Step 5.2 — “Callers”**
- Record: Build-time: `scripts/mod/file2alias.c` looks up
  `__mod_device_table__` and emits `of:` aliases. Runtime: kmod/udev on
  DT `compatible`. Probe path unchanged. Makefile: `clk-imx-lpcg-
  scu-$(CONFIG_CLK_IMX8QXP)` → aliases belong to `clk-imx-lpcg-scu.ko`.

**Step 5.3 — Callees**
- Record: None at runtime. Macro only creates an aliased copy of the
  table for modpost.

**Step 5.4 — Reachability**
- Record: Yes, from userspace/DT: i.MX8QXP/8QM DTS uses `fsl,imx8qxp-
  lpcg` (e.g. `arch/arm64/boot/dts/freescale/imx8qm-ss-*.dtsi`). With
  `=m`, udev should load the module from that compatible. `arm64
  defconfig` has `CONFIG_CLK_IMX8QXP=y`, so the default distro/defconfig
  path is unaffected; custom/distro `=m` is the affected path.

**Step 5.5 — Similar patterns**
- Record: Same missing-table pattern fixed in `clk-imx8qxp.c` and
  several other `drivers/clk/imx/*` files already have
  `MODULE_DEVICE_TABLE`. This was the LPCG outlier.

---

## PHASE 6: THIS TREE

**Step 6.1 — Buggy code here?**
- Record: Yes. Pre-commit parent still has the table without
  `MODULE_DEVICE_TABLE`. Module support is in this tree. Bug dates to
  v5.10 module support (autoload hole after v5.16
  `module_platform_driver`).

**Step 6.2 — Backport difficulty**
- Record: **Clean apply**. Context around the match table matches the
  hunk.

**Step 6.3 — Already fixed another way?**
- Record: No other autoload fix on this file. This commit *is* the fix
  (already upstream in 7.3-rc). No substitute.

---

## PHASE 7: SUBSYSTEM CONTEXT

**Step 7.1**
- Record: `[drivers/clk/imx — i.MX8QXP LPCG] [IMPORTANT for
  i.MX8QXP/8QM; PERIPHERAL vs core kernel]`. Clock provider: if the
  module never loads, LPCG-gated peripherals fail probe.

**Step 7.2**
- Record: clk-imx is active (7.3 pulls). This driver itself is mature
  (2018).

---

## PHASE 8: IMPACT AND RISK

**Step 8.1 — Who**
- Record: Config- and platform-specific: `CONFIG_CLK_IMX8QXP=m` on
  i.MX8QXP/8QM/8DXL SCU clocks. Not universal. Defconfig `=y` does not
  need aliases.

**Step 8.2 — Trigger**
- Record: Boot/enumeration with LPCG DT nodes and the driver as a
  module. Unprivileged users cannot trigger it; it is bring-up/udev.
  Common on modular distro kernels, uncommon on typical vendor `=y`
  images.

**Step 8.3 — Failure mode**
- Record: Module not autoloaded → LPCG clocks missing → dependent
  devices fail probe (UART/DMA/etc. depending on board). Not an
  oops/UAF. Severity **MEDIUM** (functional miss for `=m`), **HIGH** on
  those boards if clocks are modular.

**Step 8.4 — Risk vs benefit**
- Record: Benefit: modular i.MX8QXP clocks actually bind. Risk: **very
  low** (one line of metadata). Ratio favors taking it; same rationale
  as the “add a device ID” stable exception.

---

## PHASE 9: SYNTHESIS

**Step 9.1 — Evidence**

For:
- Real autoload bug: match table used, aliases not published.
- One line, obviously correct, reviewed by NXP i.MX and Red Hat.
- DT hardware uses these compatibles.
- Driver is tristate (`CLK_IMX8QXP`); `module_platform_driver` is
  intentional.
- Same pattern as device-ID publication, which stable explicitly allows.
- Applies cleanly; no new API; no runtime behavior change for `=y`.

Against:
- No user/syzbot report; source-level only.
- Not crash/corruption/security.
- `arm64 defconfig` is `=y`.
- No `Cc: stable` (not a negative by itself).

Unresolved:
- Could not search lore.kernel.org/stable (HTTP 403). Original thread
  had no stable discussion.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — one-line, three reviews,
   maintainer applied.
2. Real bug that affects users? **PASS** — `=m` does not autoload; DTS
   uses the IDs.
3. Important? **PASS** (as device-ID/autoload class; not a panic).
   Missing clocks on modular i.MX8 is user-visible, not trivia.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features/APIs? **PASS** — metadata only.
6. Can apply to this tree? **PASS** —
   file/table/`module_platform_driver` all present.

**Step 9.3 — Exceptions**
- Record: Device-ID / module-alias publication for an existing driver
  (stable exception #1 in spirit).

**Step 9.4 — Decision**
This is a one-line, reviewed autoload fix for a long-standing modular
i.MX8QXP LPCG driver. It matches what stable already takes for device
IDs: hardware described in DT can bind without a manual `modprobe`. Risk
is negligible on this tree.

---

## What the commit solves for this tree

Without `MODULE_DEVICE_TABLE()`, `clk-imx-lpcg-scu.ko` has no
`of:N*T*Cfsl,imx8qxp-lpcg*` aliases. kmod will not load it from DT. LPCG
is a clock provider, so that shows up as missing clocks and failed
consumer probe, not as a crash. The fix only publishes the table the
driver already uses.

It meets the stable bar: obviously correct, tiny, no new API, real
modular-load bug, applies here.

Risk vs benefit: benefit is correct autoload for `CONFIG_CLK_IMX8QXP=m`;
risk is essentially zero.

Concerns: no live repro, default `=y`. That does not outweigh a one-line
alias export that other i.MX clk drivers already have.

---

## Verification
- [Phase 1] `git log -1 e89485455ac49`: tags as above; no
  Fixes/Reported-by/Cc:stable.
- [Phase 2] `git show e89485455ac49`: +1 `MODULE_DEVICE_TABLE(of,
  imx8qxp_lpcg_match)`.
- [Phase 2] Read `clk-imx8qxp-lpcg.c`: table used as `.of_match_table`;
  `module_platform_driver`.
- [Phase 2] `include/linux/module.h`: macro creates `__mod_device_table`
  alias for modpost.
- [Phase 3] `git blame` 350–370: table `1e3121bfe51a3` (v5.0); line
  `e89485455ac49`.
- [Phase 3] `e0d0d4d86c766` in v5.10-rc1 (tristate); `eee377b8f44e7`
  switches to `module_platform_driver`.
- [Phase 3] `git merge-base --is-ancestor e89485455ac49 HEAD` succeeded.
- [Phase 3] Parent file confirmed missing `MODULE_DEVICE_TABLE`.
- [Phase 4] `b4 dig -c/-a/-w` and `b4 dig -m`: v1 thread, three R-b,
  Abel applied; To/Cc = clk + i.MX lists.
- [Phase 4] lore HTTP 403; stable-list search **UNVERIFIED**.
- [Phase 5] `Kconfig`: `CLK_IMX8QXP` tristate; Makefile builds `clk-imx-
  lpcg-scu`.
- [Phase 5] DTS: `fsl,imx8qxp-lpcg` in imx8qm-ss-*.dtsi.
- [Phase 5] defconfig: `CONFIG_CLK_IMX8QXP=y`.
- [Phase 6] `git describe HEAD` / `make kernelversion`: 7.3.0-rc4; buggy
  table present; clean apply.
- [Phase 6] Sibling `cd21fdcbef3fb` is a different file; not required
  for this hunk.
- [Phase 8] Failure mode: no autoload when `=m` — verified from code and
  MODULE_DEVICE_TABLE semantics, not from a hardware log.
- UNVERIFIED: live `=m` boot on i.MX8QXP; lore.kernel.org/stable
  contents.

**YES**

 drivers/clk/imx/clk-imx8qxp-lpcg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
index 1dae3410ee99a..f0cf6cf918992 100644
--- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
@@ -354,6 +354,7 @@ static const struct of_device_id imx8qxp_lpcg_match[] = {
 	{ .compatible = "fsl,imx8qxp-lpcg", NULL },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx8qxp_lpcg_match);
 
 static struct platform_driver imx8qxp_lpcg_clk_driver = {
 	.driver = {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] soc: ixp4xx: qmgr: add missing MODULE_DEVICE_TABLE()
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (40 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] RISC-V: perf: fix resource cleanup on driver probe failure Sasha Levin
                   ` (6 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Linus Walleij, Sasha Levin, kaloz, linux-arm-kernel,
	linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 01479280fa5d4691013bcd64fdfd935117b69769 ]

The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().

Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.

This is a source-level fix.  It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Message-ID: <20260704121851.63805-1-pengpeng@iscas.ac.cn>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: `[soc: ixp4xx: qmgr]` `[add]` add missing
`MODULE_DEVICE_TABLE()` so OF module aliases are generated.

**Step 1.2 — Tags**
Record:
- `Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>` (author)
- `Message-ID: <20260704121851.63805-1-pengpeng@iscas.ac.cn>`
- `Signed-off-by: Linus Walleij <linusw@kernel.org>` (IXP4xx/SoC
  maintainer; applied the patch)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, `Cc: stable`, or `Link:` tags (absence of Fixes/Cc-stable is
  expected for this review)

**Step 1.3 — Body**
Record:
- **Bug:** `ixp4xx_qmgr_of_match[]` is wired to `.of_match_table` but
  not exported via `MODULE_DEVICE_TABLE(of, ...)`.
- **Symptom:** `depmod`/modinfo aliases are not generated, so userspace
  cannot autoload the module from the DT compatible `intel,ixp4xx-ahb-
  queue-manager`.
- **Failure mode:** modular `CONFIG_IXP4XX_QMGR=m` does not bind on DT
  boot unless someone `modprobe`s by hand. Built-in (`=y`) is
  unaffected.
- **Version info:** none in the message. Introduced with DT probe in
  v5.2-rc1.
- **Root cause (author):** source-level omission; no hardware
  reproduction claimed.

**Step 1.4 — Hidden bug fix?**
Record: Not disguised. It is an explicit autoload fix. The “source-level
/ no reproduction” wording is honesty, not cleanup-as-fix.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- File: `drivers/soc/ixp4xx/ixp4xx-qmgr.c` (`+1 / -0`)
- Function/data: `ixp4xx_qmgr_of_match[]` (table, not a function)
- Scope: single-file, one-line surgical change

**Step 2.2 — Code flow**
Record:
- **Before:** OF table exists and is used for in-kernel matching when
  the driver is already loaded/built-in. No `alias=of:N*T*Cintel,ixp4xx-
  ahb-queue-manager` in module metadata.
- **After:** `MODULE_DEVICE_TABLE(of, ixp4xx_qmgr_of_match)` creates the
  `file2alias` alias so kmod/udev can load `ixp4xx-qmgr` from DT.
- Path affected: module-build metadata only; probe/remove/IRQ paths
  unchanged.

**Step 2.3 — Bug mechanism**
Record: **Hardware enablement / missing device-table publication**
(module autoload). Not UAF, leak, race, or crash. Mechanism: missing
`MODULE_DEVICE_TABLE` so OF IDs never reach userspace.

**Step 2.4 — Fix quality**
Record: Obviously correct; this is the standard kernel idiom next to
every OF match table. Minimal, no API change, no locking, no runtime
behavior change for built-in. Regression risk is effectively zero
(`MODULE_DEVICE_TABLE` is a build-time alias attribute).

## Phase 3: Git history

**Step 3.1 — Blame**
Record:
- OF table added in `9e01a00958405` (“soc: ixp4xx: qmgr: Add DT probe
  code”, Linus Walleij, 2019) — first in **v5.2-rc1**.
- `.of_match_table = of_match_ptr(...)` until `526f3f3b102f0`
  (v5.19-rc1) dropped `of_match_ptr()`.
- `MODULE_DEVICE_TABLE` never added until this commit `01479280fa5d4`
  (Pengpeng Hou, 2026-07-04; applied 2026-07-24).
- Buggy omission has been in tree for ~7 years.

**Step 3.2 — Fixes: tag**
Record: No `Fixes:` tag. Implicit parent is `9e01a00958405` (DT probe).
That commit **is** an ancestor of this checkout (`git merge-base --is-
ancestor` succeeded).

**Step 3.3 — File history**
Record: Recent related work is the sibling `f0b93c158aa92` (“soc:
ixp4xx: npe: add missing MODULE_DEVICE_TABLE()”) from the same
author/date. Other nearby commits are `dev_err` cleanup and `remove()`
signature changes — not prerequisites for this one-liner.

**Step 3.4 — Author**
Record: Pengpeng Hou is not the subsystem maintainer; this is one of a
batch of `MODULE_DEVICE_TABLE` additions (ixp4xx npe, aspeed, mediatek,
rtc, vdpa, watchdog, hwmon, fbdev). Maintainer Linus Walleij applied it
(“Patch applied.”).

**Step 3.5 — Dependencies**
Record: Standalone. Requires only the existing `ixp4xx_qmgr_of_match`
table and `<linux/module.h>` (already included). No series dependency
beyond the optional sibling npe patch.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
Record:
- `b4 dig -c 01479280fa5d4` →
  https://patch.msgid.link/20260704121851.63805-1-pengpeng@iscas.ac.cn
- Thread: patch + maintainer reply only. Linus Walleij: “Patch applied.”
  No NAK, no stable nomination, no requested revisions.
- `b4 dig -a` also matched an earlier same-diff series: Liao Chen,
  2024-08-14, `[PATCH -next] soc: ixp4xx/qmgr: fix module autoloading`
  (`20240814031004.3876441-1-liaochen4@huawei.com`). Same patch-id; that
  2024 posting did not land; Hou’s 2026 resend did.
- Lore HTTP fetch returned 403; thread recovered via `b4 dig -m`.

**Step 4.2 — Recipients (`b4 dig -w`)**
Record: To Linus Walleij, Imre Kaloz (historical OpenWrt IXP4xx); Cc
`linux-arm-kernel`, `linux-kernel`. Right maintainer was on To: and
merged it.

**Step 4.3 — Bug report**
Record: No syzbot/bugzilla/`Reported-by`. Author states there is no
dynamic hardware reproduction.

**Step 4.4 — Series**
Record: Not numbered `X/Y`. Parallel sibling `f0b93c158aa92` for
`ixp4xx-npe.c` is independent (same one-line pattern). This qmgr patch
is self-contained.

**Step 4.5 — Stable list**
Record: Unverified. `lore.kernel.org/stable/` fetch returned 403. No
stable discussion found via `b4` or local git.

## Phase 5: Code semantic analysis

**Step 5.1 — Functions**
Record: No function body changed. Data: `ixp4xx_qmgr_of_match[]`. Driver
still registered with `module_platform_driver(ixp4xx_qmgr_driver)`.

**Step 5.2 — Callers / impact surface**
Record:
- Probe via platform/OF: DT node `qmgr: queue-manager@60000000` in
  `arch/arm/boot/dts/intel/ixp/intel-ixp4xx.dtsi` (`compatible =
  "intel,ixp4xx-ahb-queue-manager"`), used by all IXP4xx SoC DTs that
  include that dtsi.
- Consumers of exported qmgr APIs:
  `drivers/net/ethernet/xscale/ixp4xx_eth.c`,
  `drivers/net/wan/ixp4xx_hss.c`,
  `drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c`. Those Kconfigs `depends
  on IXP4XX_QMGR`.
- Reachable on IXP4xx boot when the DT node is present. Not a syscall-
  hot path; device probe / module load.

**Step 5.3 — Callees**
Record: Unchanged. `MODULE_DEVICE_TABLE` expands to a used alias
attribute for `file2alias.c` (see `include/linux/module.h`).

**Step 5.4 — Reachability**
Record: Userspace-reachable only as module autoload (kmod). If
`CONFIG_IXP4XX_QMGR=m`, missing aliases mean the queue manager (and thus
Ethernet/HSS/crypto that need it) will not come up automatically. If
`=y`, this commit is a no-op at runtime.
`arch/arm/configs/ixp4xx_defconfig` has `CONFIG_IXP4XX_QMGR=y` and
`CONFIG_IXP4XX_ETH=y`. Kconfig is still **tristate**, so modular builds
are a supported config.

**Step 5.5 — Similar patterns**
Record: Same omission/fix in `drivers/soc/ixp4xx/ixp4xx-npe.c`
(`f0b93c158aa92`). Same author also added `MODULE_DEVICE_TABLE` in other
SoC drivers the same week.

## Phase 6: Local tree

**Step 6.1 — Does the buggy code exist here?**
Record: Local tree is **v7.3-rc4** (`7.3.0-rc4`, `git describe HEAD` =
`v7.3-rc4-27-gf0100363d8c37`). This is mainline, not an LTS branch. The
OF match table and platform driver exist. `git merge-base --is-ancestor
01479280fa5d4 HEAD` is true — the candidate is already in this checkout.
The pre-fix omission existed from v5.2 until this commit.

**Step 6.2 — Backport difficulty**
Record: Clean apply. One line next to a table that has been stable since
2019. No structural conflict with later `remove()` or `dev_err` changes.

**Step 6.3 — Related fixes already here**
Record: This exact line is already present (`MODULE_DEVICE_TABLE(of,
ixp4xx_qmgr_of_match)` at line 451). Sibling npe fix is also present. No
alternate autoload fix.

## Phase 7: Subsystem context

**Step 7.1**
Record: `drivers/soc/ixp4xx` — Intel IXP4xx (XScale ARMv5) SoC queue
manager. **PERIPHERAL** for the kernel as a whole; **IMPORTANT** on the
boards that still use this SoC (Ethernet/WAN/crypto sit on it).

**Step 7.2**
Record: Low-churn, mature platform. Occasional one-line hygiene/fixes.
Bug is old, not a new-subsystem issue.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: Platform-specific / config-specific: `ARCH_IXP4XX` (or
`COMPILE_TEST`) with `CONFIG_IXP4XX_QMGR=m`. Official defconfig builds
it in, so default distro-style `ixp4xx_defconfig` users never hit this.
Modular custom/OpenWrt-style builds can.

**Step 8.2 — Trigger**
Record: Boot with DT + driver as a module. Not a race. Unprivileged
users cannot trigger a crash; they just don’t get the device until a
manual load. Commonness: low (legacy SoC; defconfig is built-in).

**Step 8.3 — Failure mode**
Record: Module does not autoload → queue manager never probes →
Ethernet/HSS/crypto that depend on it fail to operate. **Severity:
MEDIUM** (device non-function when modular; not
oops/corruption/deadlock). Built-in: none.

**Step 8.4 — Risk/benefit**
Record:
- **Benefit:** Medium for modular IXP4xx users (hardware actually
  binds); low for defconfig/`=y` users.
- **Risk:** Very low (one line, build-time metadata only).
- **Ratio:** Favorable. This is the device-ID class of change: tiny,
  enables existing hardware, no runtime regression surface.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

For:
- Real, well-understood autoload bug: OF table used by the driver but
  not published to userspace.
- One line, idiomatically correct, zero runtime risk.
- DT node is in the SoC dtsi; Ethernet/WAN/crypto depend on this driver.
- Kconfig is tristate; modular builds are supported.
- Bug present since v5.2; applies cleanly; no prerequisites.
- Maintainer applied it; same fix on the sibling NPE driver.
- Official stable rules explicitly allow “just add a device ID”; this is
  the OF equivalent (publish existing IDs for autoload).
- Matches the documented exception for trivial ID/enablement additions.

Against:
- Not a crash, security issue, deadlock, or data-corruption bug.
- Author documents no hardware reproduction.
- No user `Reported-by`.
- `ixp4xx_defconfig` uses `CONFIG_IXP4XX_QMGR=y`, so the official config
  never needs aliases.
- IXP4xx is a legacy, small user population.
- No reviewer `Cc: stable`.

Unresolved:
- Could not read lore.kernel.org over HTTP (403); discussion recovered
  via `b4 dig -m`.
- Could not search the stable mailing list (same 403).

**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — one-line standard idiom;
   maintainer applied it. “Tested” is source-level, which is sufficient
   for this class of change.
2. Fixes a real bug that affects users? **PASS** — modular OF autoload
   is broken; users can still `modprobe` manually, but autoload is the
   supported path.
3. Important issue? **PASS** under the device-ID exception (hardware
   does not bind when built as a module). Not CRITICAL severity.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — metadata only.
6. Can apply to this tree? **PASS** — driver and table exist here; patch
   is already an ancestor of HEAD and would apply to any tree that still
   has the OF table.

**Step 9.3 — Exception category**
Record: **Device ID / module alias publication** for an existing driver
(OF equivalent of adding/exporting a PCI/USB ID). Not a new driver, not
a new API.

**Step 9.4 — Decision**
The local checkout is mainline **v7.3-rc4**. The driver, OF table, and
DT node are all here; the fix is a one-line alias publication with no
runtime risk. That is exactly the class of change stable trees take so
existing hardware keeps working when the driver is modular. Niche
platform and built-in defconfig lower the blast radius; they do not make
the fix incorrect or risky.

---

### What the commit solves for stable users
Without `MODULE_DEVICE_TABLE(of, ...)`, a `CONFIG_IXP4XX_QMGR=m` kernel
never generates `of:N*T*Cintel,ixp4xx-ahb-queue-manager` aliases. On DT
boot the queue manager stays unloaded, so IXP4xx Ethernet/HSS/crypto
that depend on it do not come up. The patch only emits those aliases.

### Rules / risk
Obviously correct, +1 line, no new API, applies cleanly. Benefit is
hardware enablement for modular builds; risk is negligible because
nothing in probe, IRQ, or locking changes.

### Concerns
No hardware reproduction and a tiny user base. Those are not blockers
for this exception class. Sibling NPE change is independent and not
required.

### Verification
- **[Phase 1]** Parsed tags: author Pengpeng Hou; SOB Linus Walleij;
  Message-ID present; no Fixes/Reported-by/Cc-stable.
- **[Phase 2]** Diff: +1 line `MODULE_DEVICE_TABLE(of,
  ixp4xx_qmgr_of_match)` in `drivers/soc/ixp4xx/ixp4xx-qmgr.c`.
- **[Phase 3]** `git blame`: table from `9e01a00958405` (v5.2-rc1); this
  line from `01479280fa5d4`.
- **[Phase 3]** `git merge-base --is-ancestor 9e01a00958405 HEAD` and
  `01479280fa5d4 HEAD`: both true.
- **[Phase 3]** Sibling `f0b93c158aa92` on `ixp4xx-npe.c` same day; not
  a prerequisite.
- **[Phase 4]** `b4 dig -c 01479280fa5d4`: lore URL `https://patch.msgid
  .link/20260704121851.63805-1-pengpeng@iscas.ac.cn`.
- **[Phase 4]** `b4 dig -a`: also matched 2024 Liao Chen posting with
  the same patch-id; Hou 2026 version is what landed.
- **[Phase 4]** `b4 dig -w`: To Linus Walleij and Imre Kaloz; Cc linux-
  arm-kernel, linux-kernel.
- **[Phase 4]** `b4 dig -m`: Walleij reply is “Patch applied.”; no NAK,
  no stable tag.
- **[Phase 4]** WebFetch lore/stable: 403. UNVERIFIED: stable-list
  discussion.
- **[Phase 5]** Callers of qmgr APIs: `ixp4xx_eth.c`, `ixp4xx_hss.c`,
  `ixp4xx_crypto.c`. DT node in `intel-ixp4xx.dtsi`.
- **[Phase 5]** `MODULE_DEVICE_TABLE` in `include/linux/module.h` is an
  alias attribute for `file2alias.c`.
- **[Phase 6]** `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
  `make kernelversion` = `7.3.0-rc4`. File already contains the line.
- **[Phase 6]** Kconfig `IXP4XX_QMGR` is tristate; `ixp4xx_defconfig`
  sets `CONFIG_IXP4XX_QMGR=y`.
- **[Phase 8]** Failure mode: module autoload miss → device never
  probes; severity MEDIUM, not oops.

**YES**

 drivers/soc/ixp4xx/ixp4xx-qmgr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 475e229039e30..e3ad0e0237a77 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -454,6 +454,7 @@ static const struct of_device_id ixp4xx_qmgr_of_match[] = {
         },
 	{},
 };
+MODULE_DEVICE_TABLE(of, ixp4xx_qmgr_of_match);
 
 static struct platform_driver ixp4xx_qmgr_driver = {
 	.driver = {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] RISC-V: perf: fix resource cleanup on driver probe failure
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (41 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] soc: ixp4xx: qmgr: " Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] spi: bcmbca-hsspi: return error from failed controller suspend Sasha Levin
                   ` (5 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Atish Patra, Sashiko AI, Charlie Jenkins, Paul Walmsley,
	Sasha Levin, atish.patra, will, mark.rutland, palmer, aou,
	linux-riscv, linux-arm-kernel, linux-perf-users, linux-kernel

From: Atish Patra <atishp@meta.com>

[ Upstream commit e24a1418e90beac2ef4384bc9b0b5a10f19b806e ]

Sashiko pointed out various UAF and memory leak issues around
pmu_sbi_device_probe() error paths.

If the probe fails, here are list of cleanups needed.
a. Already registered pmu must be freed
b. per cpu IRQ must be released
c. pmu_ctr_list data structure must be freed
d. cpu hotplug state must be cleaned up only if added.

Fix the resource cleanup by reorganizing the code around probe failure.

Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: Atish Patra <atishp@meta.com>
Link: https://patch.msgid.link/20260807-counter_delegation-v9-1-58658104e487@meta.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.12.111** (`pending-6.12`). The buggy probe cleanup is
present here, the patch applies, and it is a real UAF/leak/crash fix — a
YES for this tree.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: `[RISC-V perf / SBI PMU] [fix] [resource cleanup on driver probe
failure]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- `Reported-by: Sashiko AI <sashiko-bot@kernel.org>` — static-analysis
  bot, not a user oops, but it named concrete UAF/leak paths
- `Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>` — RISC-V
  reviewer
- `Signed-off-by: Atish Patra <atishp@meta.com>` — original SBI PMU
  driver author
- `Link: https://patch.msgid.link/20260807-counter_delegation-v9-1-
  58658104e487@meta.com` — **v9 01/20** of the counter-delegation series
- `Signed-off-by: Paul Walmsley <pjw@kernel.org>` — RISC-V maintainer
- No `Fixes:` tag (expected)
- Ignore pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit ...]`
  — none on the real commit `e24a1418e90be`

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `pmu_sbi_device_probe()` error paths leak and leave live
  references to freed objects
- **Needed cleanups:** (a) unregister an already-registered PMU, (b)
  release the per-CPU IRQ, (c) free `pmu_ctr_list`, (d) remove the CPU-
  hotplug instance only if it was added
- **Symptom:** UAF and memory leaks if probe fails after partial setup
- **Root cause:** probe does `goto out_unregister` / `out_free` without
  matching teardown
- **Version info:** none in the message; code dates to 2022–2024

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not disguised. It is an explicit error-path UAF/leak fix.
“Reorganizing probe failure” is the usual `goto` cleanup pattern, not a
refactor-for-its-own-sake.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/perf/riscv_pmu_sbi.c` — **+27 / −6** (33 insertions, 6
  deletions)
- Functions: `pmu_sbi_setup_irqs()`, `riscv_pmu_destroy()`,
  `pmu_sbi_device_probe()`
- Scope: single-file surgical error-path fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:

1. **`pmu_sbi_setup_irqs()`**
   - Before: domain/mapping/request failures return immediately.
     `riscv_pmu_use_irq` can stay **true** even though no IRQ was
     installed. Mapping leaked if `request_percpu_irq()` failed.
   - After: those paths `goto err`, dispose a created mapping, set
     `riscv_pmu_use_irq = false`.

2. **`riscv_pmu_destroy()`**
   - Before: always `cpuhp_state_remove_instance()` even when the
     instance was never added.
   - After: only if `!hlist_unhashed(&pmu->node)`.

3. **`pmu_sbi_device_probe()`**
   - Before: `riscv_pm_pmu_register` / `perf_pmu_register` failures jump
     to `out_unregister` (destroy + `kfree(pmu)` only). Snapshot-alloc
     and cpuhp-add failures also skip `perf_pmu_unregister`. IRQ,
     `hw_events`, and `pmu_ctr_list` never freed.
   - After: `irq_requested` tracks a successful IRQ request. Failures
     before PMU register go to `out_destroy`. Failures after register go
     to `out_unregister` which now calls `perf_pmu_unregister`. Then
     IRQ/percpu/`pmu_ctr_list`/`pmu` are freed.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record: **Error-path resource leak + UAF + NULL deref**, with a logic
fix on the IRQ fallback path.

Verified mechanisms in **this** tree:

| Bug | Mechanism |
|---|---|
| **UAF of registered PMU** | `perf_pmu_register()` then
`pmu_sbi_snapshot_alloc()` or `cpuhp_state_add_instance()` fails →
`kfree(pmu)` while the PMU stays in perf core |
| **NULL deref / list corruption** | `riscv_pmu_destroy()` →
`cpuhp_state_remove_instance()` → `hlist_del()` → `WRITE_ONCE(*pprev,
next)` with `pprev == NULL` on a `kzalloc`’d node |
| **IRQ + cookie UAF** | successful `request_percpu_irq(..., hw_events)`
then later probe fail frees `pmu`/`hw_events` without `free_percpu_irq`
|
| **Leaks** | `alloc_percpu` `hw_events` and `kcalloc` `pmu_ctr_list`
only freed on the new `out_free` |
| **Wrong IRQ flag on success path** | IRQ setup failure is **non-
fatal**; probe continues with `PERF_PMU_CAP_NO_INTERRUPT` but
`riscv_pmu_use_irq` stayed true, so `pmu_sbi_starting_cpu()` can
`enable_percpu_irq(0)` |

**Step 2.4: ASSESS THE FIX QUALITY**

Record: Obviously correct and minimal. `out_unregister` is only reached
after a successful `perf_pmu_register`. `out_destroy` does not
unregister. `hlist_unhashed` matches `cpuhp` (node is hashed only after
successful add). IRQ free happens before `free_percpu(hw_events)`.

Regression risk: **low**. Remaining gaps (sysctl not unregistered;
`sbi_pmu_snapshot_available` static key not disabled) are pre-existing
and not introduced here. They do not make this patch unsafe.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- IRQ error returns: `4905ec2fb7e642` (Atish Patra, 2022-02-18) —
  sscofpmf
- Destroy / `out_unregister`: `e9a023f2b73ac3` (Eric Lin, 2022-07-05) —
  PM notifier
- Snapshot + moving `cpuhp_state_add_instance` **after** register:
  `a8625217a054ca` (Atish Patra, 2024-04-20) — **this is when the
  registered-PMU UAF became real**
- Original `kfree(pmu)`-only `out_free`: `e9991434596f53` (2022-02-18) —
  driver introduction

All of these are ancestors of this 6.12 tree.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No `Fixes:` tag. Buggy code is still in this checkout (see Phase
6).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record (this tree, `git log --oneline -20 --
drivers/perf/riscv_pmu_sbi.c`): overflow-IRQ NULL check, bitmap cmask,
errno/firmware-event fixes. None of those replace this cleanup. `git log
--oneline e24a1418e90be..origin/master -- drivers/perf/riscv_pmu_sbi.c`
only shows later overflow-mask/bitmap work; they do not revert or redo
this cleanup.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Atish Patra wrote the SBI PMU driver (`e9991434596f53`) and the
snapshot code. This is a maintainer-area fix, not drive-by.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: Msgid is `counter_delegation-v9-1`. Patches 2–20 add
Smcsrind/Ssccfg/Smcdeleg and a new PMU path. They are **features**, not
prerequisites. This hunk only uses `hlist_unhashed`,
`perf_pmu_unregister`, `free_percpu_irq`, `irq_dispose_mapping`,
`free_percpu`, `pmu_ctr_list` — all already in 6.12. **Standalone.**
`git show e24a1418e90be | git apply --check` succeeded (offsets only).

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c e24a1418e90be`: matched patch-id; lore URL `https://patch.m
  sgid.link/20260807-counter_delegation-v9-1-58658104e487@meta.com`
- `b4 dig -a`: cleanup first appeared as **v7 01/22** (2026-06-22), then
  **v9 01/20** (committed)
- WebFetch of lore returned **403** (Anubis). Thread was recovered via
  `b4 dig -m /tmp/riscv-pmu-cleanup.mbox`
- No NAK on this patch. Paul Walmsley queued the first ten patches
  (including this one) for `riscv/for-next`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record: Charlie Jenkins `Reviewed-by`. Paul Walmsley applied it.
Recipients are the RISC-V list / maintainers (from msgid and SOBs). No
`Cc: stable` in review.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: Reporter is Sashiko, not syzbot. v9 review of **this** patch
restates remaining **pre-existing** issues (snapshot disable without CPU
pin, static key, sysctl leak, init-time cpuhp leak). It does **not** NAK
the cleanup. The UAF it describes of a registered-then-freed PMU is
exactly what `perf_pmu_unregister` addresses.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Rest of v9 is new ISA / delegation code. Not needed for this
cleanup. Later origin/master commits on this file do not change these
error labels.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable WebFetch also 403. **UNVERIFIED** whether
stable@ already discussed this. Absence of `Cc: stable` is expected for
this review queue.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**

Record: `pmu_sbi_setup_irqs`, `riscv_pmu_destroy`,
`pmu_sbi_device_probe`. Related: `pmu_sbi_starting_cpu`,
`riscv_pmu_alloc`, `pmu_sbi_get_ctrinfo`.

**Step 5.2: TRACE CALLERS**

Record:
- `pmu_sbi_device_probe` — `.probe` of `pmu_sbi_driver`
- Called from `pmu_sbi_devinit()` (`device_initcall`) via
  `platform_device_register_simple(RISCV_PMU_SBI_PDEV_NAME, ...)`
- `pmu_sbi_starting_cpu` / `pmu_sbi_dying_cpu` read `riscv_pmu_use_irq`
  (the flag this patch clears on IRQ setup failure)

**Step 5.3: TRACE CALLEES**

Record: `riscv_pmu_alloc()` does `kzalloc` + `alloc_percpu_gfp` (this
tree, `drivers/perf/riscv_pmu.c`). `pmu_sbi_get_ctrinfo()` `kcalloc`s
`pmu_ctr_list`. `cpuhp_state_remove_instance()` always `hlist_del()`s.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Boot/init on RISC-V with SBI PMU (`CONFIG_RISCV_PMU_SBI`
**default y**). Trigger is probe failure after partial success:
`snapshot_alloc` ENOMEM, `perf_pmu_register` failure,
`cpuhp_state_add_instance` failure, or `cpu_pm_register_notifier`
failure. After a successful `perf_pmu_register` and a later fail,
userspace `perf` can touch a PMU whose `struct riscv_pmu` is already
`kfree`d — **userspace-reachable UAF**.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Same file’s `pmu_sbi_devinit()` still leaks
`cpuhp_setup_state_multi` if `platform_driver_register` fails. Pre-
existing, out of this patch’s scope.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes.** This checkout is 6.12.111; `e24a1418e90be` is **not**
an ancestor (`git merge-base --is-ancestor` exit 1).

Current probe error path (`drivers/perf/riscv_pmu_sbi.c`):

```1462:1468:drivers/perf/riscv_pmu_sbi.c
out_unregister:
        riscv_pmu_destroy(pmu);

out_free:
        kfree(pmu);
        return ret;
```

`riscv_pmu_destroy()` still unconditionally removes the cpuhp instance.
`pmu_sbi_setup_irqs()` still returns without clearing
`riscv_pmu_use_irq` or disposing a mapping.

Bug introduced: leaks since v5.17-era driver; UAF of registered PMU
since snapshot/cpuhp reorder in `a8625217a054ca` (in this tree).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** (`git apply --check` — all 6 hunks succeeded
with −54 line offset). Context differs (`bitmap_copy` vs mainline
`pmu->cmask = cmask`) because 6.12 already has `143668c424772` (counter
mask as bitmap). No rework required.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No equivalent cleanup. Bitmap and overflow-IRQ fixes in this
tree are independent.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**

Record: `drivers/perf` / RISC-V SBI PMU. **IMPORTANT** for RISC-V
(default-on perf), not core-mm/VFS. Not staging.

**Step 7.2: SUBSYSTEM ACTIVITY**

Record: Mature driver (2022) with ongoing RISC-V perf fixes. This is a
long-standing error-path hole, not churn in brand-new code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**

Record: RISC-V systems with `CONFIG_RISCV_PMU_SBI` (default y) and SBI
PMU (QEMU virt, most recent boards). Driver-specific, not universal.

**Step 8.2: TRIGGER CONDITIONS**

Record:
- Common path: probe succeeds — no crash
- Realistic fail: `pmu_sbi_snapshot_alloc()` ENOMEM (page alloc
  GFP_ATOMIC per CPU) **after** `perf_pmu_register`
- IRQ mapping fail with SSCOF/T-Head/Andes: probe **continues**,
  `riscv_pmu_use_irq` wrongly stays true
- Unprivileged user cannot force probe, but **can** open the registered
  `"cpu"` PMU in the failure window

**Step 8.3: FAILURE MODE SEVERITY**

Record:
- Registered PMU then `kfree(pmu)` → **UAF** → HIGH
- `hlist_del` on unhashed node → **oops** → HIGH
- IRQ cookie UAF → HIGH
- One-time leaks if probe dies before register → MEDIUM
- `enable_percpu_irq(0)` on fallback success path → MEDIUM–HIGH

**Step 8.4: RISK-BENEFIT RATIO**

Record:
- **Benefit:** high for RISC-V 6.12 — prevents oops/UAF on probe fail
  and a wrong IRQ flag on a continued probe
- **Risk:** low — ~27 net lines, error path + one flag clear, applies
  cleanly
- **Ratio:** favor backport

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: EVIDENCE**

**FOR:**
- Real UAF: perf-registered PMU freed without unregister (snapshot/cpuhp
  fail after `perf_pmu_register`)
- Real oops: `cpuhp_state_remove_instance` → `hlist_del` with NULL
  `pprev`
- Real IRQ leak/UAF and `pmu_ctr_list`/`hw_events` leaks
- `riscv_pmu_use_irq` left true on non-fatal IRQ setup failure (success-
  path bug)
- Small, obviously correct, reviewed by Charlie Jenkins, authored by the
  driver owner
- Buggy code and helpers exist in 6.12; patch applies cleanly
- Standalone despite being 01/20 of a feature series

**AGAINST:**
- Probe-fail is uncommon (except IRQ-setup fallback, which is not fatal
  and is common on some platforms)
- Incomplete: sysctl, snapshot static key, init-time cpuhp still leak
  (pre-existing)
- RISC-V only
- Reported by an AI bot, not a production oops

**UNRESOLVED:** stable@ thread (lore 403); whether Sashiko had a
concrete reproducer beyond code review.

**Step 9.2: STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — reviewed, applied by RISC-V
   maintainer, logic matches the four listed holes
2. Fixes a real bug that affects users? **PASS** — UAF/oops/leaks in the
   default RISC-V PMU driver
3. Important issue? **PASS** — UAF and NULL deref are HIGH; not a style
   cleanup
4. Small and contained? **PASS** — one file, +27/−6
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — `git apply --check` clean

**Step 9.3: EXCEPTION CATEGORIES**

Record: None. Ordinary bugfix.

**Step 9.4: DECISION**

This 6.12 tree has the buggy probe path. The fix is small, applies, and
closes UAF/oops/leak holes in a default-on RISC-V driver. Remaining
cleanup gaps are not a reason to withhold the part that is correct.

---

## What this means for 6.12 users

On RISC-V with SBI PMU, a failed probe after `perf_pmu_register()`
currently frees `struct riscv_pmu` while perf still holds it, and
`riscv_pmu_destroy()` oopses by deleting an unhashed cpuhp node. The
same path leaks the per-CPU IRQ cookie, `hw_events`, and `pmu_ctr_list`.
IRQ setup failure is treated as non-fatal but leaves `riscv_pmu_use_irq`
set, so hotplug can enable IRQ 0. The patch only rewires those gotos and
frees; it does not pull in counter-delegation.

Risk is low relative to leaving a registered-PMU UAF in a long-term
tree.

---

## Verification

- **[Phase 1]** Parsed tags: Sashiko Reported-by, Charlie Jenkins
  Reviewed-by, Atish Patra + Paul Walmsley SOBs, msgid v9 01/20; no
  Fixes
- **[Phase 2]** Diff: +27/−6 in `riscv_pmu_sbi.c`; IRQ err goto,
  `hlist_unhashed` guard, `perf_pmu_unregister`,
  `free_percpu_irq`/`free_percpu`/`kfree(pmu_ctr_list)`
- **[Phase 2]** Read 6.12 `pmu_sbi_device_probe` lines 1367–1468:
  destroy + `kfree(pmu)` only
- **[Phase 2]** Read `kernel/cpu.c` `__cpuhp_state_remove_instance`:
  always `hlist_del(node)`
- **[Phase 2]** Read `include/linux/list.h` `__hlist_del`:
  `WRITE_ONCE(*pprev, next)` NULL-derefs if never hashed
- **[Phase 2]** Read `__cpuhp_state_add_instance_cpuslocked`:
  `hlist_add_head` only on success
- **[Phase 3]** `git blame` IRQ path `4905ec2fb7e642` (2022); destroy
  `e9a023f2b73ac3` (2022); snapshot/cpuhp order `a8625217a054ca` (2024,
  in this tree)
- **[Phase 3]** `git merge-base --is-ancestor e24a1418e90be HEAD` → not
  in this tree; `e9a023f2b73ac3` / `a8625217a054ca` / `e9991434596f53` →
  in this tree
- **[Phase 3]** Follow-ups on origin/master do not redo this cleanup
- **[Phase 4]** `b4 dig -c e24a1418e90be` → patch.msgid.link v9-1; `-a`
  shows v7 first, v9 applied
- **[Phase 4]** `b4 dig -m`: 31-message mbox; Sashiko comments are pre-
  existing leftovers; Paul queued first ten patches; no NAK
- **[Phase 4]** WebFetch lore/stable: 403 — UNVERIFIED stable-list
  discussion
- **[Phase 5]** Probe from `device_initcall(pmu_sbi_devinit)`;
  `riscv_pmu_alloc` allocates `hw_events`; `pmu_sbi_get_ctrinfo`
  allocates `pmu_ctr_list`
- **[Phase 5]** `pmu_sbi_starting_cpu` uses `riscv_pmu_use_irq` /
  `riscv_pmu_irq`
- **[Phase 6]** `git describe HEAD` → `p-6.12-4-gbf6fcdf761abd`; `make
  kernelversion` → **6.12.111**
- **[Phase 6]** `git apply --check` of `e24a1418e90be`: all hunks OK
- **[Phase 7]** `CONFIG_RISCV_PMU_SBI` default y in
  `drivers/perf/Kconfig`
- **[Phase 8]** Failure mode: UAF of registered PMU + cpuhp oops → HIGH
- **UNVERIFIED:** live user oops; stable@ nomination history

**YES**

 drivers/perf/riscv_pmu_sbi.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 25f3a45dd7869..10f64b7b60c53 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1258,22 +1258,29 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
 					  DOMAIN_BUS_ANY);
 	if (!domain) {
 		pr_err("Failed to find INTC IRQ root domain\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err;
 	}
 
 	riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num);
 	if (!riscv_pmu_irq) {
 		pr_err("Failed to map PMU interrupt for node\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err;
 	}
 
 	ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu", hw_events);
 	if (ret) {
 		pr_err("registering percpu irq failed [%d]\n", ret);
-		return ret;
+		irq_dispose_mapping(riscv_pmu_irq);
+		riscv_pmu_irq = 0;
+		goto err;
 	}
 
 	return 0;
+err:
+	riscv_pmu_use_irq = false;
+	return ret;
 }
 
 #ifdef CONFIG_CPU_PM
@@ -1340,7 +1347,8 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
 		}
 	}
 	riscv_pm_pmu_unregister(pmu);
-	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+	if (!hlist_unhashed(&pmu->node))
+		cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
 }
 
 static void pmu_sbi_event_init(struct perf_event *event)
@@ -1462,6 +1470,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 	struct riscv_pmu *pmu = NULL;
 	int ret = -ENODEV;
 	int num_counters;
+	bool irq_requested = false;
 
 	pr_info("SBI PMU extension is available\n");
 	pmu = riscv_pmu_alloc();
@@ -1490,6 +1499,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_EXCLUDE;
 	}
+	irq_requested = (ret == 0);
 
 	pmu->pmu.attr_groups = riscv_pmu_attr_groups;
 	pmu->pmu.parent = &pdev->dev;
@@ -1508,11 +1518,11 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 
 	ret = riscv_pm_pmu_register(pmu);
 	if (ret)
-		goto out_unregister;
+		goto out_destroy;
 
 	ret = perf_pmu_register(&pmu->pmu, "cpu", PERF_TYPE_RAW);
 	if (ret)
-		goto out_unregister;
+		goto out_destroy;
 
 	/* SBI PMU Snapsphot is only available in SBI v2.0 */
 	if (sbi_v2_available) {
@@ -1553,9 +1563,20 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 	return 0;
 
 out_unregister:
+	perf_pmu_unregister(&pmu->pmu);
+
+out_destroy:
 	riscv_pmu_destroy(pmu);
+	if (irq_requested) {
+		free_percpu_irq(riscv_pmu_irq, pmu->hw_events);
+		irq_dispose_mapping(riscv_pmu_irq);
+		riscv_pmu_irq = 0;
+	}
 
 out_free:
+	free_percpu(pmu->hw_events);
+	kfree(pmu_ctr_list);
+	pmu_ctr_list = NULL;
 	kfree(pmu);
 	return ret;
 }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] spi: bcmbca-hsspi: return error from failed controller suspend
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (42 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] RISC-V: perf: fix resource cleanup on driver probe failure Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] i2c: imx-lpi2c: properly unwind resources on probe failure Sasha Levin
                   ` (4 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Jiawen Liu, Mark Brown, Sasha Levin, william.zhang, kursad.oney,
	jonas.gorski, anand.gore, florian.fainelli, rafal, linux-spi,
	linux-arm-kernel, linux-kernel

From: Jiawen Liu <1298662399@qq.com>

[ Upstream commit faa878d4805ca375738294bc52eae310eb287b16 ]

spi_controller_suspend() can fail if pending transfers cannot stop.
bcmbca_hsspi_suspend() ignored the error and still disabled the
PLL and core clocks.

Return the error before disabling the clocks.

Signed-off-by: Jiawen Liu <1298662399@qq.com>
Link: https://patch.msgid.link/tencent_54F5634545908FBA724E758054BF03953808@qq.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.53** (`v6.18.53-5049-g0f0bdc2b0dffb`, branch
`autosel`). The verdict is only about this checkout: the buggy suspend
path is in `v6.18.53`, and the patch applies cleanly to it.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[spi / bcmbca-hsspi] [return] [propagate
`spi_controller_suspend()` failure instead of disabling clocks and
reporting success]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Fixes:** none (expected for this review pipeline)
- **Reported-by / Tested-by / Reviewed-by / Acked-by:** none on this
  specific patch (sibling Broadcom patches in the same author’s work had
  Acked-by/Reviewed-by from Broadcom)
- **Link:** https://patch.msgid.link/tencent_54F5634545908FBA724E758054B
  F03953808@qq.com
- **Cc: stable:** absent (not a negative signal)
- **Signed-off-by:** Jiawen Liu (author); Mark Brown (SPI maintainer).
  Ignore Sasha Levin SOB (pipeline).
- **[Upstream commit faa878d4805c…]** / pipeline markers: ignored per
  instructions

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `spi_controller_suspend()` can fail when pending transfers
  cannot be stopped; `bcmbca_hsspi_suspend()` ignored that and still
  disabled PLL and core clocks, then returned 0.
- **Symptom:** system suspend is reported successful while SPI clocks
  are gated with the queue possibly still active → MMIO to unclocked
  hardware, incomplete SPI transactions.
- **Version info:** none in the message. Driver added in v6.3; bug
  present from introduction.
- **Root cause:** missing return-value check before clock teardown.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not disguised. It is an explicit PM error-path fix: “Handle X
properly” / missing error check. Real bug, not style.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/spi/spi-bcmbca-hsspi.c` — **+5 / −1**
- Function: `bcmbca_hsspi_suspend()`
- Scope: **single-file surgical fix**

Upstream/context in the provided snippet also shows `remove()`/`#ifdef
CONFIG_PM_SLEEP` around it; the change that actually lands on this tree
is only the suspend return check (parent of `072b287a97bf3` matches
`v6.18.53` for this file, 0-line diff).

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:
- **Before:** `spi_controller_suspend(host)` return ignored →
  `clk_disable_unprepare(pll)` + `clk_disable_unprepare(clk)` → `return
  0`.
- **After:** if `spi_controller_suspend()` fails, return that error
  immediately; clocks stay enabled.
- Path: **system-sleep suspend error path**, not probe/init.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** logic / PM error-path correctness (resource teardown
  while transfers may still be running).
- **Mechanism:** this driver sets `host->transfer_one_message`, so
  registration calls `spi_controller_initialize_queue()` and
  `ctlr->queued = true`. `spi_controller_suspend()` then calls
  `spi_stop_queue()`, which polls up to 500 × ~10 ms (~5 s) and returns
  **`-EBUSY`** if the queue/busy bit never clears. The driver used to
  power down clocks anyway.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Obviously correct and matches the usual SPI driver pattern (e.g.
  `rockchip_spi_suspend()` in this tree).
- Minimal; no API/data-structure changes.
- Regression risk is low. An automated review (sashiko-bot) noted that
  `spi_controller_suspend()` still sets `SPI_CONTROLLER_SUSPENDED` on
  failure, and a failed device suspend does not get `resume()`. That is
  a **pre-existing SPI core quirk** shared by most drivers that already
  check this return. The old path is worse: same flag is set **and**
  clocks are gated. Mark Brown applied the series without requesting an
  unwind.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Ignored `spi_controller_suspend()` + clock disable introduced in
  **`a38a2233f23b5`** (“spi: bcmbca-hsspi: Add driver for newer HSSPI
  controller”, William Zhang, 2023-02-09).
- First appeared: **`v6.3-rc1`**. Present for the entire life of this
  driver, including 6.18.y.

**Step 3.2: FOLLOW THE FIXES TAG**

Record: No Fixes tag. Buggy code is the original driver, not a later
regression.

**Step 3.3: CHECK FILE HISTORY**

Record (this file, newest first):
- `2b580ac54f40f` — modern PM macros (later autosel candidate; **not** a
  prerequisite)
- `072b287a97bf3` — **this** commit
- `148a3f03aec89` — resume-side clock cleanup (**already in v6.18.53**,
  had Fixes + Cc: stable)
- Driver-original suspend path otherwise unchanged since v6.3

Standalone. Cover letter: *“The patches are independent and only touch
the local error paths in each driver.”*

**Step 3.4: CHECK THE AUTHOR’S OTHER COMMITS**

Record: Jiawen Liu submitted a 4-patch SPI PM error-handling series
(atcspi200, **bcmbca-hsspi**, fsl-dspi, nxp-fspi). Additional similar
Broadcom fixes exist for bcm63xx / bcm63xx-hsspi / bcm-qspi. Author is a
regular contributor, not the SPI maintainer. Maintainer **Mark Brown**
applied all 4.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: None. Uses existing `spi_controller_suspend()`. Applies
standalone. Series 2/4 is independent.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c faa878d4805c`: **[PATCH 2/4] spi: bcmbca-hsspi: return
  error from failed controller suspend**
- Thread: https://patch.msgid.link/tencent_54F5634545908FBA724E758054BF0
  3953808@qq.com
- Cover: **[PATCH 0/4] spi: fix PM error handling in several drivers**
  (2026-06-20)
- `b4 dig -a`: **v1 only**; committed version is that v1.
- Human review: no NAK. Mark Brown applied to `spi/for-7.3`
  (git.kernel.org/broonie/spi/c/faa878d4805c).
- sashiko-bot: “permanently wedged in a suspended state” if error is
  propagated (SPI core marks suspended even on `-EBUSY`). No maintainer
  follow-up; patch still applied.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): To Mark Brown; Cc William Zhang, Kursad Oney,
Jonas Gorski, bcm-kernel-feedback-list, Florian Fainelli, linux-spi,
linux-arm-kernel, etc. Right maintainers/lists. No Acked-by on this hunk
(unlike some sibling Broadcom patches).

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No syzbot, bugzilla, or user crash report. Bug is from code
inspection of the ignored return. The same driver’s **resume**
counterpart (`148a3f03aec89`) was user/author-driven with
Fixes+Cc:stable and is already in this tree.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Independent 2/4. Sibling Broadcom suspend-return patches are the
same class, not build/runtime dependencies. Resume clock-disable-on-
failure is already in 6.18.53; this is the suspend-side counterpart.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org returned 403; WebSearch of
`lore.kernel.org/stable` for this subject found **no** stable-specific
discussion. UNVERIFIED that anyone requested or rejected it on stable@;
no evidence of a known reason to skip it.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**

Record: `bcmbca_hsspi_suspend()` (modified). Callees of interest:
`spi_controller_suspend()`, `spi_stop_queue()`,
`clk_disable_unprepare()`.

**Step 5.2: TRACE CALLERS**

Record: Wired via `DEFINE_SIMPLE_DEV_PM_OPS(bcmbca_hsspi_pm_ops, …)` /
`.pm` on the platform driver. Called from the PM core on **system
sleep**, not from syscalls directly. Reachable on BCMBCA boards that
suspend with `CONFIG_SPI_BCMBCA_HSSPI` and `CONFIG_PM_SLEEP`.

**Step 5.3: TRACE CALLEES**

Record:
- `spi_controller_suspend()` → `spi_stop_queue()` if queued; always
  `__spi_mark_suspended()`.
- Then (success only, after this patch) clock disable.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record:
`pm_suspend` → `dpm_suspend` → `bcmbca_hsspi_suspend` →
`spi_controller_suspend` → `spi_stop_queue`.

In-flight work is `bcmbca_hsspi_transfer_one` → `bcmbca_hsspi_do_txrx`
doing `__raw_readl`/`__raw_writel` on `bs->regs`. Yanking clocks while
that runs is a hang/abort/corruption path. Userspace can keep the queue
busy (SPI flash, sensors) across a suspend request.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Most SPI drivers in this tree already check
`spi_controller_suspend()` (dw, tegra, rockchip, qup, pxa2xx, atmel, …).
This driver was an outlier. Same author’s bcm63xx/bcm-qspi patches fix
the same pattern.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes.** `v6.18.53:drivers/spi/spi-bcmbca-hsspi.c` still has:

```c
spi_controller_suspend(host);
clk_disable_unprepare(bs->pll_clk);
clk_disable_unprepare(bs->clk);
return 0;
```

`git merge-base --is-ancestor 072b287a97bf3 v6.18.53` → **not an
ancestor**. Bug introduced in v6.3, still in 6.18.53.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply.** `git diff v6.18.53 072b287a97bf3^ --
drivers/spi/spi-bcmbca-hsspi.c` is empty. No rework needed. Later
“modern PM macros” commit is unrelated and not required.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: Resume-side `148a3f03aec89` **is** in v6.18.53. No other
suspend-error check for this function. This is the missing counterpart,
not a duplicate.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**

Record: **drivers/spi** — Broadcom BCMBCA HSSPI
(`CONFIG_SPI_BCMBCA_HSSPI`, `depends on ARCH_BCMBCA || COMPILE_TEST`).
**PERIPHERAL / platform-specific**, but SPI NOR on those SoCs is often
boot/config flash, so a bad suspend is not cosmetic.

**Step 7.2: SUBSYSTEM ACTIVITY**

Record: SPI core is mature; this driver is small and not heavily
churned. Bug is long-standing (since v6.3), not a brand-new feature.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**

Record: **Platform-specific** — Broadcom BCMBCA (ARM/ARM64 broadband
SoCs: gateways/routers). Only if the HSSPI driver and system sleep are
enabled.

**Step 8.2: TRIGGER CONDITIONS**

Record: System suspend while the SPI queue stays busy for ~5 seconds
(`spi_stop_queue` limit). Uncommon, but exactly the dangerous case
(stuck or long transfer). Not a syzbot syscall crash; can be induced by
userspace SPI activity plus suspend. Unprivileged trigger depends on who
can open the SPI device and who can suspend (typically privileged).

**Step 8.3: FAILURE MODE SEVERITY**

Record:
- Clocks gated while the pump may still MMIO → bus hang, imprecise
  abort, or torn SPI NOR write.
- PM core is told suspend succeeded, so the machine continues into sleep
  with live SPI I/O unclocked.
- **Severity: HIGH** when it hits (corruption/hang); trigger is
  uncommon.

**Step 8.4: RISK-BENEFIT RATIO**

Record:
- **Benefit:** medium-high for BCMBCA devices that suspend; prevents
  clock-off during active SPI. Completes PM error handling already fixed
  on resume in this tree.
- **Risk:** very low (5 lines, standard pattern). Residual:
  `SPI_CONTROLLER_SUSPENDED` can stick if suspend fails (SPI core). That
  already exists for the majority of SPI drivers here; old code still
  set the flag **and** cut clocks.
- **Ratio:** benefit outweighs risk.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: EVIDENCE**

**For backporting:**
- Real PM bug: ignored `-EBUSY` from `spi_controller_suspend()`, then
  clock disable + `return 0`.
- Can unclock MMIO and corrupt in-flight SPI (including flash).
- 5-line, obviously correct, maintainer-applied (Mark Brown).
- Driver and buggy code exist in **this** 6.18.53 tree since v6.3.
- Applies cleanly; no prerequisites.
- Same class as the resume fix already in 6.18.53.
- Aligns this outlier with the rest of the SPI subsystem.

**Against:**
- No user/syzbot report; error path is uncommon (~5 s busy).
- Platform-specific (not all machines).
- Incomplete vs an unwind via `spi_controller_resume()` (SPI core marks
  suspended on failure).
- No Fixes/Cc:stable (expected here; not a reason to reject).

**Unresolved:**
- Could not fetch lore.kernel.org (403). Thread recovered via `b4 dig`
  mbox + LKML/openwall. No stable@ discussion found.

**Step 9.2: STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — applied by SPI maintainer;
   pattern used across `drivers/spi`.
2. Fixes a real bug that affects users? **PASS** — ignored suspend
   failure + clock teardown.
3. Important issue? **PASS** — hang/abort/data corruption on active SPI
   during suspend, not a style tweak.
4. Small and contained? **PASS** — +5/−1, one function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean on v6.18.53.

**Step 9.3: EXCEPTION CATEGORIES**

Record: Not a device-ID/quirk/DT/build/doc exception. Ordinary small
bugfix.

**Step 9.4: DECISION**

This belongs in this 6.18.y tree. The bug is in the tree, the fix is
surgical, and leaving clocks on when the queue cannot stop is the
correct hardware behavior.

---

### Problem for stable users

On Broadcom BCMBCA HSSPI, suspend called `spi_controller_suspend()`
(which can return `-EBUSY` after ~5 s if transfers will not stop) and
then **always** disabled PLL/core clocks and returned success. That can
cut clocks under a live transfer (`bcmbca_hsspi_do_txrx` MMIO). This
tree already fixed the matching resume error path; suspend was still
wrong.

### Stable rules / risk

Meets the rules: real bug, small, no new API, clean apply to 6.18.53.
Risk is a few lines in one PM callback. Benefit is avoiding unclocked
SPI and false-successful suspend.

### Concerns

No extra commits needed. Sashiko’s “stuck SUSPENDED flag” note is a SPI-
core limitation already shared by most drivers; it does not make the old
“disable clocks anyway” path acceptable.

---

Verification:
- [Phase 1] Parsed subject/tags/body from `git show 072b287a97bf3` /
  upstream `faa878d4805c`; no Fixes/Reported-by; Link to msgid; Mark
  Brown SOB
- [Phase 2] Diff: +5/−1 in `bcmbca_hsspi_suspend()`; ignore →
  check/return
- [Phase 2] `spi_controller_suspend()` / `spi_stop_queue()` in
  `drivers/spi/spi.c`: queued controllers can return `-EBUSY`;
  `__spi_mark_suspended()` always runs
- [Phase 2] Driver sets `transfer_one_message`;
  `spi_register_controller()` initializes the queue (`ctlr->queued =
  true`)
- [Phase 3] `git blame 072b287a97bf3^`: buggy lines from `a38a2233f23b5`
  (v6.3-rc1)
- [Phase 3] `git log --oneline -- drivers/spi/spi-bcmbca-hsspi.c`:
  resume fix `148a3f03aec89` already in v6.18.53; this commit not in
  v6.18.53
- [Phase 3] `git merge-base --is-ancestor 072b287a97bf3 v6.18.53` → no;
  `git diff v6.18.53 072b287a97bf3^ -- drivers/spi/spi-bcmbca-hsspi.c` →
  0 lines
- [Phase 3] Author series via `git log --author="Jiawen Liu" --
  drivers/spi/`
- [Phase 4] `b4 dig -c faa878d4805c` / `-a` / `-w` / `-m`: v1 2/4,
  independent series, applied by Mark Brown 2026-06-30; Broadcom/SPI
  lists on Cc
- [Phase 4] Cover letter from lkml.iu.edu: patches independent
- [Phase 4] sashiko-bot mbox msg: SUSPENDED-flag concern; no NAK from
  maintainer
- [Phase 4] lore.kernel.org WebFetch 403; stable@ search found nothing
  relevant — UNVERIFIED no stable@ thread
- [Phase 5] Callers: PM ops only; callees: `spi_controller_suspend`,
  `clk_disable_unprepare`; transfer path uses MMIO
- [Phase 5] Similar pattern already in `spi-rockchip.c` and many other
  SPI drivers
- [Phase 6] `git describe HEAD` → `v6.18.53-5049-g0f0bdc2b0dffb`; `make
  kernelversion` → 6.18.53; buggy suspend in `v6.18.53` file
- [Phase 7] `CONFIG_SPI_BCMBCA_HSSPI` depends on `ARCH_BCMBCA`
- [Phase 8] Failure mode: unclocked SPI MMIO / possible flash
  corruption; trigger = suspend with busy queue for ~5 s
- UNVERIFIED: live user reports of this suspend path; full
  lore.kernel.org HTML (403)

**YES**

 drivers/spi/spi-bcmbca-hsspi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c
index a1ff33f6dc095..50beb8443ea90 100644
--- a/drivers/spi/spi-bcmbca-hsspi.c
+++ b/drivers/spi/spi-bcmbca-hsspi.c
@@ -586,8 +586,12 @@ static int bcmbca_hsspi_suspend(struct device *dev)
 {
 	struct spi_controller *host = dev_get_drvdata(dev);
 	struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
+	int ret;
+
+	ret = spi_controller_suspend(host);
+	if (ret)
+		return ret;
 
-	spi_controller_suspend(host);
 	clk_disable_unprepare(bs->pll_clk);
 	clk_disable_unprepare(bs->clk);
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] i2c: imx-lpi2c: properly unwind resources on probe failure
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (43 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] spi: bcmbca-hsspi: return error from failed controller suspend Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
                   ` (3 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Carlos Song, Frank Li, Andi Shyti, Sasha Levin, aisheng.dong,
	linux-i2c, imx, linux-arm-kernel, linux-kernel

From: Carlos Song <carlos.song@nxp.com>

[ Upstream commit cbd043b00ee3f542c115c8809c4d9a67465c07d5 ]

When probe fails at devm_clk_rate_exclusive_get() or clk_get_rate(),
which occur before runtime PM is initialized, the clocks enabled by
clk_bulk_prepare_enable() are never disabled.

When probe fails after runtime PM is initialized, the previous error
path called pm_runtime_put_sync(), which triggers the runtime suspend
callback. However, due to different clock management strategies on
different SoCs[1] (to avoid deadlocks between the global prepare_lock
and runtime PM), the callback may only disable clocks without
unpreparing them, causing an incomplete unwind.

Introduce a new error label 'clk_disable' to explicitly invoke
clk_bulk_disable_unprepare(). Replace pm_runtime_put_sync() with the
sequence of pm_runtime_disable(), pm_runtime_set_suspended() and
pm_runtime_put_noidle() to bypass the runtime suspend callback during
error recovery. During the LPI2C driver probe phase, clock APIs are
used exclusively to manage clocks. Once probing succeeds, clock
management is handed over to the runtime PM core.

[1] https://lore.kernel.org/all/20251125084718.2156168-1-carlos.song@nxp.com/

Signed-off-by: Carlos Song <carlos.song@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260716071957.2670263-2-carlos.song@oss.nxp.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.12.111** (`pending-6.12`). The buggy probe unwind
is present here; the later SoC-specific clock strategy is not. The leak
is real and the fix is a small error-path change.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[i2c: imx-lpi2c]** **[properly unwind]** probe resources are
not released when `lpi2c_imx_probe()` fails. “Properly unwind” is fix
language (missing cleanup), not a feature.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- **Fixes:** none (expected for this review queue)
- **Reported-by / Tested-by / Acked-by / Cc: stable:** none
- **Reviewed-by:** Frank Li &lt;Frank.Li@nxp.com&gt;
- **Signed-off-by:** Carlos Song &lt;carlos.song@nxp.com&gt; (author);
  Andi Shyti &lt;andi.shyti@kernel.org&gt; (I2C maintainer, merger)
- **Link:** https://lore.kernel.org/r/20260716071957.2670263-2-
  carlos.song@oss.nxp.com
- **Inline [1]:** https://lore.kernel.org/all/20251125084718.2156168-1-
  carlos.song@nxp.com/ (later SoC clock/IRQ RPM split)
- Ignore any pipeline SOBs / “Upstream commit” markers

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** After `clk_bulk_prepare_enable()`, two classes of probe
  failure leak clocks.
  1. Failures **before** RPM init (`devm_clk_rate_exclusive_get()`,
     `clk_get_rate()`): early `return` leaves clocks prepared **and**
     enabled.
  2. Failures **after** RPM init: `pm_runtime_put_sync()` runs
     `lpi2c_runtime_suspend()`, which on this tree only
     `clk_bulk_disable()`s (no unprepare), so the prepare count is left
     elevated.
- **Symptom:** Unbalanced clock prepare/enable. On `-EPROBE_DEFER` the
  prepare count grows on every retry.
- **Root cause:** Probe uses clock APIs; after success, RPM owns
  enable/disable. Error paths mixed the two and did not fully unwind.
- **Version info in message:** none for 6.12. `[1]` is the later
  i.MX8QXP/8QM RPM split (`949f647eff76a`, **not** in this tree).

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not hidden. Explicit resource-leak / incomplete error-path
unwind. Not style cleanup.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/i2c/busses/i2c-imx-lpi2c.c` (+14 / −7)
- **Function:** `lpi2c_imx_probe()` only
- **Scope:** single-file, error-path only

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Hunk 1 (pre-RPM errors):** `return dev_err_probe(...)` after
  exclusive-get / `clk_get_rate()` failure → `goto clk_disable` so
  `clk_bulk_disable_unprepare()` runs.
- **Hunk 2 (post-RPM errors):** `rpm_disable` no longer
  `pm_runtime_put_sync()`. It now `pm_runtime_disable()`,
  `pm_runtime_set_suspended()`, `pm_runtime_put_noidle()`, then falls
  through to `clk_disable` for `clk_bulk_disable_unprepare()`.
- **Success path:** unchanged (`pm_runtime_put_autosuspend()` still
  hands clocks to RPM).

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **Error-path resource leak (clock prepare/enable).**
- Missing `clk_bulk_disable_unprepare()` on early probe failure.
- RPM suspend used as unwind, but in **this** tree
  `lpi2c_runtime_suspend()` is only `clk_bulk_disable()` (since
  `fa39065833dbd`), so prepare is never reversed.
- `clk_disable` is an added put/unprepare, not a double-free: RPM
  suspend is skipped, then clocks are disabled and unprepared once.

Step 2.4: ASSESS THE FIX QUALITY
Record: Surgical and correct for this tree. Same pattern as other probe-
fail RPM unwinds. Success path untouched. Regression risk is low; the
only real risk is pairing `put_sync` with `disable_unprepare` (double-
disable). This patch removes `put_sync` and does one explicit unwind.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record (this checkout):
- Early leak: `4268254a39484` (“Avoid calling clk_get_rate during
  transfer”, 2024-05-06) — **in v6.12**.
- RPM enable/disable-only callbacks: `fa39065833dbd` (2023) — **in
  v6.12**.
- `rpm_disable` + `put_sync`: `4f4388a55019d` / upstream `b1852c5de2f2a`
  (“Fix clock count when probe defers”) — **already in this 6.12 tree**.
  That only fixed the **enable** count; prepare still leaks.
- `-EPROBE_DEFER` from recovery pinctrl: `188542964e782` — **in this
  tree**.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` tag. Bug-introducing history above is in this tree.
`cbd043b00ee3f` is **not** an ancestor of HEAD.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Latest local change is `4f4388a55019d` (the incomplete enable-
count fix). This commit is the missing prepare-count half of that
unwind. Standalone for 6.12; does not need DMA, `hwdata`, or
`need_prepare_unprepare_clk`.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Carlos Song is an NXP LPI2C contributor (GPIO recovery in this
tree). Frank Li reviewed. Andi Shyti merged. Series v6 patch 2
(`a4c419356a333`, controller reset) is independent and not required.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Message cites later SoC clock strategies (`949f647eff76a`,
2026-01-19) — **not in 6.12**. The **code** of this fix does not use
`hwdata` / `need_prepare_unprepare_clk`. Needed APIs
(`clk_bulk_disable_unprepare`, `pm_runtime_put_noidle`,
`pm_runtime_set_suspended`) exist in 6.12. **Can be backported
standalone** with context tweaks.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- SHA: `cbd043b00ee3f542c115c8809c4d9a67465c07d5`
- `b4 dig -c`: https://patch.msgid.link/20260716071957.2670263-2-
  carlos.song@oss.nxp.com
- Series: **v6 1/2** “fix probe error handling and reset controller”
  (v4/v5/v6 of the same subject)
- Andi Shyti: merged to `i2c/i2c-2` (2026-07-28). No NAK.
- Cover letter: v3 replaced `put_sync` with disable + set_suspended +
  put_noidle specifically to avoid the suspend callback during error
  recovery.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): linux-i2c, imx@lists, linux-arm-kernel; Andi
Shyti; Dong Aisheng (LPI2C maintainer in MAINTAINERS); Frank Li
(Reviewed-by); Pengutronix i.MX folks. Right audience.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla. Bug is from code review / NXP analysis, not
a crash report. Still a concrete leak with a documented `-EPROBE_DEFER`
path.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Patch 2/2 (reset in probe) is a separate hang-on-boot issue; not
a dependency. Earlier `b1852c5`/`4f4388a55019d` is the related
incomplete stable fix already here.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned HTTP 403. No stable nomination
on the patch itself. Related defer clock-count fix **was** `Cc: stable #
v4.16+` and is already in this tree.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `lpi2c_imx_probe()` only. Unwind interacts with
`lpi2c_runtime_suspend()` (not edited).

Step 5.2: TRACE CALLERS
Record: `.probe = lpi2c_imx_probe` on the platform driver. Called from
driver core on DT devices (`fsl,imx7ulp-lpi2c`) and on deferred retry.
Not a syscall hot path.

Step 5.3: TRACE CALLEES
Record: `clk_bulk_prepare_enable` / `clk_bulk_disable_unprepare`,
`devm_clk_rate_exclusive_get`, `clk_get_rate`, RPM helpers,
`lpi2c_imx_init_recovery_info()` (`devm_pinctrl_get` → `-EPROBE_DEFER`),
`i2c_add_adapter()`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Reachable at boot and on probe defer.
`lpi2c_imx_init_recovery_info()` is a real `-EPROBE_DEFER` source when
pinctrl is not ready. Unprivileged userspace does not need to trigger
it.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Other I2C drivers use `clk_disable:` /
`clk_bulk_disable_unprepare` on probe fail (`i2c-qcom-geni.c`,
`i2c-qcom-cci.c`). This driver was the odd one out after RPM callbacks
stopped unpreparing.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.** `lpi2c_imx_probe()` in `drivers/i2c/busses/i2c-imx-
lpi2c.c` still does:

```609:625:drivers/i2c/busses/i2c-imx-lpi2c.c
        ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks,
lpi2c_imx->clks);
        if (ret)
                return ret;
        ...
        if (ret)
                return dev_err_probe(...);  /* exclusive_get: leak */
        ...
        if (!lpi2c_imx->rate_per)
                return dev_err_probe(...);  /* rate 0: leak */
```

```654:657:drivers/i2c/busses/i2c-imx-lpi2c.c
rpm_disable:
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
```

```672:679:drivers/i2c/busses/i2c-imx-lpi2c.c
static int __maybe_unused lpi2c_runtime_suspend(struct device *dev)
{
        ...
        clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks);
```

No `hwdata` / `need_prepare_unprepare_clk` here, so **every** SoC only
disables in RPM. The prepare leak on `rpm_disable` is unconditional.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **`git apply --check` fails** because context includes
`hwdata->need_prepare_unprepare_clk` and later DMA probe code. Logical
change maps 1:1 onto this probe (same exclusive-get returns, same
`rpm_disable` + `put_sync`). Difficulty: **minor context backport**, not
a rewrite.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: `4f4388a55019d` is here and only switched `pm_runtime_put()` to
`put_sync()`. It does **not** unprepare. No other unwind of this leak in
this tree.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: I2C bus driver for i.MX LPI2C (`CONFIG_I2C_IMX_LPI2C`,
`ARCH_MXC`). **IMPORTANT** for i.MX boards (PMIC, audio, sensors on that
bus), not core MM/VFS. Maintainer: Dong Aisheng; I2C maintainer merged
it.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver (since ~2016). This tree’s recent churn is small
fixes, not a rewrite. The big SoC RPM split landed after 6.12.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Driver-specific / platform-specific** — i.MX systems using
LPI2C. Common on i.MX7ULP / i.MX8 class boards, not all Linux users.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Exclusive-get / zero clock rate: uncommon hard errors.
- **`-EPROBE_DEFER` from pinctrl in recovery init:** normal boot race;
  retries leak another prepare each time.
- `i2c_add_adapter()` failure: less common.
- Not a userspace-triggered security path.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: Clock prepare leak (and enable leak on the pre-RPM returns).
Repeated defer can unbalance the clock tree, keep parents prepared, and
block low power. Not an oops/corruption/CVE. **Severity: MEDIUM**,
higher if defer retries pile up.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** Completes the unwind that `4f4388a55019d` only half-
  fixed; stops prepare-count growth on defer. Medium benefit for i.MX
  LPI2C users.
- **Risk:** ~20-line error-path change; success path unchanged. Low risk
  if backported without keeping `put_sync`.
- **Ratio:** Favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

**FOR backporting:**
- Real clock leak on probe failure, including a documented
  `-EPROBE_DEFER` path.
- Buggy code is in this 6.12 tree (exclusive-get + disable-only RPM +
  `put_sync` unwind).
- This tree already took the enable-count half (`4f4388a55019d`); this
  is the remaining prepare-count fix.
- Small, probe-error only; reviewed and merged by the I2C maintainer.
- No new API/feature; no `hwdata` dependency in the changed lines.

**AGAINST:**
- Does not apply with `git apply` as-is (later DMA/`hwdata` context).
- Not a crash/security/corruption bug.
- No `Cc: stable` / syzbot / user crash report.
- Message talks about later per-SoC clock strategies that 6.12 does not
  have (the leak is still real here, and simpler).

**UNRESOLVED:**
- Stable list search was blocked (HTTP 403). Unverified whether anyone
  already NAK’d this for stable.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — explicit unwind; merged
   after v4–v6 review.
2. Fixes a real bug that affects users? **PASS** — clock leak on probe
   fail/defer.
3. Important issue? **PASS** at medium — not panic-level, but resource
   leak on a normal defer path; sister fix already went to stable.
4. Small and contained? **PASS** — one function, error labels only.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS with backport** — code is here;
   context needs a small edit. Not “code missing / bug introduced after
   branch.”

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None (not an ID/quirk/DT/build/docs exception). Qualifies as a
normal small bugfix.

Step 9.4: MAKE YOUR DECISION
Backport to **this** 6.12 tree. The later SoC RPM split is not required.
Drop `hwdata`/DMA context and apply the same `goto clk_disable` + RPM-
bypass + `clk_bulk_disable_unprepare()` sequence to `lpi2c_imx_probe()`.

Verification:
- [Phase 1] Tags: Reviewed-by Frank Li; SOB Andi Shyti; Link to v6 1/2;
  no Fixes/Cc:stable/syzbot
- [Phase 2] Diff: +14/−7 in `lpi2c_imx_probe()`; two early returns →
  `clk_disable`; `put_sync` → disable/set_suspended/put_noidle +
  `clk_bulk_disable_unprepare`
- [Phase 3] Blame: leak from `4268254a39484` (in v6.12); RPM disable-
  only from `fa39065833dbd` (in v6.12); incomplete enable fix
  `4f4388a55019d` already in HEAD
- [Phase 3] `git merge-base --is-ancestor cbd043b00ee3f HEAD` → not in
  this tree
- [Phase 3] `949f647eff76a` (`need_prepare_unprepare_clk`) → **not** in
  this tree
- [Phase 4] `b4 dig -c cbd043b00ee3f`: lore v6 1/2; Andi merged to
  i2c-2; no NAK
- [Phase 4] Cover: v3 introduced the RPM-bypass unwind; patch 2/2 is
  independent
- [Phase 4] UNVERIFIED: stable@ lore (403)
- [Phase 5] Probe is platform `.probe`; `-EPROBE_DEFER` from
  `devm_pinctrl_get` in recovery init
- [Phase 6] `git describe` / Makefile: 6.12.111; buggy returns and
  `rpm_disable` present; `git apply --check` fails on `hwdata` context
- [Phase 8] Failure mode: clock prepare leak, worse on deferred probe;
  severity MEDIUM; risk low

The leak exists on this 6.12 branch, the fix is small and correct, and
it finishes an unwind this tree already started.

**YES**

 drivers/i2c/busses/i2c-imx-lpi2c.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 24c70ea371bb9..7c560a4f68319 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -1500,14 +1500,18 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
 	 * each transfer
 	 */
 	ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
-	if (ret)
-		return dev_err_probe(&pdev->dev, ret,
-				     "can't lock I2C peripheral clock rate\n");
+	if (ret) {
+		ret = dev_err_probe(&pdev->dev, ret,
+				    "can't lock I2C peripheral clock rate\n");
+		goto clk_disable;
+	}
 
 	lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
-	if (!lpi2c_imx->rate_per)
-		return dev_err_probe(&pdev->dev, -EINVAL,
-				     "can't get I2C peripheral clock rate\n");
+	if (!lpi2c_imx->rate_per) {
+		ret = dev_err_probe(&pdev->dev, -EINVAL,
+				    "can't get I2C peripheral clock rate\n");
+		goto clk_disable;
+	}
 
 	pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -1545,8 +1549,11 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
 
 rpm_disable:
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
-	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+clk_disable:
+	clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks);
 
 	return ret;
 }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (44 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] i2c: imx-lpi2c: properly unwind resources on probe failure Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin
                   ` (2 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 636a883e2feef5e4ff95695d3c372ceff03960f5 ]

Releasing buffered frames has to turn off the PSE redirect for the
station, otherwise the released frames are looped straight back into the
driver PS queue. Nothing ever turns it back on: mt7603_sta_ps() only runs
on an observed PM bit transition, and MT_WCID_FLAG_PS keeps mt76 from
reporting the same state twice. After the first service period the
hardware therefore treats a dozing station as awake and transmits at it
directly, which is where the retry storms and the packet loss reported
against U-APSD clients come from.

Re-arm hardware buffering from mt7603_mac_work() for every station that
is still known to be asleep, once the PSD queue has drained and the
released frames have passed the redirect stage. Frames that are still
queued belong to the service period that was just served, so unlike on a
sleep transition they must not be pulled back with mt7603_filter_tx().

Track the sleep state separately from the WTBL state, so a station that
wakes up while the re-arm is pending is not put back to sleep.

Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough to judge this against 5.15.221: the bug is in this tree,
the fix is real, and it needs a small mechanical backport rather than
missing code.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603:] [restore] [re-arm hardware PS buffering
after a U-APSD/PS-Poll service period]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name`
  — this is **patch 07/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
  (ignore any Sasha Levin SOB)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence expected)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Releasing buffered frames disables PSE redirect
  (`mt7603_wtbl_set_ps(..., false)`). Nothing turns it back on:
  `mt7603_sta_ps()` only runs on a PM-bit edge, and `MT_WCID_FLAG_PS`
  suppresses duplicate notifications.
- **Symptom:** After the first service period the HW treats a dozing STA
  as awake, TX goes to a sleeping radio → **retry storms and packet
  loss** on U-APSD clients.
- **Root cause:** Missing re-arm of hardware PS buffering after an SP;
  sleep state was conflated with WTBL PS state.
- **Fix:** Re-arm from `mt7603_mac_work()` once the PSD queue has
  drained; do not `mt7603_filter_tx()` on that re-arm; track
  `ps_sleeping` separately.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. This is an explicit functional bug fix.

---

## PHASE 2: DIFF ANALYSIS - LINE BY LINE

**Step 2.1: INVENTORY THE CHANGES**
Record:
- `mac.c`: +~70 / −~7 — split `mt7603_wtbl_set_ps`, add
  `__mt7603_wtbl_set_ps`, `mt7603_wtbl_sta_ps`,
  `mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`; call it from
  `mt7603_mac_work`
- `main.c`: 1 line — `mt7603_sta_ps()` uses `mt7603_wtbl_sta_ps`
- `mt7603.h`: `u8 ps_sleeping` plus two prototypes
- Scope: **single-driver surgical fix** (~72/7, 3 files)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- Before: `mt7603_wtbl_set_ps(true)` enables PSE redirect + `filter_tx`;
  `false` disables both. `release_buffered_frames` / PS-response TX
  force `false` and never restore.
- After: `sta_ps` also sets `ps_sleeping`. Temporary WTBL-off (SP)
  leaves `ps_sleeping` true. `mac_work` (100 ms) walks stations; if `!ps
  && ps_sleeping` and PSD is empty, re-enables redirect **without**
  pulling in-flight SP frames back via `filter_tx`.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-state correctness.** HW PS filter left off
after an SP. Not UAF/leak/race in the sanitizer sense; it is a driver
state-machine bug with airtime/retry fallout.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Quality is high. `ps_sleeping` is updated under `ps_lock`;
`restore_ps` re-checks it under the same lock so a wakeup cannot put the
STA back to sleep. `filter=false` on restore is required so SP frames
are not recycled. Risk: extra WTBL/PSE MMIO from mac_work (low; only
stations that need re-arm). No public API change.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_wtbl_set_ps` from `c8846e1015022d` (2019-02-26) — initial
  MT7603 driver, **in this tree**
- The off-without-restore came from `f25e813bf48dce` (2019-03-07) “clear
  ps filtering mode before releasing buffered frames” — **in this tree**
  (`git merge-base --is-ancestor` exit 0). That commit is what made SPs
  work at all; it never re-armed.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug-introducing commit is `f25e813bf48dce`,
present here.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Candidate is `636a883e2feef` (not in HEAD). Series around it:
1. `a547b414bf7ea` — **new feature** `MT_DRV_HW_PS_BUFFERING` (other
   chips)
2–3. mt7915/mt7996 MCU PS sync
4. EOSP bit in `mt76_release_buffered_frames`
5. `fix U-APSD service period termination` (mt7603 `main.c`)
6. tell mac80211 when PS queue is empty
7. **this commit**
8. file buffered frames under the reported TID
9–10. mt76 link-id / mt7996 OOB

This commit does **not** call anything those others add. Sibling 4–6 fix
other U-APSD bugs; they are complementary, not compile/runtime
prerequisites.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original mt7603 author.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Mainline uses `mt76_wcid_ptr` (`dc66a129adf1f`, 2025, **not
here**) and 4-arg `mt7603_filter_tx(dev, sta->vif->idx, idx, ...)`
(`fe0ea395f0a35`, 2023, **not here**). In 5.15, `msta->vif` is **never
assigned**. A correct backport is: 3-arg `mt7603_filter_tx(dev, idx,
false)` and `rcu_dereference(dev->mt76.wcid[i])`. Logic does not need
those later commits.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 636a883e2feef` →
  https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
- Series v1 only (`b4 dig -a`): `[PATCH 01/10] wifi: mt76: add PS
  buffering support for HW-managed TIM drivers`
- Thread: no NAK on patch 07; only kbuild noise on patch 10
  (`ieee80211_txq_aql_pending`), unrelated to mt7603
- lore.kernel.org HTTP 403 for WebFetch/curl; discussion recovered via
  `b4 dig -m`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: Felix Fietkau, `linux-wireless@vger.kernel.org`. No
extra Reviewed-by. Author is the subsystem maintainer.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt **mt76#1080** (closed 2026-08-01, same day as this
series): MT7628AN AP, iPhone/U-APSD, Wi-Fi “hangs”, thousands of TX
retries, packet loss; workaround was forcing legacy b/g. Related reports
#865, #576, #390, #841, #375, #26. PR #1084: EOSP helped iPhone freezes;
**retries/loss remained as a separate bug**. Commit text matches that
remaining failure (“retry storms and the packet loss reported against
U-APSD clients”).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 10-patch series. 01 is a new mt76 feature; 07 is a standalone
mt7603 HW-PS re-arm. Full iPhone/U-APSD recovery also wants 04–06/08; 07
still fixes a distinct, real bug.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** — lore.kernel.org/stable returned 403.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_wtbl_set_ps` → `__mt7603_wtbl_set_ps`; added
`mt7603_wtbl_sta_ps`, `mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`;
`mt7603_sta_ps`; `mt7603_mac_work`.

**Step 5.2: TRACE CALLERS**
Record (this tree):
- `mt7603_sta_ps` ← `mt76_check_sta()` via `drv->sta_ps` on RX PM-bit
  change
- `mt7603_wtbl_set_ps(false)` still used by
  `mt7603_release_buffered_frames` and `mt7603_tx_prepare_skb` (PS
  response) — those are the paths that drop HW buffering
- `mt7603_mac_work` — delayed work every `MT7603_WATCHDOG_TIME` (100 ms)

**Step 5.3: TRACE CALLEES**
Record: PSE_RTA write + poll, optional `mt7603_filter_tx`, WTBL1
POWER_SAVE bit, `ps_lock`. Restore skips `filter_tx`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace-reachable: STA in PS/U-APSD associated to an
mt7603/MT7628 AP → mac80211 `.release_buffered_frames` / PS-Poll. **Yes,
unprivileged clients trigger this.**

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same “turn off PS to release frames” exists in `tx_prepare_skb`;
`ps_sleeping` covers that too because it is only cleared on a real wake.

---

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

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is **5.15.221** (`pending-5.15`,
`p-5.15-2-g6703e5d2f3a29`).
- `mt7603_release_buffered_frames` still does `mt7603_wtbl_set_ps(dev,
  msta, false)` (`main.c:434`)
- `mt76_check_sta` still uses `MT_WCID_FLAG_PS` to skip duplicate
  `sta_ps`
- `636a883e2feef` is **not** an ancestor of HEAD

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: `git show 636a883e2feef | git apply --check` **fails**. Needed
adaptations:
1. `mt7603_filter_tx(dev, sta->vif->idx, idx, false)` →
   `mt7603_filter_tx(dev, idx, false)` (3-arg; `msta->vif` unused here)
2. `mt76_wcid_ptr(dev, i)` → `rcu_dereference(dev->mt76.wcid[i])`
3. `mac_work` context differs (`mt76_tx_status_check` arity,
   `aggr_stats` location) — insertion after `mt7603_edcca_check` is
   still valid

`main.c` hunk and `ps_sleeping` field apply. **Backport difficulty:
minor rework, not a redesign.**

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No `ps_sleeping` / `mac_ps_check` / `wtbl_restore_ps` in this
tree. Older PS commits here (`e004b70066002`, `9dc27bcbe78c5`,
`d55aa5e17461b`) do not re-arm after an SP.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/net/wireless/mediatek/mt76/mt7603** —
**PERIPHERAL/IMPORTANT for that hardware.** MT7603E/MT7628 is common on
low-end APs/routers (`CONFIG_MT7603E`). Not core mm/fs, but AP mode with
phones is a primary use.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (landed 2019). Little 5.15-era churn; the bug is
long-lived.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** mt7603/MT7628 in AP mode with power-
save/U-APSD clients (iPhones and similar).

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: First PS-Poll or U-APSD SP after the client dozes. Common on
phones (Instagram/video in #1080). Unprivileged associated STAs trigger
it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **HIGH** (not kernel oops). Retry storms, packet loss, AP
“hangs” vs PS clients; wasted airtime can hurt the whole BSS. Users had
to force legacy b/g.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for that hardware. **Risk: low–medium**
(contained MMIO + lock; `ps_sleeping` handles races). Blind 4-arg/`vif`
apply would be wrong here; a 3-arg + `rcu_dereference` backport is safe.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real, old bug in this tree (`f25e813bf48dce`, 2019)
- User-visible: retry storms, loss, Wi-Fi hangs with U-APSD/iPhone
  (OpenWrt #1080 and several older issues)
- Small, mt7603-only, maintainer-authored, logic is clear
- Standalone vs series patches 01–06
- Trigger is normal AP + phone PS

**AGAINST:**
- 07/10 in a series that also adds a new mt76 feature
- Does not apply cleanly (filter_tx arity, `mt76_wcid_ptr`, mac_work
  context)
- Full U-APSD repair also wants 04–06; 07 is not the entire story
- Not a kernel crash/security/corruption bug

**UNRESOLVED:** stable@ lore (HTTP 403). No Tested-by on the commit
itself; OpenWrt #1080 was closed the day the series landed.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — maintainer fix; matches a
   long-standing user report
2. Fixes a real bug that affects users? **PASS**
3. Important issue? **PASS** — AP unusable with PS phones / BSS retry
   storms (HIGH, not oops)
4. Small and contained? **PASS** — ~70 lines, one driver
5. No new features or APIs? **PASS** — internal state + helpers
6. Can apply to the local tree? **PASS** with a small backport (not a
   clean cherry-pick)

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc exception). Qualifies
as a normal driver bug fix.

**Step 9.4: MAKE YOUR DECISION**
The buggy “disable PSE redirect on SP, never re-arm” path is in
5.15.221. That is a real AP-mode failure for mt7603/MT7628, not a new-
stack issue. The patch is the right fix and is adaptable without pulling
the HW_PS_BUFFERING feature series.

---

### What the commit solves and why it matters here
After a service period, mt7603 leaves hardware PS buffering off. The AP
then TX’s at a dozing client → retries and loss. That code has been in
this tree since 2019. MT7628 APs with phones hit it in the real world.

### Stable rules
Meets the bar: real bug, contained, no new API. Needs a mechanical
backport (`filter_tx` 3-arg, `rcu_dereference` instead of
`mt76_wcid_ptr`), which is allowed.

### Risk vs benefit
Benefit is high for mt7603 AP users; risk is low if the backport does
**not** use `sta->vif` (unset in 5.15). Sibling EOSP/TIM patches would
help more U-APSD cases but are not required for this re-arm.

### Concerns
Cherry-pick will not apply as-is. Do not copy the 4-argument
`mt7603_filter_tx(..., sta->vif->idx, ...)` call into this tree.

---

Verification:
- [Phase 1] Subject/body/tags: restore HW PS after SP; Link is 07/10;
  maintainer SOB only
- [Phase 2] Diff: ~72/7 in mt7603 mac.c/main.c/mt7603.h; `ps_sleeping` +
  mac_work re-arm
- [Phase 3] `git describe HEAD` / Makefile: 5.15.221, branch
  `pending-5.15`
- [Phase 3] `git merge-base --is-ancestor 636a883e2feef HEAD` → not in
  tree
- [Phase 3] blame: `c8846e1015022d` (driver), `f25e813bf48dce` (clear PS
  before release) — both ancestors of HEAD
- [Phase 3] Related series commits listed; 01 is new feature; 07 does
  not call those APIs
- [Phase 4] `b4 dig -c 636a883e2feef` / `-a` / `-w` / `-m`: lore thread,
  v1-only series, wireless list, no NAK on 07
- [Phase 4] OpenWrt mt76#1080 / #1084: retry storms + iPhone U-APSD;
  issue closed 2026-08-01
- [Phase 5] Callers verified in 5.15: `sta_ps`,
  `release_buffered_frames`, `tx_prepare_skb`, `mac_work` 100 ms
- [Phase 6] Local `mt7603_wtbl_set_ps` / `release_buffered_frames` still
  match the bug; `mt76_wcid_ptr` absent; `filter_tx` is 3-arg;
  `msta->vif` never set
- [Phase 6] `git apply --check` of 636a883e2feef fails on filter_tx/wcid
  helper; main.c hunk would apply
- [Phase 8] Failure mode: retry storms / packet loss / AP hang vs PS
  clients, severity HIGH
- UNVERIFIED: stable@ mailing-list discussion (lore 403)

**YES**

 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 73 +++++++++++++++++--
 .../net/wireless/mediatek/mt76/mt7603/main.c  |  2 +-
 .../wireless/mediatek/mt76/mt7603/mt7603.h    |  4 +
 3 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 6387f9e61060a..85c727fc44e6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -235,16 +235,17 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	sta->smps = enabled;
 }
 
-void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
-			bool enabled)
+static void
+__mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+		     bool enabled, bool filter)
 {
 	int idx = sta->wcid.idx;
 	u32 addr;
 
-	spin_lock_bh(&dev->ps_lock);
+	lockdep_assert_held(&dev->ps_lock);
 
 	if (sta->ps == enabled)
-		goto out;
+		return;
 
 	mt76_wr(dev, MT_PSE_RTA,
 		FIELD_PREP(MT_PSE_RTA_TAG_ID, idx) |
@@ -255,7 +256,7 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 
 	mt76_poll(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY, 0, 5000);
 
-	if (enabled)
+	if (enabled && filter)
 		mt7603_filter_tx(dev, sta->vif->idx, idx, false);
 
 	addr = mt7603_wtbl1_addr(idx);
@@ -264,8 +265,34 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 		 enabled * MT_WTBL1_W3_POWER_SAVE);
 	mt76_clear(dev, MT_WTBL1_OR, MT_WTBL1_OR_PSM_WRITE);
 	sta->ps = enabled;
+}
 
-out:
+void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+			bool enabled)
+{
+	spin_lock_bh(&dev->ps_lock);
+	__mt7603_wtbl_set_ps(dev, sta, enabled, enabled);
+	spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta, bool ps)
+{
+	spin_lock_bh(&dev->ps_lock);
+	sta->ps_sleeping = ps;
+	__mt7603_wtbl_set_ps(dev, sta, ps, ps);
+	spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta)
+{
+	spin_lock_bh(&dev->ps_lock);
+	/*
+	 * Frames that are already queued for the station belong to the service
+	 * period that has just been served, so unlike on a sleep transition
+	 * they must not be pulled back into the PS queue.
+	 */
+	if (sta->ps_sleeping)
+		__mt7603_wtbl_set_ps(dev, sta, true, false);
 	spin_unlock_bh(&dev->ps_lock);
 }
 
@@ -1816,6 +1843,39 @@ mt7603_false_cca_check(struct mt7603_dev *dev)
 	mt7603_adjust_sensitivity(dev);
 }
 
+/*
+ * Releasing buffered frames turns off the PSE redirect for a station, since
+ * the released frames would otherwise be looped back into the driver PS queue
+ * again. mac80211 never tells us when the service period is over, so hardware
+ * buffering has to be re-armed here for every station that is still known to
+ * be asleep. Waiting for the PSD queue to drain makes sure that the released
+ * frames have already passed the redirect stage.
+ */
+static void
+mt7603_mac_ps_check(struct mt7603_dev *dev)
+{
+	int i;
+
+	if (dev->mphy.q_tx[MT_TXQ_PSD]->queued)
+		return;
+
+	rcu_read_lock();
+	for (i = 0; i < MT7603_WTBL_STA; i++) {
+		struct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);
+		struct mt7603_sta *msta;
+
+		if (!wcid || !wcid->sta)
+			continue;
+
+		msta = container_of(wcid, struct mt7603_sta, wcid);
+		if (msta->ps || !msta->ps_sleeping)
+			continue;
+
+		mt7603_wtbl_restore_ps(dev, msta);
+	}
+	rcu_read_unlock();
+}
+
 void mt7603_mac_work(struct work_struct *work)
 {
 	struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
@@ -1830,6 +1890,7 @@ void mt7603_mac_work(struct work_struct *work)
 	dev->mphy.mac_work_count++;
 	mt76_update_survey(&dev->mphy);
 	mt7603_edcca_check(dev);
+	mt7603_mac_ps_check(dev);
 
 	for (i = 0, idx = 0; i < 2; i++) {
 		u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index f8a43d9f72f95..04e3966ab047f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -410,7 +410,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 	struct sk_buff_head list;
 
 	mt76_stop_tx_queues(&dev->mphy, sta, true);
-	mt7603_wtbl_set_ps(dev, msta, ps);
+	mt7603_wtbl_sta_ps(dev, msta, ps);
 	if (ps)
 		return;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 55a034ccbacd9..c43ddd3e693c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -80,6 +80,7 @@ struct mt7603_sta {
 	u8 smps;
 
 	u8 ps;
+	u8 ps_sleeping;
 };
 
 struct mt7603_vif {
@@ -229,6 +230,9 @@ int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,
 			struct ieee80211_key_conf *key);
 void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 			bool enabled);
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+			bool ps);
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta);
 void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 			  bool enabled);
 void mt7603_filter_tx(struct mt7603_dev *dev, int mac_idx, int idx, bool abort);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (45 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] clk: sunxi-ng: fix ccu probe clock unregister on error Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] ARM: OMAP2+: Add CFI type for omap4_finish_suspend Sasha Levin
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Shiji Yang, Simon Horman, Lorenzo Bianconi, Jakub Kicinski,
	Sasha Levin, nbd, andrew+netdev, davem, edumazet, pabeni,
	matthias.bgg, angelogioacchino.delregno, netdev, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Shiji Yang <yangshiji66@outlook.com>

[ Upstream commit c0ef04232f9fac083c3d8a77ce58ba32243e6734 ]

Change WDMA RESV_BUFF from 0x40 to 0x80 to avoid CDM TX FIFO overflow.
Without this patch mt7986 and mt7981 may have WDMA TX hang issue. This
patch was pulled from mtk-openwrt-feeds GPL open source project.

Link: https://github.com/mediatek/mtk-openwrt-feeds/commit/07c87502e854b68b48544d101b6fe17ec059b97b
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/OSZPR01MB779537889255E2F606E47EABBCA52@OSZPR01MB7795.jpnprd01.prod.outlook.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This 6.12.111 tree has the WED v2 DMA path without the RESV_BUFF bump.
The change is a small MediaTek hardware workaround for a WDMA TX hang on
mt7986/mt7981.

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: `[net: ethernet: mtk_wed:] [increase] [WED v2 WDMA RESV_BUFF
0x40 -> 0x80]`

**Step 1.2 — Tags**
Record:
- `Link: https://github.com/mediatek/mtk-openwrt-
  feeds/commit/07c87502e854b68b48544d101b6fe17ec059b97b` (vendor source)
- `Signed-off-by: Shiji Yang <yangshiji66@outlook.com>` (author)
- `Reviewed-by: Simon Horman <horms@kernel.org>`
- `Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>` (mtk_wed maintainer)
- `Link: https://patch.msgid.link/OSZPR01MB779...` (netdev submission)
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (applied to
  netdev/net)
- No `Fixes:` and no `Cc: stable` on the committed version (expected for
  this pipeline)
- No `Reported-by:` / `Tested-by:` / syzbot

**Step 1.3 — Body**
Record:
- Bug: default WDMA `RESV_BUFF` of `0x40` can overflow the CDM TX FIFO
  on WED v2.
- Symptom: WDMA TX hang on mt7986 and mt7981.
- Root cause: reserved WDMA buffer too small for v2 hardware.
- Source: MediaTek OpenWrt GPL feeds (`Fix WED 2.0 WDMA TX hang issue`).
- Version info: v2 only (mt7986/mt7981). Rex Lu later said v3 dropped
  this register.

**Step 1.4 — Hidden bug fix?**
Record: Not hidden. Explicit hang fix / hardware workaround. Vendor
subject was also a hang fix.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- `drivers/net/ethernet/mediatek/mtk_wed.c`: +5 in
  `mtk_wed_dma_enable()`
- `drivers/net/ethernet/mediatek/mtk_wed_regs.h`: +1
  (`MTK_WDMA_GLO_CFG_RESV_BUFF` = `GENMASK(23, 16)`)
- Scope: single-driver surgical change (~6 lines)

**Step 2.2 — Flow change**
Record: After the existing v1/v2 vs v3 `MTK_WDMA_GLO_CFG` setup, and
before enabling WED GLO DMA, v2 now RMWs bits 23:16 of
`MTK_WDMA_GLO_CFG` to `0x80`. v1 and v3 are unchanged. Init/enable path
only.

**Step 2.3 — Bug mechanism**
Record: Hardware workaround. Default `RESV_BUFF` is `0x40`; raising it
to `0x80` leaves more WDMA reserved buffer so CDM TX FIFO does not
overflow and stall TX. `wdma_m32()` already does `(read & ~mask) | val`.

**Step 2.4 — Fix quality**
Record: Minimal, gated by `mtk_wed_is_v2()`, uses existing helpers.
Regression risk is low: only WED v2 register bits 23:16. MediaTek
confirmed v3 must not get this write because the field was removed.

## Phase 3: Git history

**Step 3.1 — Blame**
Record: `mtk_wed_dma_enable()` came from `cf26df8833cc` (2022-09-22,
“add mtk_wed_configure_irq and mtk_wed_dma_{enable/disable}”).
Surrounding v2/v3 split is `e2f64db13aa1d` (2023-09-18, MT7988 WED). The
missing programming is a long-standing omission, not new 6.12 code.

**Step 3.2 — Fixes: tag**
Record: Committed patch has none. Simon Horman and Lorenzo Bianconi both
named `cf26df8833cc`. That commit **is** an ancestor of this tree (`git
merge-base --is-ancestor` succeeded).

**Step 3.3 — File history**
Record: Recent 6.12 `mtk_wed.c` work is leaks/UAF/reset, not RESV_BUFF.
No competing local fix. Standalone, not patch N/M.

**Step 3.4 — Author**
Record: Shiji Yang has no other `drivers/net/ethernet/mediatek/` commits
in this tree. Original vendor author is Rex Lu (MediaTek). Lorenzo
(maintainer) acked.

**Step 3.5 — Prerequisites**
Record: Needs `mtk_wed_is_v2()`, `wdma_m32()`, `FIELD_PREP`,
`MTK_WDMA_GLO_CFG`. All present. Upstream SHA `c0ef04232f9f` is **not**
in this tree (ancestor check failed). Can apply standalone.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
Record:
- `b4 dig -c c0ef04232f9f` → https://patch.msgid.link/OSZPR01MB779537889
  255E2F606E47EABBCA52@OSZPR01MB7795.jpnprd01.prod.outlook.com
- Single revision (v1). Applied as-is to netdev/net.git.
- Simon: target `net`, **CC stable**, add Fixes; still `Reviewed-by`.
- Jakub asked Lorenzo to review, including the Fixes suggestion.
- Lorenzo asked if v3 needs it; Rex Lu: v2 only, v3 removed the
  register.
- Lorenzo: `Acked-by`.
- No NAK.

**Step 4.2 — Recipients (`b4 dig -w`)**
Record: netdev, linux-mediatek, Lorenzo Bianconi, Felix Fietkau, Rex Lu,
netdev maintainers. Right people.

**Step 4.3 — Bug report**
Record: Vendor feeds commit `07c87502e854`: “Fix WED 2.0 WDMA TX hang
issue” / “without this patch mt7986 and mt7981 may have WDMA TX hang”.
Same 6-line change. No public syzbot/bugzilla thread found.

**Step 4.4 — Series**
Record: Standalone 1/1. No companion patches.

**Step 4.5 — Stable list**
Record: UNVERIFIED for lore.kernel.org/stable (HTTP 403). Simon’s review
is an explicit stable nomination. No evidence of a stable NAK.

## Phase 5: Semantic / call graph

**Step 5.1 — Functions**
Record: `mtk_wed_dma_enable()` plus a register `#define`.

**Step 5.2 — Callers**
Record: Only `mtk_wed_start()` → `mtk_wed_dma_enable()`. That is
`wed_ops.start`, invoked as `mtk_wed_device_start()` from mt76
(`mt7915/dma.c`, `mt7996/dma.c`). mt7915 is the usual WiFi partner for
mt7986/mt7981 (WED v2).

**Step 5.3 — Callees**
Record: `wdma_m32` → `wdma_r32`/`wdma_w32` (MMIO RMW). No alloc, no
locks.

**Step 5.4 — Reachability**
Record: Yes. Bringing WiFi up with WED offload on Filogic 820/830 hits
this. Not a rare debug path.

**Step 5.5 — Similar patterns**
Record: No other `RESV_BUFF` users. Nearby `wdma_set(MTK_WDMA_GLO_CFG,
...)` already programs this register for TX enable / prerest bits.

## Phase 6: This tree (6.12.111)

**Step 6.1 — Buggy code present?**
Record: Yes. `make kernelversion` / `git describe` → **6.12.111**
(`p-6.12-3-gc504cf0baa3d8`). `mtk_wed_dma_enable()` has the v2/v3 split
and does **not** set RESV_BUFF. `mt7981_data` / `mt7986_data` have
`.version = 2`. `hw->version = eth->soc->version`. Bug dates to WED
dma_enable (2022), well before 6.12.

**Step 6.2 — Backport difficulty**
Record: Clean apply. Insertion context around the v3 `else` branch and
`MTK_WDMA_GLO_CFG` bit defines matches the upstream hunk.

**Step 6.3 — Already fixed?**
Record: No. `git log --grep=RESV_BUFF` / `WDMA TX hang` / `increase WED
v2` on these files is empty. `c0ef04232f9f` is not an ancestor.

## Phase 7: Subsystem

**Step 7.1**
Record: MediaTek ethernet WED (WiFi/Ethernet dispatch offload).
**IMPORTANT** for Filogic routers, not core-mm/VFS. OpenWrt 6.12 devices
(BPI-R3, GL-MT6000, many AX3000/AX6000 boards) use this.

**Step 7.2**
Record: Mature driver; v2 support is years old. This is a vendor hang
workaround, not churn from a new API.

## Phase 8: Impact / risk

**Step 8.1 — Who**
Record: Driver/SoC specific: `CONFIG_NET_MEDIATEK_SOC` + WED,
mt7981/mt7986, WiFi WED offload.

**Step 8.2 — Trigger**
Record: WED DMA enable when WiFi starts. Can be common on those APs.
Unprivileged users do not poke the register; they can trigger it by
using the AP. Timing-dependent FIFO overflow under TX load is plausible.

**Step 8.3 — Severity**
Record: WDMA TX hang → WiFi/Ethernet TX stall. **HIGH** (hang / loss of
forwarding). Not a KASAN UAF, but a real production hang on shipping
routers.

**Step 8.4 — Benefit vs risk**
Record: Benefit high for Filogic v2 users (fixes hang). Risk very low (6
lines, v2-only, maintainer + MediaTek + netdev review). Ratio strongly
favors backport.

## Phase 9: Synthesis

**For backporting**
- Real hang: CDM TX FIFO overflow → WDMA TX stall on mt7986/mt7981.
- Hardware quirk/workaround (stable exception).
- Tiny, obviously correct RMW of a documented field.
- Code and helpers exist in 6.12; applies cleanly.
- Simon Horman asked for `Cc: stable`; Lorenzo acked; MediaTek confirmed
  v2-only.
- Vendor already shipped the same change in OpenWrt feeds.

**Against**
- No kernel.org `Reported-by` / crash log (vendor description only).
- Affects one SoC family, not all machines.
- Committed patch omitted `Fixes:` / `Cc: stable` (Simon noted that; not
  a technical reason to skip).

**Unresolved**
- Could not query lore.kernel.org/stable (403). No sign it was rejected.

**Stable rules**
1. Obviously correct and tested — **PASS** (review + vendor feeds +
   MediaTek confirmation)
2. Real user bug — **PASS** (TX hang)
3. Important (hang) — **PASS** (HIGH)
4. Small/contained — **PASS** (6 lines, two files)
5. No new features/APIs — **PASS** (register programming)
6. Applies to this tree — **PASS** (clean context on 6.12.111)

**Exception:** hardware workaround / quirk.

This should be backported to this 6.12.y tree.

Verification:
- [Phase 1] Parsed tags: vendor GitHub link, Reviewed-by Horman, Acked-
  by Bianconi, applied by Kicinski; no Fixes/Cc: stable on the commit
- [Phase 2] Diff: +5 in `mtk_wed_dma_enable()`, +1 GENMASK; v2-only
  `wdma_m32` of bits 23:16 to 0x80
- [Phase 2] `wdma_m32()` in this tree is `(read & ~mask) | val` at
  `mtk_wed.c:111-114`
- [Phase 3] Blame: `mtk_wed_dma_enable` from `cf26df8833cc`
  (2022-09-22); v2/v3 split from `e2f64db13aa1d`
- [Phase 3] `git merge-base --is-ancestor cf26df8833cc HEAD` succeeded;
  `c0ef04232f9f` is not in this tree
- [Phase 3] `mtk_wed_is_v2` from `d274d523c71c82` is in this tree
- [Phase 4] `b4 dig -c c0ef04232f9f`: v1 only; lore msgid
  OSZPR01MB7795...
- [Phase 4] Horman review (openwall 2026/08/21/128): “Be CCed to
  stable”, Fixes `cf26df8833cc`, Reviewed-by
- [Phase 4] Rex Lu: v2 only; v3 removed RESV_BUFF
- [Phase 4] Lorenzo Acked-by after that confirmation
- [Phase 4] GitHub `07c87502e854`: same 6-line hang fix
- [Phase 4] lore.kernel.org/stable: UNVERIFIED (403)
- [Phase 5] Caller: `mtk_wed_start` → `mtk_wed_dma_enable`;
  `mtk_wed_device_start` from mt76 mt7915/mt7996
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111;
  RESV_BUFF define absent; insertion context matches
- [Phase 6] `mt7981_data`/`mt7986_data`.version = 2; `hw->version =
  eth->soc->version`
- [Phase 8] Failure mode: WDMA TX hang, severity HIGH
- UNVERIFIED: whether anyone already requested this on stable@ (lore
  403)

The hang is real on WED v2 hardware this tree supports, the fix is a
six-line register quirk, and it applies cleanly here.

**YES**

 drivers/net/ethernet/mediatek/mtk_wed.c      | 5 +++++
 drivers/net/ethernet/mediatek/mtk_wed_regs.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
index 1ed1f88dd7f8b..fdb487e5d46e1 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -2071,6 +2071,11 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
 		wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
 	}
 
+	if (mtk_wed_is_v2(dev->hw))
+		wdma_m32(dev, MTK_WDMA_GLO_CFG,
+			 MTK_WDMA_GLO_CFG_RESV_BUFF,
+			 FIELD_PREP(MTK_WDMA_GLO_CFG_RESV_BUFF, 0x80));
+
 	wed_set(dev, MTK_WED_GLO_CFG,
 		MTK_WED_GLO_CFG_TX_DMA_EN |
 		MTK_WED_GLO_CFG_RX_DMA_EN);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
index c71190924816c..e5f83100ded52 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -433,6 +433,7 @@ struct mtk_wdma_desc {
 #define MTK_WDMA_GLO_CFG_TX_DMA_BUSY			BIT(1)
 #define MTK_WDMA_GLO_CFG_RX_DMA_EN			BIT(2)
 #define MTK_WDMA_GLO_CFG_RX_DMA_BUSY			BIT(3)
+#define MTK_WDMA_GLO_CFG_RESV_BUFF			GENMASK(23, 16)
 #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES		BIT(26)
 #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES		BIT(27)
 #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES		BIT(28)
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] clk: sunxi-ng: fix ccu probe clock unregister on error
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (46 preceding siblings ...)
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] ARM: OMAP2+: Add CFI type for omap4_finish_suspend Sasha Levin
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Jerome Brunet, Sashiko, Chen-Yu Tsai, Sasha Levin, sboyd,
	bmasney+clk, jbrunet+clk, jernej.skrabec, samuel, linux-clk,
	linux-arm-kernel, linux-sunxi, linux-kernel

From: Jerome Brunet <jbrunet@baylibre.com>

[ Upstream commit 81f4ddc9f7e0c11d3e9d24d0f30023845a02f7ee ]

When registering clocks with sunxi_ccu_probe(), the number of ccu_clocks
and the number of hw clocks might be different, eventhough they usually are
the same.

If they are different, it could lead to out-of-bound access or registered
clock left behind on error.

Use a different variable when iterating on hw clocks so every registered
clock, and only those, gets unregistered on error.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/20260629131254.7E34C1F00A3A@smtp.kernel.org
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://patch.msgid.link/20260706-a733-rtc-v4-3-f330728db3d3@baylibre.com
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[clk: sunxi-ng]** **[fix]** unregister the right set of CCU
`clk_hw` objects when `sunxi_ccu_probe()` fails.

**Step 1.2: Tags**
Record:
- `Reported-by: Sashiko <sashiko-bot@kernel.org>` — static-analysis bot,
  not syzbot
- `Closes:
  https://lore.kernel.org/r/20260629131254.7E34C1F00A3A@smtp.kernel.org`
- `Reviewed-by: Chen-Yu Tsai <wens@kernel.org>` — sunxi/clk maintainer
- `Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>` (author)
- `Link: https://patch.msgid.link/20260706-a733-rtc-v4-3-
  f330728db3d3@baylibre.com` — **v4 3/9** of the A733 RTC series
- `Signed-off-by: Chen-Yu Tsai <wens@kernel.org>` (applied to sunxi clk
  tree)
- No `Fixes:` tag (expected)
- No `Cc: stable` (expected; not treated as a negative)

**Step 1.3: Body**
Record:
[Bug] `sunxi_ccu_probe()` uses one index for both `desc->ccu_clks`
(`num_ccu_clks`) and `desc->hw_clks` (`hw_clks->num`). Those lengths are
not always equal.
[Symptom] On probe error: **out-of-bounds** `hws[i]` access, or
**registered clocks left behind**.
[Version] None stated.
[Root cause] Error-path unregister walks the leftover loop index instead
of the hw-clock index.

**Step 1.4: Hidden bug fix?**
Record: **No disguise.** This is an explicit error-path OOB/leak fix.
Sashiko rated the pre-existing issue **High**.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record: `drivers/clk/sunxi-ng/ccu_common.c` only; **+6 / −6**. Function:
`sunxi_ccu_probe()`. Surgical, single-file.

**Step 2.2: Code-flow change**
Before: one `i` for (1) `ccu_clks` setup, (2) `hw_clks` register, (3)
rate-range on `ccu_clks`, then `err_clk_unreg` does `while (--i)` over
`hw_clks->hws[i]`. After loop (3), `i == num_ccu_clks`, so
provider/reset failures use the wrong bound.
After: hw-clock register/unregister uses `j`; `i` stays for `ccu_clks`.

**Step 2.3: Bug mechanism**
Record: **[memory safety / error-path leak]**
- `num_ccu_clks > hw_clks->num` → OOB read of `hws[]`
- `num_ccu_clks < hw_clks->num` → incomplete `clk_hw_unregister()`
  (leak)
`clk_hw_register()` failure already used the hw index; the clobber is
the **rate-range loop** added later, then `of_clk_add_hw_provider()` /
`reset_controller_register()` failures.

**Step 2.4: Fix quality**
Record: Obviously correct (separate index). Minimal. Regression risk
**very low** (`j` is always set by `for (j = 0; …)` before any `goto
err_clk_unreg`). No API/locking changes.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: Probe helper from `1d80c14248d608` (2016). Error unregister from
`5d806f9fc8e63d` / `9bec2b9c61340` (v5.16 era). The **clobber** is
`ea977d742507e` (“Don't call hw_to_ccu_common on hw without common”,
**v6.10-rc7**), which inserted a `num_ccu_clks` loop after hw
registration and reused `i`.

**Step 3.2: Fixes: tag**
Record: **None.** Introducer is `ea977d742507e` (ancestor of HEAD). That
commit was itself `Cc: stable` / `Fixes: b914ec33b391e`.

**Step 3.3: File history**
Record: Candidate `81f4ddc9f7e0c`. Nearby Jerome commits are A733 RTC
**features** after this fix. This patch is **standalone**; later series
patches are not prerequisites.

**Step 3.4: Author**
Record: Jerome Brunet (BayLibre, regular clk/sunxi contributor).
Maintainer Chen-Yu Tsai reviewed and applied it.

**Step 3.5: Dependencies**
Record: Needs the three-loop `sunxi_ccu_probe()` from `ea977d742507e`.
That is in this tree. No new helpers. **Can apply standalone.**

---

## Phase 4: Mailing list / external

**Step 4.1: Original discussion**
Record: `b4 dig -c 81f4ddc9f7e0c` → https://patch.msgid.link/20260706-
a733-rtc-v4-3-f330728db3d3@baylibre.com
Series: v1 (Junhui Liu, Jan 2026) → v2/v3/v4 (Jerome). This fix first
appears in **v3** (“Fix ccu probe helper to properly unregister clocks
on error”), applied as **v4 3/9**.
No NAK. Chen-Yu applied it to `sunxi/clk-for-7.3`. No reviewer `Cc:
stable`.

**Step 4.2: Recipients (`b4 dig -w`)**
Record: Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Stephen Boyd,
Maxime Ripard, linux-clk, linux-sunxi. Right maintainers.

**Step 4.3: Bug report**
Record: Sashiko on **v2 5/6** (msgid
`20260629131254.7E34C1F00A3A@smtp.kernel.org`), severity **High**: error
path uses `i == num_ccu_clks` as the `hws[]` bound → leak or OOB
depending on driver sizes. Pre-existing, not introduced by the A733
patch.

**Step 4.4: Series**
Record: 9-patch A733 RTC enablement. This hunk only touches
`ccu_common.c` and does not need A733. Later patches make RTC
`num_ccu_clks` vs `hw_clks->num` diverge more; the common-probe bug
already exists.

**Step 4.5: Stable list**
Record: lore.kernel.org/stable search for this subject returned **no**
dedicated stable-thread discussion. WebFetch to lore.html returned 403;
raw mbox via curl/`b4 dig -m` succeeded.

---

## Phase 5: Semantic / impact

**Step 5.1: Functions**
Record: `sunxi_ccu_probe()` only (plus log index).

**Step 5.2: Callers**
Record: `devm_sunxi_ccu_probe()` and `of_sunxi_ccu_probe()` in the same
file. Called from **all** sunxi-ng CCU drivers (H6, A64, H3, D1, A10,
RTC, …) at SoC clock probe/boot.

**Step 5.3: Callees**
Record: `clk_hw_register` / `of_clk_hw_register`,
`of_clk_add_hw_provider`, `reset_controller_register`,
`clk_hw_unregister`. Provider add can fail (`-ENOMEM`,
`of_clk_set_defaults()`).

**Step 5.4: Reachability**
Record: Boot-time CCU probe on Allwinner. Failure is error-path (OOM,
assigned-clock defaults). On failure, `of_sunxi_ccu_probe()` /
`devm_sunxi_ccu_probe()` **kfree** the `struct sunxi_ccu` whose `lock`
remaining clocks still point at (`cclk->lock = &ccu->lock`) if
unregister is incomplete.

**Step 5.5: Similar patterns**
Record: `devm_sunxi_ccu_release()` already walks `hw_clks->num`
correctly. Only the probe error path was wrong. Counts really differ,
e.g. H6: **127** `ccu_clks` vs **CLK_NUMBER 138**; A64: **104** vs
**115**. RTC in this tree: 12 `ccu_clks` vs `CLK_NUMBER_NO_GATES` **8**
on H616/R329 → **OOB** if probe fails after the rate-range loop.

---

## Phase 6: This checkout (v7.3-rc4)

**Step 6.1: Buggy code here?**
Record: **Yes.** `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
`VERSION=7 PATCHLEVEL=3`. `ea977d742507e` and `81f4ddc9f7e0c` are both
ancestors of HEAD. Pre-fix `sunxi_ccu_probe()` at `81f4ddc9f7e0c^` still
clobbers `i`. Bug since **v6.10**, long before 7.3.

**Step 6.2: Backport difficulty**
Record: **Clean apply** on this code (6-line index split). No refactor
between the buggy helper and this patch.

**Step 6.3: Other fixes already here?**
Record: This **is** the fix (`81f4ddc9f7e0c`). No earlier equivalent.
That does not mean “already selected for stable”; it is the mainline
commit being evaluated.

---

## Phase 7: Subsystem

**Step 7.1:** Record: **clk / Allwinner sunxi-ng CCU**. **IMPORTANT**
(every Allwinner platform’s clock controller), not core mm/net, not
staging.

**Step 7.2:** Record: Mature CCU core (2016) with ongoing SoC additions.
Helper is shared and stable; this is not churny experimental code.

---

## Phase 8: Impact and risk

**Step 8.1:** Record: **platform-specific** — `CONFIG_SUNXI_CCU` /
Allwinner boards (phones, SBCs, TVs). Many LTS users.

**Step 8.2:** Record: Trigger = CCU **probe failure** after clocks are
registered (`of_clk_add_hw_provider` / reset register). Not every boot.
Not a userspace syscall. `of_clk_set_defaults()` is a realistic DT
failure. Unprivileged users do not trigger it directly.

**Step 8.3:** Record: Incomplete unregister → leak; wrong bound →
**OOB**; leftover `clk_hw` plus `kfree(ccu)` → **UAF** on `cclk->lock`.
Severity **HIGH** on the error path (crash / memory safety), not a
normal-boot oops.

**Step 8.4:** Record: **Benefit high** for Allwinner error-path safety;
**risk very low** (6-line index fix). Ratio strongly favors backport.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**

FOR:
- Real OOB/leak in shared CCU probe cleanup; counts differ on H6/A64/RTC
  in this tree
- Sashiko High; maintainer Reviewed-by + applied
- Tiny, obviously correct, no new API
- Bug from v6.10 (`ea977d742507e`) is in this tree
- No extra series patches required

AGAINST:
- Error-path only (not every boot)
- Nested in an A733 **feature** series (this patch is still self-
  contained)
- No live user oops; found by static review
- No `Fixes:` / `Cc: stable` (not a negative here)

UNRESOLVED:
- lore HTML 403 (mbox/raw used instead)
- Exact production hit rate of `of_clk_set_defaults()` failure on CCU
  nodes

**Step 9.2: Stable rules**
1. Obviously correct and tested — **PASS** (maintainer review; logic is
   local)
2. Real bug affecting users — **PASS** (Allwinner CCU probe fail →
   leak/OOB)
3. Important (crash/corruption/deadlock/security) — **PASS** (OOB;
   incomplete unwind + free of lock)
4. Small and contained — **PASS** (12 lines, one function)
5. No new features/APIs — **PASS**
6. Can apply to this tree — **PASS**

**Step 9.3: Exception category**
Record: None (not an ID/quirk/DT/build/doc exception). It is a normal
small bugfix.

**Step 9.4: Decision**
This tree is **7.3-rc4**. The helper and the v6.10 index-clobber exist
here. The patch is a surgical error-path memory-safety fix for every
sunxi-ng CCU, including OOB on RTC when `num_ccu_clks` (12) exceeds
`hw_clks->num` (8). It meets stable rules with very low regression risk.

---

### Problem and why it matters

`sunxi_ccu_probe()` registered `hw_clks` with index `i`, then reused `i`
to walk `ccu_clks` for rate limits. On later failure it unregistered
with that leftover `i`. Those array lengths differ on real SoCs, so
cleanup either walks off `hws[]` or leaves clocks registered (and can
free the `ccu` lock those clocks still use). Stable Allwinner devices
share this helper.

### Stable rules / risk

Small, reviewed, no features, applies cleanly. Benefit is avoiding
OOB/UAF on CCU probe failure; risk is a loop-index change only.

### Concerns

Needs `ea977d742507e` (present here). Do not pull the rest of the A733
series. Trigger is probe-error, not hot-path, but the failure mode is
memory safety.

Verification:
- [Phase 1] Tags: Sashiko Reported-by/Closes, Chen-Yu Reviewed-by, msgid
  v4 3/9; no Fixes/Cc stable
- [Phase 2] Diff: `i` vs `j` in `sunxi_ccu_probe()`; +6/−6 in
  `ccu_common.c`
- [Phase 3] `git describe HEAD` → `v7.3-rc4-27-gf0100363d8c37`; blame:
  bug from `ea977d742507e` (v6.10-rc7); `git merge-base --is-ancestor
  ea977d742507e HEAD` → yes
- [Phase 3] `git log --oneline -- drivers/clk/sunxi-ng/ccu_common.c`:
  candidate `81f4ddc9f7e0c`; later commits are A733 features, not
  prerequisites
- [Phase 4] `b4 dig -c 81f4ddc9f7e0c` → lore msgid; `-a` v1–v4; `-w`
  sunxi/clk maintainers; `-m` 25-message mbox; Chen-Yu applied 3/9; no
  NAK
- [Phase 4] Original Sashiko report (curl raw): High, wrong loop limit,
  leak or OOB
- [Phase 4] Stable lore search: no prior stable-thread hit
- [Phase 5] Callers: `devm_sunxi_ccu_probe` / `of_sunxi_ccu_probe` → all
  sunxi-ng CCU drivers
- [Phase 5] H6 127 vs 138; A64 104 vs 115; RTC 12 vs 8
  (`CLK_NUMBER_NO_GATES`) verified in tree
- [Phase 5] `of_clk_add_hw_provider` can return `-ENOMEM` or
  `of_clk_set_defaults` error
- [Phase 6] Pre-fix source at `81f4ddc9f7e0c^` still uses one `i`;
  current file already has `j`
- [Phase 7] MAINTAINERS: Chen-Yu Tsai maintains `drivers/clk/sunxi-ng/`
- [Phase 8] Failure mode: OOB / leak / possible lock UAF on probe error
  — HIGH, error-path
- UNVERIFIED: live user crash report beyond Sashiko; lore HTML pages
  (403)

**YES**

 drivers/clk/sunxi-ng/ccu_common.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index c7e00f0c29a55..bbda75c2bc461 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -114,7 +114,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 			   const struct sunxi_ccu_desc *desc)
 {
 	struct ccu_reset *reset;
-	int i, ret;
+	int i, j, ret;
 
 	ccu->desc = desc;
 
@@ -130,8 +130,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 		cclk->lock = &ccu->lock;
 	}
 
-	for (i = 0; i < desc->hw_clks->num ; i++) {
-		struct clk_hw *hw = desc->hw_clks->hws[i];
+	for (j = 0; j < desc->hw_clks->num ; j++) {
+		struct clk_hw *hw = desc->hw_clks->hws[j];
 		const char *name;
 
 		if (!hw)
@@ -143,7 +143,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 		else
 			ret = of_clk_hw_register(node, hw);
 		if (ret) {
-			pr_err("Couldn't register clock %d - %s\n", i, name);
+			pr_err("Couldn't register clock %d - %s\n", j, name);
 			goto err_clk_unreg;
 		}
 	}
@@ -186,8 +186,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 err_del_provider:
 	of_clk_del_provider(node);
 err_clk_unreg:
-	while (--i >= 0) {
-		struct clk_hw *hw = desc->hw_clks->hws[i];
+	while (--j >= 0) {
+		struct clk_hw *hw = desc->hw_clks->hws[j];
 
 		if (!hw)
 			continue;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] ARM: OMAP2+: Add CFI type for omap4_finish_suspend
  2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
                   ` (47 preceding siblings ...)
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] clk: sunxi-ng: fix ccu probe clock unregister on error Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  48 siblings, 0 replies; 50+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Mithil Bavishi, Nathan Chancellor, Andreas Kemnade,
	Kevin Hilman (TI), Sasha Levin, aaro.koskinen, rogerq, tony,
	linux, linux-arm-kernel, linux-omap, linux-kernel

From: Mithil Bavishi <bavishimithil@gmail.com>

[ Upstream commit 4a7b197ad28d71f9fac873f283b4408df3fdb287 ]

With CONFIG_CFI enabled, OMAP4 can trap in omap4_enter_lowpower()
because omap_pm_ops.finish_suspend points directly to the assembly
routine omap4_finish_suspend, which lacks the expected KCFI type
metadata.

Annotate omap4_finish_suspend with SYM_TYPED_FUNC_START so the assembly
routine carries the KCFI type metadata.

Signed-off-by: Mithil Bavishi <bavishimithil@gmail.com>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Andreas Kemnade <andreas@kemnade.info>
Link: https://patch.msgid.link/20260604054048.18980-1-bavishimithil@gmail.com
Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.53**. The patch is a three-line CFI annotation
for an OMAP4 assembly suspend finisher that is called through a C
function pointer, so a `CONFIG_CFI` kernel can oops on idle/suspend.
That is a real crash with a tiny, standard fix.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[ARM: OMAP2+]** **[Add]** Add KCFI type metadata for assembly
`omap4_finish_suspend`. The verb is “Add”, but the body is a CFI-trap
fix, not a feature.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Reviewed-by: Nathan Chancellor (Clang/CFI)
- Reviewed-by: Andreas Kemnade (OMAP)
- Link: https://patch.msgid.link/20260604054048.18980-1-
  bavishimithil@gmail.com
- Signed-off-by: Mithil Bavishi (author)
- Signed-off-by: Kevin Hilman (TI) (OMAP maintainer; applied)
- No Fixes:, Reported-by, Tested-by, or Cc: stable (absence expected)
- Ignore pipeline “Upstream commit” / Sasha Levin SOB

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: with `CONFIG_CFI`, OMAP4 can trap in `omap4_enter_lowpower()`
  because `omap_pm_ops.finish_suspend` points at assembly
  `omap4_finish_suspend` with no KCFI type hash.
- Symptom: CFI failure / oops on low-power entry.
- Root cause: indirectly called asm lacks `__kcfi_typeid_*`.
- Fix: `SYM_TYPED_FUNC_START` / `SYM_FUNC_END`.
- No version range given; ARM CFI itself is from 6.11.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not disguised. It is an explicit CFI-trap fix, same class as
other `SYM_TYPED_FUNC_START` annotations.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `arch/arm/mach-omap2/sleep44xx.S` (+3 / −2)
- Functions: `omap4_finish_suspend` only
- Scope: single-file surgical annotation

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Hunk 1: `#include <linux/cfi_types.h>` so `SYM_TYPED_FUNC_START` is
  defined.
- Hunk 2: `ENTRY(omap4_finish_suspend)` →
  `SYM_TYPED_FUNC_START(omap4_finish_suspend)`. Without `CONFIG_CFI`
  this is the same as `SYM_FUNC_START`/`ENTRY`. With CFI it emits
  `.4byte __kcfi_typeid_omap4_finish_suspend` before the symbol.
- Hunk 3: `ENDPROC` → `SYM_FUNC_END` (paired end; ARM `ENDPROC` vs
  generic `SYM_FUNC_END` is ELF metadata only).
- Path: function prologue of the suspend finisher; no control-flow
  change.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **(h) hardware/CFI metadata + (g) correctness.** Indirect call
to asm without a type hash. Compiler CFI checks at
`omap_pm_ops.finish_suspend(...)` fail → trap. Fix attaches the
compiler-emitted type id to the asm entry.

Step 2.4: ASSESS THE FIX QUALITY
Record: Obviously correct and the established pattern
(`include/linux/cfi_types.h`). No locking, no API, no data-structure
change. Regression risk is very low: without CFI it is equivalent to
`ENTRY`/`SYM_FUNC_START`; with CFI it only adds the expected hash.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: `ENTRY(omap4_finish_suspend)` body from Santosh Shilimkar,
`b2b9762f76981` (2010). Function-pointer assignment
`omap_pm_ops.finish_suspend = omap4_finish_suspend` from `9f192cf7dad8f`
(2013). The crash only appears after ARM CFI (`1a4fec49efe52`, “ARM:
9392/2: Support CLANG CFI”, 2024-04-29, in v6.11+).

Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. Buggy combination is long-lived asm + CFI on ARM
since 6.11.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: File is quiet. Last functional change before this was
`2402ff05c6e6b` (use `v7_invalidate_l1`). Standalone, not “patch X/Y”.
Maintainer applied it as `[1/1]`.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Mithil Bavishi’s nearby work here is OMAP DT (Galaxy Tab 2), not
a CFI series. Reviewers are the domain experts.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Needs `SYM_TYPED_FUNC_START` (`e84e008e7b02`, 2022) and ARM
`ARCH_SUPPORTS_CFI` (`1a4fec49efe52`). Both are ancestors of this
6.18.53 tree. Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c 4a7b197ad28d71f9fac873f283b4408df3fdb287` → v3 https://patc
  h.msgid.link/20260604054048.18980-1-bavishimithil@gmail.com
- `b4 dig -a`: v2 2026-05-22, v3 2026-06-03 (applied)
- v1 (May 12): “Make OMAP4 finish_suspend callback CFI-safe”. Nathan
  asked for `SYM_TYPED_FUNC_START` and whether other `omap_pm_ops`
  members need it. Andreas: `omap4_cpu_resume` / secondary startup are
  stored as `u32` phys addrs (no CFI); `scu_prepare` is C. Only
  `finish_suspend` needs the annotation.
- Kevin Hilman applied v3 (`d58849ac3044` in his tree). No NAK found.
- lore.kernel.org fetches returned 403; discussion recovered from b4,
  spinics, LKML mirrors, openwall.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: `b4 dig -w` CCs: OMAP maintainers (Kemnade, Hilman, Lindgren,
Quadros, Koskinen), RMK, Sami Tolvanen, Kees Cook, Nathan Chancellor,
linux-omap, linux-arm-kernel, llvm@. Right people.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla. Mechanism is described in the patch;
reviewers treated it as a real CFI trap, not speculative.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone. v1→v3 is the same fix rewritten to
`SYM_TYPED_FUNC_START`.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned 403. UNVERIFIED whether stable@
already discussed it. No local `git log` hit for a prior OMAP4 CFI
annotation.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `omap4_finish_suspend` (asm). Callers use
`omap_pm_ops.finish_suspend`.

Step 5.2: TRACE CALLERS
Record (verified in this tree):
- `omap-mpuss-lowpower.c:440` assigns the pointer on OMAP44xx.
- `omap4_enter_lowpower()`: `cpu_suspend(...,
  omap_pm_ops.finish_suspend)` or
  `omap_pm_ops.finish_suspend(save_state)` (C indirect call — CFI-
  checked).
- `omap4_hotplug_cpu()`: always `omap_pm_ops.finish_suspend(cpu_state)`.
- `pm44xx.c:79` → suspend.
- `cpuidle44xx.c:108,187` → idle.

Step 5.3: TRACE CALLEES
Record: cache flush, SCU power mode, WFI. Unchanged.

Step 5.4: FOLLOW THE CALL CHAIN
Record: cpuidle / suspend / hotplug → `omap4_enter_lowpower` /
`omap4_hotplug_cpu` → indirect call. Userspace-reachable via idle and
suspend. On CFI failure ARM `hw_breakpoint_cfi_handler` does `die("Oops
- CFI", ...)` unless `CFI_PERMISSIVE`.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: `omap4_cpu_resume` still uses `ENTRY` — intentional (ROM jump
via phys addr). Rest of mach-omap2 asm is not stored in that C function-
pointer slot. Widespread `SYM_TYPED_FUNC_START` in
`arch/arm/mm/proc-*.S`.

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

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. `git describe HEAD` = **v6.18.53-5049-g0f0bdc2b0dffb**,
`make kernelversion` = **6.18.53**. `v6.18.53` has
`ENTRY(omap4_finish_suspend)` and `ARCH_SUPPORTS_CFI`. `git diff
v6.18.53 -- arch/arm/mach-omap2/sleep44xx.S` is exactly this patch.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. File otherwise unchanged vs v6.18.53.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: No other omap4_finish_suspend CFI fix. This tree already has
other ARM CFI work (`ARM: 9481/2: breakpoint: CFI breakpoints only on
demand`), so CFI-on-ARM is in-scope for 6.18.y.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: `arch/arm/mach-omap2` platform PM. **PERIPHERAL** hardware, but
the path is idle/suspend (high frequency if that SoC + CFI is used).

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature; sleep44xx.S rarely changes. Bug is CFI enablement
meeting old code, not new churn.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver/platform + config: `CONFIG_ARCH_OMAP4` and `CONFIG_CFI`.
Not universal.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: CPU idle, suspend, hotplug on OMAP4 with CFI. Not an
unprivileged exploit; it is a false CFI hit on a legitimate call. With
default CFI (non-permissive) it oopses.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: CFI mismatch → `report_cfi_failure()` → `BUG_TRAP_TYPE_BUG` →
`die("Oops - CFI")`. **HIGH** (oops/panic on idle/suspend). Permissive
CFI is warn-only.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: medium-high for OMAP4+CFI (otherwise idle/suspend is broken);
  none otherwise, and the macros are inert without CFI.
- Risk: very low (3 lines, no behavior change off CFI).
- Ratio: favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real CFI trap → oops on a live idle/suspend/hotplug path
- ARM CFI exists in this 6.18.y tree
- Tiny, standard, reviewed by CFI and OMAP maintainers
- Applies cleanly; helpers already present
- Harmless when CFI is off

AGAINST:
- Only `ARCH_OMAP4` + `CONFIG_CFI` (small population)
- No public crash log / syzbot
- OMAP4 is old

UNRESOLVED:
- lore.kernel.org 403; no stable@ thread recovered
- No independent Tested-by on hardware in the tags

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — standard annotation;
   Reviewed-by Nathan Chancellor and Andreas Kemnade
2. Fixes a real bug that affects users? **PASS** — CFI false positive on
   indirect call
3. Important issue? **PASS** — oops/panic on idle/suspend when CFI is on
   (HIGH, config-specific)
4. Small and contained? **PASS** — 5 lines, one file
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — identical context on v6.18.53

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/docs patch. Closest analogue:
supported-config correctness (CFI annotation), like a build/runtime fix
for `CONFIG_CFI`.

Step 9.4: MAKE YOUR DECISION
The population is small, but the failure is a kernel oops on a common PM
path, the patch is three lines and matches existing ARM CFI helpers in
this tree, and it does nothing when CFI is off. That meets 6.18.y stable
rules.

What it solves for this tree: 6.18 already selects `ARCH_SUPPORTS_CFI`.
OMAP4 still assigns the asm finisher to a C function pointer and calls
it from cpuidle/suspend. Without the type hash, a CFI kernel can
`die("Oops - CFI")` in `omap4_enter_lowpower()`. Benefit vs risk is
strongly in favor of backporting.

Verification:
- [Phase 1] Subject/tags: CFI-trap fix; Reviewed-by Nathan Chancellor,
  Andreas Kemnade; SOB Kevin Hilman; no Fixes/syzbot
- [Phase 2] Diff: sleep44xx.S +3/−2; include cfi_types.h;
  ENTRY→SYM_TYPED_FUNC_START; ENDPROC→SYM_FUNC_END
- [Phase 2] Without CONFIG_CFI, SYM_TYPED_FUNC_START == SYM_FUNC_START
  == ENTRY (include/linux/cfi_types.h, linkage.h)
- [Phase 3] blame: asm from b2b9762f76981 (2010); pointer assign
  9f192cf7dad8f (2013)
- [Phase 3] ARM CFI: 1a4fec49efe52 in v6.11 and in this tree (`git
  merge-base --is-ancestor`)
- [Phase 3] cfi_types.h: e84e008e7b02 in this tree; SYM_TYPED_FUNC_START
  present at v6.18.53
- [Phase 3] Standalone; parent of upstream 4a7b197ad28d7 is 7.2-rc1 (not
  in 6.18 mainline, hence backport)
- [Phase 4] b4 dig: v2+v3 lore URLs; v3 applied by Hilman; v1 review:
  only finish_suspend needs typing
- [Phase 4] Recipients: OMAP + LLVM/CFI maintainers
- [Phase 4] UNVERIFIED: stable@ discussion (lore 403)
- [Phase 5] Callers: omap4_enter_lowpower, omap4_hotplug_cpu;
  cpuidle44xx.c, pm44xx.c
- [Phase 5] ARM CFI handler: hw_breakpoint.c die("Oops - CFI") on
  BUG_TRAP_TYPE_BUG
- [Phase 5] kernel/cfi.c: default non-permissive → BUG
- [Phase 6] git describe HEAD: v6.18.53-5049-g0f0bdc2b0dffb;
  kernelversion 6.18.53
- [Phase 6] git diff v6.18.53 -- sleep44xx.S is this patch (clean apply)
- [Phase 8] Trigger: idle/suspend/hotplug; severity HIGH oops; risk very
  low
- UNVERIFIED: hardware Tested-by; lore.kernel.org full thread text (403)

**YES**

 arch/arm/mach-omap2/sleep44xx.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
index f09c9197808b1..8b515f30072b0 100644
--- a/arch/arm/mach-omap2/sleep44xx.S
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -6,6 +6,7 @@
  * 	Santosh Shilimkar <santosh.shilimkar@ti.com>
  */
 
+#include <linux/cfi_types.h>
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/smp_scu.h>
@@ -58,7 +59,7 @@
  * stack frame and it expects the caller to take care of it. Hence the entire
  * stack frame is saved to avoid possible stack corruption.
  */
-ENTRY(omap4_finish_suspend)
+SYM_TYPED_FUNC_START(omap4_finish_suspend)
 	stmfd	sp!, {r4-r12, lr}
 	cmp	r0, #0x0
 	beq	do_WFI				@ No lowpower state, jump to WFI
@@ -223,7 +224,7 @@ skip_scu_gp_clear:
 	isb
 	dsb
 	ldmfd	sp!, {r4-r12, pc}
-ENDPROC(omap4_finish_suspend)
+SYM_FUNC_END(omap4_finish_suspend)
 
 /*
  * ============================
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2026-10-19 14:06 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] iommu/rockchip: Clear stale page faults before enabling stall Sasha Levin
2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-6.6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: clocking-wizard: fix clock difference detection Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.1] net: stmmac: fix device node reference leaks in stmmac_mtl_setup() Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] arm64: mm: fix accidental linear mapping of no-map reserved memory Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] perf/arm-cmn: Add workarounds for CMN-S3 on Graviton5 Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] perf: marvell: Cancel CN10K DDR PMU hrtimer on device remove Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18] soc: amlogic: meson-clk-measure: remove debugfs tree Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/tegra241-cmdqv: Rate-limit the error ISR's log message Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] mmc: sdhci-of-ma35d1: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp: " Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18] memory: stm32_omm: initialize ret in stm32_omm_set_amcr Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.12] iommu/arm-smmu-qcom: Add SM8450 MDSS compatible Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: zynq: handle kasprintf() failure in periph_clk registration Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] media: cec: stm32: return an error when log-address wait times out Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] drm/rockchip: dw_hdmi: Use resume_early pm ops for system suspend Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] rtc: brcmstb-waketimer: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] net: stmmac: use dma_addr_t for DMA addresses Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] firmware: imx: scu: manage mailbox channels and global handle Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.15] net: stmmac: raise TX completion interrupt at the end of an xmit burst Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] soc: ixp4xx: qmgr: " Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] RISC-V: perf: fix resource cleanup on driver probe failure Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] spi: bcmbca-hsspi: return error from failed controller suspend Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] i2c: imx-lpi2c: properly unwind resources on probe failure Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] clk: sunxi-ng: fix ccu probe clock unregister on error Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] ARM: OMAP2+: Add CFI type for omap4_finish_suspend Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox