* [PATCH AUTOSEL 6.18] usb: xhci: remove legacy 'num_trbs_free' tracking
[not found] <20260831133314.4125787-1-sashal@kernel.org>
@ 2026-08-31 13:21 ` Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] xhci: Prevent queuing new commands if xhci is inaccessible Sasha Levin
` (21 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Niklas Neronin, Mathias Nyman, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb, linux-kernel
From: Niklas Neronin <niklas.neronin@linux.intel.com>
[ Upstream commit 7ee645963075651d72f8d85bee428a9b7f1f148c ]
Keeping track of free TRBs in a ring by adding and subtracting each time
a enqueue or dequeue pointer is modified has proven to be buggy and
complicated, especially over long periods of time.
The xhci driver has already moved to calculating free TRBs dynamically
based on ring size and the enqueue/dequeue positions.
The DbC path is the last user of 'num_trbs_free'. Rather than maintaining
two separate accounting mechanisms, remove the field entirely and switch
DbC to use xhci_num_trbs_free(). Since 'num_trbs_free' undercounts by one,
and xhci_num_trbs_free() does not, the check for sufficient free TRBs is
adjusted.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260603091132.1110849-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.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: xhci]` `[remove]` — remove legacy `num_trbs_free`
tracking from the xHCI DbC (Debug Capability) path.
**Step 1.2 — Tags**
Record:
- `Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>`
(author)
- `Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>` (xHCI
maintainer)
- `Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>` (USB
maintainer)
- `Link: https://patch.msgid.link/20260603091132.1110849-3-
mathias.nyman@linux.intel.com`
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable@vger.kernel.org`
- Ignore `[Upstream commit ...]` and pipeline `Signed-off-by: Sasha
Levin` per instructions
Notable: maintainer sign-offs only; no explicit reporter or stable
nomination.
**Step 1.3 — Body**
Record:
- **Bug:** Manual `num_trbs_free` increment/decrement on enqueue/dequeue
is buggy and drifts over long runtimes.
- **Symptom:** Incorrect free-TRB accounting can cause DbC to believe
the transfer ring is full and refuse new transfers (`failed to queue
trbs` in related DbC fixes).
- **Root cause:** DbC was the last user of legacy counter-based
accounting; the rest of xHCI already uses dynamic
`xhci_num_trbs_free()`.
- **Fix:** Remove `num_trbs_free` field entirely; DbC uses
`xhci_num_trbs_free()`. Comparison adjusted from `< num_trbs` to `<=
num_trbs` because legacy counter undercounted by one.
- **Versions:** No explicit version range in message.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Despite “remove legacy tracking” wording, this fixes
incorrect ring-space accounting — the same class of bug fixed for main
transfer rings in `2710f8186f889` (“Stop unnecessary tracking of free
trbs in a ring”), with a user report and bugzilla for that path.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
| File | Change |
|------|--------|
| `xhci-dbgcap.c` | −4 manual counter ops, +1 dynamic check |
| `xhci-mem.c` | −6 (init of `num_trbs_free`) |
| `xhci-ring.c` | `static` → exported `xhci_num_trbs_free()` |
| `xhci.h` | Remove struct field, add prototype |
- Net: ~12 lines removed, ~3 added
- Functions: `xhci_dbc_queue_trb()`, `xhci_dbc_queue_bulk_tx()`,
`dbc_handle_xfer_event()`, `xhci_initialize_ring_info()`,
`xhci_num_trbs_free()`
- Scope: **single-subsystem surgical fix** (xHCI DbC only)
**Step 2.2 — Code flow per hunk**
Record:
1. **`xhci_dbc_queue_trb()`** — Before: decrement `num_trbs_free` on
enqueue. After: no manual accounting; enqueue pointer only.
2. **`xhci_dbc_queue_bulk_tx()`** — Before: `ring->num_trbs_free <
num_trbs` → `-EBUSY`. After: `xhci_num_trbs_free(ring) <= num_trbs` →
`-EBUSY`.
3. **`dbc_handle_xfer_event()`** — Before: `num_trbs_free++` on
completion and stale-stall giveback. After: no manual increments;
pointer-based calculation handles it.
4. **`xhci_initialize_ring_info()`** — Before: initialize
`num_trbs_free`. After: removed.
5. **`xhci_num_trbs_free()`** — Before: `static`. After: non-static +
header export for DbC use.
**Step 2.3 — Bug mechanism**
Record: **Logic/correctness fix — stale manual counter accounting.**
- Legacy path manually `++`/`--` on queue/complete/stall paths.
- Counter can drift from actual ring state (noop TRBs, stall handling,
long-lived sessions) — same failure mode fixed on main transfer rings
in `fe82f16aafda` / `2710f8186f889`.
- Dynamic `xhci_num_trbs_free()` derives free space from enqueue/dequeue
pointers and ring geometry.
**Step 2.4 — Fix quality**
Record:
- **Obviously correct:** Reuses the same mechanism already used for
command/transfer rings in this tree.
- **Minimal:** Removes duplicate accounting; no new APIs beyond
exporting an existing function.
- **Regression risk:** Low. Comparison operator change (`<` → `<=`) is
documented compensation for the one-TRB undercount in legacy init (`-
1` in `xhci-mem.c:325`).
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: `num_trbs_free` initialization dates to `b008df60c6369b` (Andiry
Xu, 2012-03-05). Legacy accounting has been present since early xHCI;
main path stopped using it in `2710f8186f889` (2023). DbC retained it
until this commit.
**Step 3.2 — Fixes: tag**
Record: Not applicable — no `Fixes:` tag. Related introducing/fix
commits in tree:
- `2710f8186f889` — main path moved to dynamic calculation (in tree)
- `fe82f16aafda` — original transfer-ring accounting bug (user report,
Cc: stable)
- `a5c98e8b13985` — DbC ring-full workaround on reconnect (in tree, Cc:
stable)
**Step 3.3 — Related file history**
Record: Recent DbC fixes in this tree include `a5c98e8b13985` (ring full
after reconnects), `f3d12ec847b94` (stall race), `2bbd38fcd2967`
(resume). This commit is standalone (not “patch X/Y”); `5adc1cc038f44`
(off-by-one in `xhci_num_trbs_free`) is already present. No other series
dependency.
**Step 3.4 — Author context**
Record: Niklas Neronin is an active Intel xHCI contributor
(`931e468764b22`, `ff9a09b3e09c7`, etc.). Mathias Nyman is the xHCI
maintainer and authored the original transfer-ring accounting fix.
**Step 3.5 — Prerequisites**
Record:
- `xhci_num_trbs_free()` exists (static) in `xhci-ring.c:342` —
**present**
- `2710f8186f889` main-path refactor — **present**
- `5adc1cc038f44` off-by-one fix — **present**
- DbC support (`dfba2174dc42`, 2017) — **present**
- Patch applies cleanly (`git apply --check` passed)
- **Standalone:** yes
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: `b4 dig -c 9e332a74fa0de` → https://patch.msgid.link/20260521080
426.258909-1-niklas.neronin@linux.intel.com. Single-patch submission
(not a multi-revision series). Mbox downloaded; no review replies,
stable nominations, or NAKs in thread.
**Step 4.2 — Reviewers**
Record: `b4 dig -w` shows CC to `mathias.nyman@linux.intel.com` and
`linux-usb@vger.kernel.org`. Mathias Nyman Signed-off-by on committed
version.
**Step 4.3 — Bug reports**
Record: No `Reported-by:` or syzbot link for this commit. Related bug
context from `fe82f16aafda` / bugzilla #217242 applies to the same
accounting mechanism on transfer rings. Related DbC symptom documented
in `a5c98e8b13985`: `"failed to queue trbs"`.
**Step 4.4 — Series context**
Record: Commit Link references `...1110849-3-...` (possibly part of a
3-patch series on a later submission), but the committed diff is self-
contained. No other patches required.
**Step 4.5 — Stable list**
Record: Not searched on lore stable (WebFetch blocked). No stable
nomination in commit or mbox thread. Not a negative signal per
instructions.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `xhci_dbc_queue_bulk_tx()`, `dbc_handle_xfer_event()`,
`xhci_num_trbs_free()`, `dbc_ep_do_queue()`.
**Step 5.2 — Callers**
Record:
- `xhci_dbc_queue_bulk_tx()` ← `dbc_ep_do_queue()` ← `dbc_ep_queue()`
(TTY/gadget write path)
- `dbc_handle_xfer_event()` ← event polling workqueue in DbC
- `xhci_num_trbs_free()` also used in `xhci-ring.c:3328` for command-
ring space checks
Impact surface: **CONFIG_USB_XHCI_DBGCAP** users only; not general USB
hot path.
**Step 5.3 — Callees**
Record: `xhci_num_trbs_free()` walks ring segments using `enqueue`,
`dequeue`, `enq_seg`, `deq_seg`. `count_trbs()`, `xhci_dbc_queue_trb()`,
`xhci_dbc_giveback()` on queue/complete paths.
**Step 5.4 — Reachability**
Record: Triggered when DbC is configured and TTY I/O is active over USB3
debug port. Requires `CONFIG_USB_XHCI_DBGCAP=y` and hardware with xHCI
DbC. Not a general syscall path, but reachable by any user with debug-
cable access and DbC enabled.
**Step 5.5 — Similar patterns**
Record: Main xHCI path already uses `xhci_num_trbs_free(ep_ring) <=
num_trbs` at `xhci-ring.c:3328`. This commit aligns DbC with that
pattern and removes the last manual counter user.
---
## Phase 6: Cross-Reference Against Local Tree (v6.18.44)
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is `v6.18.44` / `6.18.44`. Commit
`9e332a74fa0de` is **not** an ancestor of HEAD. Legacy code present at:
- `xhci-dbgcap.c:263,284,785,850`
- `xhci-mem.c:325`
- `xhci.h:1380`
**Step 6.2 — Backport complications**
Record: **Clean apply expected.** `git apply --check` on the patch
succeeded with no conflicts. File structure matches upstream diff
context.
**Step 6.3 — Related fixes already present?**
Record: `a5c98e8b13985` (DbC ring reinit on disconnect) is in tree —
symptom workaround for ring-full case. This commit addresses the
underlying accounting mechanism. The dynamic-calculation infrastructure
(`xhci_num_trbs_free`, `2710f8186f889`) is already in tree. This
specific DbC migration is **not** yet applied.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: **drivers/usb/host (xHCI DbC)** — IMPORTANT for developers using
USB3 debug port; PERIPHERAL for general production workloads (optional
Kconfig, default off).
**Step 7.2 — Activity**
Record: xHCI DbC actively maintained — 10+ DbC commits in recent history
on `xhci-dbgcap.c`.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users with `CONFIG_USB_XHCI_DBGCAP=y` on xHCI hosts with DbC
hardware — kernel developers, early-debug/remote-console setups. Not
universal.
**Step 8.2 — Trigger conditions**
Record:
- Long-running DbC sessions
- Stall/no-op TRB handling paths
- Repeated connect/disconnect (partially mitigated by `a5c98e8b13985`,
but accounting drift can occur in other paths)
- Likelihood: low-to-moderate for active DbC users over time; not every
boot
**Step 8.3 — Failure mode severity**
Record:
- **Failure:** DbC returns `-EBUSY`, prints `"failed to queue trbs"`,
debug port stops accepting I/O
- **Severity: MEDIUM** — functional failure of debug infrastructure; not
kernel crash, deadlock, data corruption, or security issue
- Does not affect normal USB device operation
**Step 8.4 — Risk/benefit**
Record:
- **Benefit:** Prevents false ring-full conditions; completes removal of
known-buggy accounting (same class as stable-worthy
`fe82f16aafda`/`2710f8186f889`)
- **Risk:** Very low — 15-line net deletion, uses existing tested
function, maintainer-reviewed
- **Ratio:** Moderate benefit for small DbC user base, very low risk
---
## Phase 9: Final Synthesis
**Evidence FOR backport:**
- Fixes real accounting bug (same mechanism as user-reported transfer-
ring bug)
- Small, surgical, applies cleanly to v6.18.44
- All prerequisites already in tree
- DbC ring-full fixes already accepted for stable (`a5c98e8b13985` with
Cc: stable)
- xHCI maintainers (Nyman, Kroah-Hartman) signed off
- Removes duplicate/error-prone code path
**Evidence AGAINST backport:**
- Only affects optional `CONFIG_USB_XHCI_DBGCAP` (debug feature)
- No explicit user report or syzbot for this specific DbC commit
- Failure mode is debug-port unusability, not crash/corruption/security
- Symptom partially mitigated by existing `a5c98e8b13985` reconnect
workaround
**Unresolved questions:**
- No review-thread discussion beyond sign-offs
- Exact long-run drift scenarios for DbC not documented with a specific
reporter
**Stable rules checklist:**
1. Obviously correct and tested? **PASS** — reuses proven
`xhci_num_trbs_free()`, maintainer SOBs; no Tested-by
2. Fixes a real bug? **PASS** — legacy counter drift is a documented
real bug class
3. Important issue? **PASS (borderline)** — debug infrastructure
failure, not crash/corruption; comparable to memory-growth fix that
went stable for main path
4. Small and contained? **PASS** — 4 files, ~15 lines net
5. No new features/APIs? **PASS** — refactor only; exporting existing
function is not a userspace API
6. Can apply to local tree? **PASS** — verified clean apply
**Exception category:** None (not device ID, quirk, DT, build, or docs).
---
## Problem Summary for Stable Users
The xHCI driver stopped using manual `num_trbs_free` counter tracking
for normal transfer/command rings in 2023 because it drifted over time
(user-reported memory growth from unnecessary ring expansion). DbC (USB3
debug port / `ttyDBC`) was left on the old mechanism. Over long
sessions, especially with stall/no-op TRB edge cases, the counter can
desync from actual ring state, causing DbC to falsely report the ring as
full and refuse transfers with `"failed to queue trbs"`. This commit
switches DbC to the same dynamic calculation used everywhere else — a
low-risk completion of an already-stable refactoring.
For v6.18.44 specifically: the buggy code exists, prerequisites are
present, the patch applies cleanly, and related DbC ring-full fixes are
already in this tree.
## Verification
- [Phase 1] Parsed commit `9e332a74fa0de` message and tags via `git
show`
- [Phase 2] Full diff analyzed via `git show 9e332a74fa0de -p`
- [Phase 3] `git describe HEAD` → `v6.18.44`; `make kernelversion`
equivalent from Makefile → 6.18.44
- [Phase 3] `git merge-base --is-ancestor 9e332a74fa0de HEAD` → exit 1
(not in tree)
- [Phase 3] `git blame` on `xhci-mem.c:325` → `b008df60c6369b` (2012)
- [Phase 3] `2710f8186f889`, `5adc1cc038f44`, `dfba2174dc42` confirmed
ancestors of HEAD
- [Phase 3] `git log --grep='num_trbs_free'` found related history
- [Phase 4] `b4 dig -c 9e332a74fa0de` → lore URL found
- [Phase 4] `b4 dig -m /tmp/xhci_num_trbs.mbox` → mbox downloaded, no
review replies or stable CC
- [Phase 4] WebFetch of lore URLs blocked (403/Anubis); used b4 mbox
instead
- [Phase 5] `grep num_trbs_free` / `grep xhci_num_trbs_free` in
`drivers/usb/host/`
- [Phase 5] Read `xhci-dbgcap.c`, `xhci-ring.c:342-370`, `xhci-
ring.c:3328`, `Kconfig` for `USB_XHCI_DBGCAP`
- [Phase 6] Buggy code confirmed present at lines listed above
- [Phase 6] `git apply --check` on patch → clean apply
- [Phase 6] `a5c98e8b13985` confirmed in tree with Cc: stable and
`"failed to queue trbs"` symptom
- [Phase 8] Failure mode: false `-EBUSY` on DbC queue → debug port
stops; severity MEDIUM
**YES**The analysis is done for **usb: xhci: remove legacy
'num_trbs_free' tracking** on the **v6.18.44** tree.
**Summary:** This is a small DbC-only fix that drops manual TRB free-
space counting (known to drift) and uses the existing
`xhci_num_trbs_free()` path instead. The buggy code is still present in
this tree, prerequisites are already there, and the patch applies
cleanly. Main downside: it only affects `CONFIG_USB_XHCI_DBGCAP` users,
and the failure mode is the debug port stopping with `"failed to queue
trbs"`, not a crash or data corruption.
**Recommendation: YES** for backport to this stable tree.
drivers/usb/host/xhci-dbgcap.c | 5 +----
drivers/usb/host/xhci-mem.c | 6 ------
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci.h | 2 +-
4 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index ecda964e018ac..e2e0694d0c22a 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -260,7 +260,6 @@ xhci_dbc_queue_trb(struct xhci_ring *ring, u32 field1,
trace_xhci_dbc_gadget_ep_queue(ring, &trb->generic,
xhci_trb_virt_to_dma(ring->enq_seg,
ring->enqueue));
- ring->num_trbs_free--;
next = ++(ring->enqueue);
if (TRB_TYPE_LINK_LE32(next->link.control)) {
next->link.control ^= cpu_to_le32(TRB_CYCLE);
@@ -281,7 +280,7 @@ static int xhci_dbc_queue_bulk_tx(struct dbc_ep *dep,
num_trbs = count_trbs(req->dma, req->length);
WARN_ON(num_trbs != 1);
- if (ring->num_trbs_free < num_trbs)
+ if (xhci_num_trbs_free(ring) <= num_trbs)
return -EBUSY;
addr = req->dma;
@@ -782,7 +781,6 @@ static void dbc_handle_xfer_event(struct xhci_dbc *dbc, union xhci_trb *event)
}
if (r->status == -COMP_STALL_ERROR) {
dev_warn(dbc->dev, "Give back stale stalled req\n");
- ring->num_trbs_free++;
xhci_dbc_giveback(r, 0);
}
}
@@ -847,7 +845,6 @@ static void dbc_handle_xfer_event(struct xhci_dbc *dbc, union xhci_trb *event)
break;
}
- ring->num_trbs_free++;
req->actual = req->length - remain_length;
xhci_dbc_giveback(req, status);
}
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 6e5b6057de79e..7f8c4a680832d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -317,12 +317,6 @@ void xhci_initialize_ring_info(struct xhci_ring *ring)
* handling ring expansion, set the cycle state equal to the old ring.
*/
ring->cycle_state = 1;
-
- /*
- * Each segment has a link TRB, and leave an extra TRB for SW
- * accounting purpose
- */
- ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
}
EXPORT_SYMBOL_GPL(xhci_initialize_ring_info);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 3f1a6089a01ce..859680bc74a2c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -339,7 +339,7 @@ static struct xhci_segment *trb_in_td(struct xhci_td *td, dma_addr_t suspect_dma
* Only for transfer and command rings where driver is the producer, not for
* event rings.
*/
-static unsigned int xhci_num_trbs_free(struct xhci_ring *ring)
+unsigned int xhci_num_trbs_free(struct xhci_ring *ring)
{
struct xhci_segment *enq_seg = ring->enq_seg;
union xhci_trb *enq = ring->enqueue;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 4cd4cb0e431d1..64f4207270f32 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1377,7 +1377,6 @@ struct xhci_ring {
u32 cycle_state;
unsigned int stream_id;
unsigned int num_segs;
- unsigned int num_trbs_free; /* used only by xhci DbC */
unsigned int bounce_buf_len;
enum xhci_ring_type type;
u32 old_trb_comp_code;
@@ -1953,6 +1952,7 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
void xhci_cleanup_command_queue(struct xhci_hcd *xhci);
void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring);
unsigned int count_trbs(u64 addr, u64 len);
+unsigned int xhci_num_trbs_free(struct xhci_ring *ring);
int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
int suspend, gfp_t gfp_flags);
void xhci_process_cancelled_tds(struct xhci_virt_ep *ep);
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] xhci: Prevent queuing new commands if xhci is inaccessible
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18] usb: xhci: remove legacy 'num_trbs_free' tracking Sasha Levin
@ 2026-08-31 13:21 ` Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Don't access path config space on Lane 1 adapters in tb_switch_reset_host() Sasha Levin
` (20 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Mathias Nyman, Greg Kroah-Hartman, Sasha Levin, mathias.nyman,
linux-usb, linux-kernel
From: Mathias Nyman <mathias.nyman@linux.intel.com>
[ Upstream commit 82b70c799281cc24506085be978b829149ba0ca4 ]
Refuse to queue a new command on the command ring if xHC is marked
inaccessible with the HCD_FLAG_HW_ACCESSIBLE.
HCD_FLAG_HW_ACCESSIBLE is set and cleared in suspend and resume.
Also print a warning if xhci is being suspended with commands
still pending on the command ring.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260603091132.1110849-13-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `xhci: Prevent queuing new commands if xhci
is inaccessible`
## Phase 1: Commit Message Forensics
**Step 1.1 – Subject line**
- Record: `[xhci] [Prevent] refuse to queue commands when xHC is marked
inaccessible via HCD_FLAG_HW_ACCESSIBLE`
**Step 1.2 – Tags**
- Record:
- `Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>`
(author)
- `Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>`
(USB maintainer)
- `Link: https://patch.msgid.link/20260603091132.1110849-13-
mathias.nyman@linux.intel.com`
- No `Fixes:`, `Reported-by:`, `Cc: stable@vger.kernel.org`, `Tested-
by:`, or `Reviewed-by:` tags
- Notable: no fuzzer or user bug report cited
**Step 1.3 – Body analysis**
- Record:
- **Bug:** `queue_command()` can still queue TRBs after
`HCD_FLAG_HW_ACCESSIBLE` is cleared during suspend
- **Symptom:** commands may be queued to an inaccessible controller;
suspend may proceed while commands are still pending
- **Version info:** none stated
- **Root cause:** `HCD_FLAG_HW_ACCESSIBLE` is cleared in
`xhci_suspend()` before the controller is fully stopped, but the
command-ring path did not honor that flag (unlike URB submission)
**Step 1.4 – Hidden bug fix?**
- Record: **Yes.** Although the subject says “Prevent” rather than
“fix”, this closes a real suspend/resume race: command submission
bypasses the same hardware-accessibility guard already used on the URB
path.
---
## Phase 2: Diff Analysis
**Step 2.1 – Inventory**
- Record:
- `drivers/usb/host/xhci-ring.c`: +6 lines
- `drivers/usb/host/xhci.c`: +4 lines
- Total: 10 lines added, 0 removed
- Functions modified: `queue_command()`, `xhci_suspend()`
- Scope: single-subsystem, surgical, 2-file fix
**Step 2.2 – Code flow change**
- Record:
- **`queue_command()` before:** only rejected commands when
`XHCI_STATE_DYING` or `XHCI_STATE_HALTED`
- **`queue_command()` after:** also rejects when
`!HCD_HW_ACCESSIBLE(hcd)`, returning `-ESHUTDOWN`
- **`xhci_suspend()` before:** cleared `HCD_FLAG_HW_ACCESSIBLE`, then
stopped xHC and cleared command ring, with no visibility into
pending commands
- **`xhci_suspend()` after:** warns if `cmd_list` is non-empty before
stopping the controller
**Step 2.3 – Bug mechanism**
- Record:
- **Category:** logic / synchronization gap during suspend
- **Mechanism:** `xhci_suspend()` clears `HCD_FLAG_HW_ACCESSIBLE` at
line 999 while holding `xhci->lock`, then later calls
`xhci_clear_command_ring()`. `queue_command()` had no equivalent
check, unlike `xhci_urb_enqueue()` which already checks
`HCD_HW_ACCESSIBLE` at line 1658. Command callers such as
`xhci_setup_device()` use `xhci->mutex`, not `xhci->lock`, so they
are not serialized against suspend. A thread can pass the
`xhci->xhc_state` check, then lose the race to suspend, queue a
command, and ring the doorbell via `xhci_ring_cmd_db()` against
inaccessible hardware.
**Step 2.4 – Fix quality**
- Record:
- Fix is minimal and mirrors an existing pattern in the same driver
- Centralized in `queue_command()`, protecting all command submission
paths
- Low regression risk: returns `-ESHUTDOWN`, same as dying/halted case
- Warning in suspend is diagnostic only; no behavior change beyond
logging
---
## Phase 3: Git History Investigation
**Step 3.1 – Blame**
- Record:
- `queue_command()` core logic dates to Sarah Sharp, 2009–2010
- `HCD_FLAG_HW_ACCESSIBLE` clearing in `xhci_suspend()` introduced in
`5535b1d5f88856` (Andiry Xu, 2010-10-14)
- Shared-HCD mirroring of the flag in `873f323618c202` /
`b320937972d45` (2022/2011)
- Buggy missing check has been present since HW_ACCESSIBLE was added
to suspend
**Step 3.2 – Fixes: tag**
- Record: N/A — no `Fixes:` tag in commit message
**Step 3.3 – Related file history**
- Record:
- Recent xhci work in this tree includes suspend/resume fixes
(`ff9a09b3e09c7`), command-timeout handling, and HCE interrupt-storm
fixes
- This patch is **standalone** — patch 12/15 in the “xhci features for
usb-next” series; it does not depend on patches 1–11 or 13–15
**Step 3.4 – Author context**
- Record: Mathias Nyman is a long-time xhci maintainer with many xhci
suspend/command-ring fixes in this tree
**Step 3.5 – Dependencies**
- Record: No prerequisites. Uses `HCD_HW_ACCESSIBLE()` /
`xhci_to_hcd()`, both present in this tree. `git apply --check`
succeeds cleanly.
---
## Phase 4: Mailing List and External Research
**Step 4.1 – Original discussion**
- Record:
- Lore thread fetched via `b4 mbox`: `/tmp/xhci_b4/20260603091132.1110
849-13-mathias.nyman@linux.intel.com.mbx`
- Patch is `[PATCH 12/15]` in series `[PATCH 00/15] xhci features for
usb-next`
- Cover letter describes the series as “generic improvements,
cleanups, refactoring and some DbC hung state detection and
recovery”
- No explicit stable nomination found in thread for patch 12/15
- No NAKs found for this specific patch
**Step 4.2 – Reviewers**
- Record: Series sent to `linux-usb@vger.kernel.org`; Greg Kroah-Hartman
Signed-off-by on the committed form
**Step 4.3 – Bug report**
- Record: No external bug report, syzbot link, or stack trace. Related
RFT DbC runtime-suspend work exists in the same thread but is a
separate patch.
**Step 4.4 – Series context**
- Record: Other patches in the series are mostly cleanups/refactors/DbC
features; this patch is independently backportable
**Step 4.5 – Stable list history**
- Record: Not searched separately; no stable-list discussion found in
fetched thread
---
## Phase 5: Code Semantic Analysis
**Step 5.1 – Key functions**
- Record: `queue_command()`, `xhci_suspend()`, and indirectly all
`xhci_queue_*()` wrappers
**Step 5.2 – Callers**
- Record: `queue_command()` is reached from many paths including:
- `xhci_queue_address_device()` → `xhci_setup_device()`
- `xhci_queue_configure_endpoint()` / `xhci_queue_evaluate_context()`
- `xhci_queue_slot_control()` (enable/disable slot)
- `xhci_queue_stop_endpoint()` (hub suspend, endpoint stop)
- `xhci_set_tr_deq()` (Set TR Dequeue Pointer)
- All are on device enumeration, configuration, disconnect, and
suspend/resume paths
**Step 5.3 – Callees**
- Record: `prepare_ring()`, `queue_trb()`, `list_add_tail()` to
`cmd_list`; callers then often invoke `xhci_ring_cmd_db()` which does
`writel()`/`readl()` on doorbell registers
**Step 5.4 – Reachability**
- Record: Reachable from normal USB operations and from suspend/resume.
`xhci_setup_device()` is reachable during enumeration; suspend can
interleave because it uses a different lock (`xhci->lock` vs
`xhci->mutex`). Buggy path is realistically triggerable during system
suspend on laptops/desktops with xHCI.
**Step 5.5 – Similar patterns**
- Record:
- `xhci_urb_enqueue()` already checks `HCD_HW_ACCESSIBLE` (line 1658)
- `xhci-hub.c` hub resume checks `HCD_HW_ACCESSIBLE` (line 1894)
- `xhci_suspend()` early-returns if already inaccessible (line 980)
- EHCI/OHCI/UHCI drivers check `HCD_HW_ACCESSIBLE` in hot paths
- xhci command path was the outlier
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 – Buggy code present?**
- Record: **Yes.** Local tree is **v6.18.44** (`VERSION=6`,
`PATCHLEVEL=18`, `SUBLEVEL=44`). `queue_command()` at lines 4383–4422
lacks the `HCD_HW_ACCESSIBLE` check. `xhci_suspend()` clears the flag
at lines 999–1001. Bug has existed since 2010-era suspend code.
**Step 6.2 – Backport complications**
- Record: Clean apply verified with `git apply --check`. No conflicting
local changes expected.
**Step 6.3 – Related fixes already present?**
- Record: No equivalent fix found in local tree. `git log
--grep="Prevent queuing new commands"` returns nothing. Fix is not yet
in this 6.18.y tree.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 – Subsystem criticality**
- Record: `drivers/usb/host/xhci` — **IMPORTANT/CORE-adjacent**. xHCI is
the standard USB3 host controller on virtually all modern PCs,
laptops, and servers.
**Step 7.2 – Subsystem activity**
- Record: Actively maintained; recent local history shows multiple xhci
suspend/resume and command-ring fixes.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 – Who is affected**
- Record: All systems using xHCI (Intel, AMD, and most ARM platforms
with xHCI). Config: `CONFIG_USB_XHCI_HCD`.
**Step 8.2 – Trigger conditions**
- Record:
- System suspend / bus suspend while commands are in flight
- Race between `xhci_setup_device()` / configure-endpoint paths and
`xhci_suspend()`
- Not easily triggered by unprivileged users directly, but common on
every laptop suspend
- Likelihood: moderate during suspend with active or completing USB
operations
**Step 8.3 – Failure mode severity**
- Record:
- Commands queued then lost when `xhci_clear_command_ring()` runs →
`wait_for_completion()` timeouts
- Doorbell `writel()` to inaccessible hardware → possible hang, failed
suspend, or “host not responding” behavior
- Severity: **HIGH** (suspend failure / hang), not merely cosmetic
**Step 8.4 – Risk vs benefit**
- Record:
- Benefit: **HIGH** — prevents command submission to inaccessible
hardware during suspend
- Risk: **LOW** — 10-line, pattern-consistent guard returning existing
error code
- Ratio: strongly favorable
---
## Phase 9: Final Synthesis
**Evidence FOR backport**
- Real inconsistency: URB path guarded, command path was not
- Suspend/resume is a critical stable use case
- Fix is tiny, obviously correct, and applies cleanly to v6.18.44
- Failure mode can cause suspend hangs/timeouts
- Author is xhci maintainer; USB maintainer acked
- Standalone; no series dependencies
- Same HW_ACCESSIBLE infrastructure present since 2010
**Evidence AGAINST backport**
- No explicit user report, CVE, or syzbot hit in commit message
- Part of a larger feature series (though this hunk is independent)
- Diagnostic warning does not itself fix pending-command cleanup
**Unresolved questions**
- No quantitative data on how often the suspend warning fires in the
field
- No independent Tested-by in the patch
**Stable rules checklist**
1. Obviously correct and tested? **PASS** — mirrors existing xhci
checks; maintainer-reviewed
2. Fixes a real bug affecting users? **PASS** — suspend/command race is
real and code-verified
3. Important issue? **PASS** — suspend hang/timeout, HIGH severity
4. Small and contained? **PASS** — 10 lines, 2 files
5. No new features or APIs? **PASS** — guard + warning only
6. Can apply to local tree? **PASS** — verified clean apply on v6.18.44
**Exception category:** N/A (not a device ID, quirk, DT, build, or docs-
only change)
---
## What Problem This Solves for Stable Users
During suspend, xhci marks hardware inaccessible via
`HCD_FLAG_HW_ACCESSIBLE` before stopping the controller and clearing the
command ring. Until this fix, the command-ring entry point did not honor
that flag, while URB submission already did. That gap allows commands to
be queued—and doorbells to be rung—against hardware being torn down,
which can leave callers waiting on completions that will never arrive
and can contribute to suspend failures. The fix aligns command
submission with the rest of the driver’s accessibility checks.
---
## Verification
- [Phase 1] Parsed commit message and tags from user-provided diff and
lore mbox
- [Phase 2] Read `queue_command()` at lines 4383–4422 in
`drivers/usb/host/xhci-ring.c`
- [Phase 2] Read `xhci_suspend()` at lines 961–1051 in
`drivers/usb/host/xhci.c`
- [Phase 2] Read `xhci_ring_cmd_db()` at lines 420–433 — confirmed
doorbell register access
- [Phase 2] Read `prepare_ring()` — software ring management; doorbell
is separate
- [Phase 3] `git describe HEAD` → `v6.18.44`
- [Phase 3] `git blame` on `xhci_suspend()` HW_ACCESSIBLE clear → 2010
commit `5535b1d5f88856`
- [Phase 3] `git blame` on `queue_command()` → core logic from
2009–2016, no HW_ACCESSIBLE check
- [Phase 3] `git log --grep="Prevent queuing new commands"` → not in
tree
- [Phase 4] `b4 mbox` fetched lore thread (21 messages) to
`/tmp/xhci_b4/`
- [Phase 4] Extracted patch 12/15 body and cover letter from mbox
- [Phase 4] No stable nomination or NAK found for patch 12/15
- [Phase 5] `grep HCD_HW_ACCESSIBLE drivers/usb/host/xhci*` → present in
`xhci.c` (lines 980, 1658) and `xhci-hub.c` (line 1894), absent from
`xhci-ring.c`
- [Phase 5] Traced `xhci_setup_device()` — uses `mutex_lock`, not
`spin_lock`; no HW_ACCESSIBLE check before
`xhci_queue_address_device()`
- [Phase 5] Traced `xhci_urb_enqueue()` — checks `HCD_HW_ACCESSIBLE`
under `xhci->lock`
- [Phase 6] Confirmed buggy code present in v6.18.44 checkout
- [Phase 6] `git apply --check` on reconstructed patch → **clean apply**
- [Phase 6] `git merge-base --is-ancestor b320937972d45 HEAD` →
HW_ACCESSIBLE suspend infrastructure present
- [Phase 8] Assessed failure mode from suspend path calling
`xhci_clear_command_ring()` with possible live `cmd_list` entries
**YES**
drivers/usb/host/xhci-ring.c | 6 ++++++
drivers/usb/host/xhci.c | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 859680bc74a2c..c48bcc6cc958a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -4386,6 +4386,7 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
u32 field3, u32 field4, bool command_must_succeed)
{
int reserved_trbs = xhci->cmd_ring_reserved_trbs;
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
int ret;
if ((xhci->xhc_state & XHCI_STATE_DYING) ||
@@ -4395,6 +4396,11 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
return -ESHUTDOWN;
}
+ if (!HCD_HW_ACCESSIBLE(hcd)) {
+ xhci_warn(xhci, "Can't queue command, xHC not accessible\n");
+ return -ESHUTDOWN;
+ }
+
if (!command_must_succeed)
reserved_trbs++;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 23b104c2956c7..9dc3ef8fcc67e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1002,6 +1002,10 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
/* step 1: stop endpoint */
/* skipped assuming that port suspend has done */
+ /* Check if command ring is empty */
+ if (!list_empty(&xhci->cmd_list))
+ xhci_warn(xhci, "Suspending and stopping xHC with pending command!\n");
+
/* step 2: clear Run/Stop bit */
command = readl(&xhci->op_regs->command);
command &= ~CMD_RUN;
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.6] thunderbolt: Don't access path config space on Lane 1 adapters in tb_switch_reset_host()
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18] usb: xhci: remove legacy 'num_trbs_free' tracking Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] xhci: Prevent queuing new commands if xhci is inaccessible Sasha Levin
@ 2026-08-31 13:22 ` Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep XDomain reference during the lifetime of a service Sasha Levin
` (19 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:22 UTC (permalink / raw)
To: patches, stable
Cc: Pooja Katiyar, Rene Sapiens, Mika Westerberg, Sasha Levin,
andreas.noever, westeri, YehezkelShB, linux-usb, linux-kernel
From: Pooja Katiyar <pooja.katiyar@intel.com>
[ Upstream commit 95c4379e37a0abea72dfd389cfe2c54452523690 ]
USB4 Lane 1 adapters do not have accessible path config space. Skip the
path config space cleanup in tb_switch_reset_host() for these ports. The
check is for USB4 switches only. Thunderbolt 1-3 Lane 1 adapters stay as
is because we do need to program their path config space.
Co-developed-by: Rene Sapiens <rene.sapiens@linux.intel.com>
Signed-off-by: Rene Sapiens <rene.sapiens@linux.intel.com>
Signed-off-by: Pooja Katiyar <pooja.katiyar@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `thunderbolt: Don't access path config space
on Lane 1 adapters in tb_switch_reset_host()`
**Local tree:** Linux **6.18.44** (`git describe HEAD` → `v6.18.44`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[thunderbolt]` `[prevent/avoid]` — Don't access path config
space on Lane 1 adapters in `tb_switch_reset_host()`.
### Step 1.2: Tags
**Record:**
- **Fixes:** — absent (expected for manual review)
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by:** — none
- **Acked-by:** — none
- **Link:** — none
- **Cc: stable:** — none
- **Signed-off-by:** Rene Sapiens, Pooja Katiyar, Mika Westerberg
(subsystem maintainer)
- **Co-developed-by:** Rene Sapiens
- Notable: no syzbot/fuzzer report; maintainer sign-off from Mika
Westerberg
### Step 1.3: Body analysis
**Record:**
- **Bug:** USB4 Lane 1 adapters have no accessible path config space,
but `tb_switch_reset_host()` tries to clean it up anyway.
- **Symptom:** Config-space reads/writes on Lane 1 fail (negative errno
from `tb_port_read()` / `tb_path_deactivate_hop()`), causing host
reset to fail.
- **Root cause:** Regression in the expanded reset path added by
`ec8162b3f0683` (v6.10); it did not exclude USB4 Lane 1 adapters,
unlike earlier init-time handling.
- **Version info:** USB4-only; TB1–3 Lane 1 adapters intentionally
unchanged.
### Step 1.4: Hidden bug fix?
**Record:** Yes — explicit bug fix. It completes the same Lane 1
exclusion already applied during port init (`2ad3e1314cafa`) for the
reset path introduced later.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **Files:** `drivers/thunderbolt/switch.c` (+6 lines)
- **Function:** `tb_switch_reset_host()`
- **Scope:** Single-file, surgical fix
### Step 2.2: Code flow change
**Record:**
- **Before:** After `tb_port_reset()` on a downstream lane (null)
adapter, always loop over hop IDs and call `tb_path_deactivate_hop()`.
- **After:** For USB4 switches, if `!port->usb4` (Lane 1 adapter — no
USB4 port capability/device), `continue` and skip path-config cleanup.
- **Path affected:** Host-router reset during `tb_switch_reset()` →
`tb_switch_reset_host()` for generation > 1 routers.
### Step 2.3: Bug mechanism
**Record:**
- **Category:** Logic / hardware-spec correctness fix (invalid config-
space access)
- **Mechanism:** `tb_path_deactivate_hop()` → `tb_port_read(port, ...,
TB_CFG_HOPS, ...)` on Lane 1 adapters where that space is not
implemented per USB4 spec. `tb_port_reset()` already skips USB4 Lane 1
(`!port->cap_usb4` → return 0 at line 691), but the subsequent cleanup
loop did not.
### Step 2.4: Fix quality
**Record:**
- Obviously correct: mirrors `2ad3e1314cafa` (`port->cap_usb4` at init)
and `tb_port_reset()` logic.
- `port->usb4` is only set on Lane 0 adapters with `cap_usb4`
(`usb4_switch_add_ports()`).
- TB1–3 unaffected because `tb_switch_is_usb4(sw)` is false.
- Low regression risk: 6 lines, no API/locking changes.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** Buggy reset loop introduced by **`ec8162b3f0683`** (Sanath
S, 2024-01-13), merged for **v6.10**. Present in this 6.18.44 tree.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag. Introducing commit verified:
`ec8162b3f0683` ("Make tb_switch_reset() support Thunderbolt 2, 3 and
USB4 routers") is an ancestor of HEAD.
### Step 3.3: Related file history
**Record:**
- **`2ad3e1314cafa`** (2022): "Do not touch lane 1 adapter path config
space" in `tb_init_port()` — **already in this tree**
- **`ec8162b3f0683`** (2024): Added path-config cleanup to reset —
**introduced the regression**
- **`95c4379e37a0a`** (2026): This fix — **NOT in this tree** (`git
merge-base --is-ancestor` confirms)
- Standalone fix, not part of a series
### Step 3.4: Author context
**Record:** Pooja Katiyar / Rene Sapiens (Intel); committed by Mika
Westerberg (Thunderbolt maintainer). Prior related fix by same
maintainer (Mika) in `2ad3e1314cafa`.
### Step 3.5: Dependencies
**Record:** No prerequisites. Uses `tb_switch_is_usb4()` and
`port->usb4`, both present in 6.18.44. `git show 95c4379e37a0a | git
apply --check` passes cleanly.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** `b4 dig -c 95c4379e37a0a` — **no match found** on lore
(patch may be too recent or not yet indexed). Manual lore search blocked
by bot protection.
### Step 4.2: Reviewers
**Record:** `b4 dig -w` also failed. Maintainer sign-off from Mika
Westerberg verified from commit metadata.
### Step 4.3: Bug report
**Record:** No external bug report, syzbot link, or user `Reported-by:`
tags.
### Step 4.4: Related patches
**Record:** Direct predecessor fix `2ad3e1314cafa` already in tree; this
commit closes the same gap in the reset path.
### Step 4.5: Stable list history
**Record:** UNVERIFIED — could not search lore stable archive due to
access restrictions.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `tb_switch_reset_host()`, `tb_path_deactivate_hop()`,
`tb_port_reset()`, `tb_switch_reset()`
### Step 5.2: Callers
**Record:** `tb_switch_reset()` called from `drivers/thunderbolt/tb.c`:
1. Line 3038: USB4 v1 root switch during domain init (`reset &&
tb_switch_is_usb4 && version == 1`)
2. Line 3127: Non-USB4 root switch on resume (`!tb_switch_is_usb4`)
USB4 bug path is (1). Resume path (2) uses non-USB4 hosts only.
### Step 5.3: Callees
**Record:** `tb_path_deactivate_hop()` →
`tb_port_read()`/`tb_port_write()` on `TB_CFG_HOPS` — fails on
inaccessible Lane 1 space.
### Step 5.4: Reachability
**Record:** Triggered during Thunderbolt/USB4 domain initialization on
USB4 v1 host routers with dual-lane downstream null adapters — real
hardware path, not theoretical.
### Step 5.5: Similar patterns
**Record:**
- `tb_init_port()`: `if (port->cap_usb4)` before reading hops
(post-`2ad3e1314cafa`)
- `tb_port_reset()`: `port->cap_usb4 ? usb4_port_reset(port) : 0` for
USB4
- `usb4_switch_add_ports()`: only sets `port->usb4` when
`port->cap_usb4` (Lane 0)
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code exists?
**Record:** **Yes.** `drivers/thunderbolt/switch.c` lines 1600–1623 in
6.18.44 lack the Lane 1 skip. Bug present since v6.10 (`ec8162b3f0683`).
### Step 6.2: Backport complications
**Record:** **Clean apply** — `git apply --check` succeeds with zero
conflicts.
### Step 6.3: Related fixes already present?
**Record:** `2ad3e1314cafa` (init-time Lane 1 exclusion) is in tree.
This reset-path gap is **not** yet fixed.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/thunderbolt/` — **IMPORTANT** (laptop/workstation
docking, USB4/Thunderbolt peripherals; not core kernel but widely used
on modern hardware).
### Step 7.2: Subsystem activity
**Record:** Actively maintained; recent stable-worthy fixes in same
subsystem (UAF, buffer bounds, property validation).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users with **USB4 v1 host routers** (dual-lane topology)
where `tb_switch_reset()` runs during domain init. Config-dependent on
`CONFIG_THUNDERBOLT`.
### Step 8.2: Trigger conditions
**Record:** Domain init with `reset=true` on USB4 v1 root switch. Not
every boot path (USB4 v2+ uses different reset), but reproducible on
affected hardware when that code path runs.
### Step 8.3: Failure severity
**Record:** `tb_switch_reset_host()` returns error; `tb_switch_reset()`
logs `"failed to reset"`. Early return leaves later ports unprocessed.
Init at line 3038 **ignores** the return value, but partial reset and
dmesg warnings remain. Severity: **MEDIUM-HIGH** (functional
Thunderbolt/USB4 reset failure on real hardware, not a security issue).
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** MEDIUM-HIGH for USB4 v1 users; fixes a regression in a
maintainer-owned code path
- **Risk:** VERY LOW — 6 lines, consistent with existing in-tree pattern
- **Ratio:** Strongly favors backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real bug: invalid config-space access on USB4 Lane 1 adapters
- Regression from `ec8162b3f0683`, present in 6.18.44
- Prior art in-tree (`2ad3e1314cafa`) establishes the correct behavior
- Small, surgical, applies cleanly
- Maintainer sign-off (Mika Westerberg)
- No new APIs or features
**AGAINST backport:**
- No user/syzbot report (impact inferred from code + spec)
- Caller ignores reset failure return value (mitigates crash risk but
not functional correctness)
- Affects a subset of USB4 v1 init paths, not all Thunderbolt users
**UNRESOLVED:**
- No lore discussion retrieved
- No explicit stable nomination found
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — matches existing Lane 1
handling; maintainer-reviewed
2. Fixes a real bug affecting users? **PASS** — invalid hardware access
on USB4 Lane 1 during reset
3. Important issue? **PASS** — functional reset failure on USB4 hardware
(MEDIUM-HIGH)
4. Small and contained? **PASS** — 6 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to local tree? **PASS** — verified clean apply
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build, or docs). Standard
bug fix.
### Step 9.4: Decision rationale
This is a regression fix for code introduced in v6.10 that is present in
Linux 6.18.44. The Thunderbolt maintainers already fixed the same USB4
Lane 1 path-config-space issue during port initialization
(`2ad3e1314cafa`); this commit applies the same principle to the reset
path added by `ec8162b3f0683`. The fix is minimal, obviously correct,
applies cleanly, and prevents erroneous config-space access that causes
host-router reset to fail on USB4 v1 hardware.
---
## Verification
- [Phase 1] Parsed commit message and tags from user-provided content
and `git show 95c4379e37a0a`
- [Phase 2] Read current `tb_switch_reset_host()` at lines 1584–1641 in
6.18.44; analyzed diff
- [Phase 3] `git blame -L 1600,1623`: buggy code from `ec8162b3f0683`
- [Phase 3] `git show ec8162b3f0683`: introduced expanded reset with
path-config cleanup (v6.10)
- [Phase 3] `git show 2ad3e1314cafa`: prior Lane 1 fix in
`tb_init_port()` using `port->cap_usb4`
- [Phase 3] `git merge-base --is-ancestor`: `2ad3e` and `ec8162` in
tree; `95c437` NOT in tree
- [Phase 3] `git tag --contains ec8162b3f0683`: first in v6.10
- [Phase 4] `b4 dig -c/-w/-a 95c4379e37a0a`: no lore match
- [Phase 4] lore.kernel.org fetch: blocked (bot protection) — stable
discussion UNVERIFIED
- [Phase 5] `grep tb_switch_reset`: callers at `tb.c:3038` and
`tb.c:3127`
- [Phase 5] Read `tb_port_reset()` at switch.c:688–692: Lane 1 already
skipped for reset, not for hop cleanup
- [Phase 5] Read `__tb_path_deactivate_hop()` at path.c:392–446:
accesses `TB_CFG_HOPS`
- [Phase 5] Read `usb4_switch_add_ports()` at usb4.c:1073–1097:
`port->usb4` only on `cap_usb4` ports
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] `git show 95c4379e37a0a | git apply --check`: applies
cleanly
- [Phase 6] Confirmed fix not present in current `switch.c` (no
`!port->usb4` check in `tb_switch_reset_host`)
- [Phase 8] Read `tb.c:3035–3038`: USB4 v1 reset during domain init;
return value not checked
**YES****Verdict: YES** — backport to this tree (Linux 6.18.44).
The fix is a 6-line change in `tb_switch_reset_host()` that skips path
config space cleanup on USB4 Lane 1 adapters, which don't expose that
space. Without it, the reset path added in v6.10 (`ec8162b3f0683`) can
fail on USB4 v1 hosts during domain init — the same class of issue
already handled at init time in `2ad3e1314cafa`. The patch applies
cleanly and is not yet in this tree.
drivers/thunderbolt/switch.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 0e07904aa73b4..a99d2db220802 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1601,6 +1601,12 @@ static int tb_switch_reset_host(struct tb_switch *sw)
ret = tb_port_reset(port);
if (ret)
return ret;
+ /*
+ * USB4 Lane 1 adapters do not have accessible
+ * path config space.
+ */
+ if (tb_switch_is_usb4(sw) && !port->usb4)
+ continue;
} else if (tb_port_is_usb3_down(port) ||
tb_port_is_usb3_up(port)) {
tb_usb3_port_enable(port, false);
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep XDomain reference during the lifetime of a service
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (2 preceding siblings ...)
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Don't access path config space on Lane 1 adapters in tb_switch_reset_host() Sasha Levin
@ 2026-08-31 13:23 ` Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: aspeed_udc: avoid past-the-end iterator in dequeue Sasha Levin
` (18 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:23 UTC (permalink / raw)
To: patches, stable
Cc: Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit 8b4060998637f06975fceee9b73845d8672d411e ]
This is needed because we release the service ID in tb_service_release()
and the ID array is owned by the parent XDomain.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
### Step 1.1: Parse the Subject Line
**Record:** `[thunderbolt]` `[keep]` — Keep an XDomain reference for the
full lifetime of a Thunderbolt service device.
### Step 1.2: Parse All Commit Message Tags
**Record:**
- **Fixes:** — absent (expected for manual review)
- **Reported-by:** — absent
- **Tested-by:** — absent
- **Reviewed-by:** — absent
- **Acked-by:** — absent
- **Link:** — absent
- **Cc: stable@vger.kernel.org** — absent (not a negative signal)
- **Signed-off-by:** Mika Westerberg \<mika.westerberg@linux.intel.com\>
(subsystem maintainer)
No syzbot, no multi-reporter tags. Author is the Thunderbolt maintainer.
### Step 1.3: Analyze Commit Body
**Record:**
- **Bug:** `tb_service_release()` calls `ida_free(&xd->service_ids,
...)`, but `service_ids` is owned by the parent XDomain. The XDomain
can be freed before the service’s final `release` callback runs.
- **Symptom:** Use-after-free when freeing the service ID during service
teardown (potential crash / memory corruption).
- **Version info:** Not stated in the commit message.
- **Root cause (author):** Missing explicit XDomain reference for the
service’s lifetime.
### Step 1.4: Detect Hidden Bug Fixes
**Record:** Not disguised — this is an explicit lifetime/reference-
counting bug fix, not cleanup or optimization.
---
## Phase 2: Diff Analysis
### Step 2.1: Inventory the Changes
**Record:**
- **File:** `drivers/thunderbolt/xdomain.c` (+2 lines net)
- **Functions modified:** `tb_service_release()`, `enumerate_services()`
- **Scope:** Single-file, surgical fix (2 meaningful lines)
### Step 2.2: Code Flow Change (per hunk)
**Hunk 1 — `tb_service_release()`:**
- **Before:** Frees service ID from parent XDomain’s IDA, frees service
memory; no XDomain refcount drop.
- **After:** Same, then calls `tb_xdomain_put(xd)` to release the
reference taken at enumeration.
- **Path:** Service device final release callback (after last
`put_device()` on the service).
**Hunk 2 — `enumerate_services()`:**
- **Before:** `svc->dev.parent = &xd->dev` (bare pointer, no refcount).
- **After:** `svc->dev.parent = get_device(&xd->dev)` (holds XDomain
alive).
- **Path:** XDomain service enumeration during property exchange /
reconnect.
### Step 2.3: Bug Mechanism
**Record:** **Reference counting / use-after-free fix.**
Mechanism verified against the driver core:
1. `enumerate_services()` registers child service devices parented under
the XDomain.
2. `tb_service_release()` accesses `xd->service_ids` via `ida_free()`.
3. `tb_xdomain_release()` destroys that IDA with
`ida_destroy(&xd->service_ids)`.
4. On `device_unregister(service)`, `device_del()` immediately calls
`put_device(parent)` (see `drivers/base/core.c:3983`), dropping the
parent reference acquired in `device_add()` — even if the service
device struct still exists because something holds an extra
reference.
5. `tb_xdomain_remove()` unregisters all services, then unregisters the
XDomain; the XDomain can reach refcount zero and run
`tb_xdomain_release()` while a service device is still pending final
release.
6. When `tb_service_release()` finally runs, `xd` and `xd->service_ids`
may already be freed → UAF.
The fix holds an independent XDomain reference from enumeration until
`tb_service_release()`.
### Step 2.4: Fix Quality Assessment
**Record:**
- **Quality:** Obviously correct; standard `get_device()` /
`put_device()` pairing via `tb_xdomain_put()`.
- **Scope:** Minimal; no API changes.
- **Regression risk:** Very low. Refcount is balanced: one
`get_device()` at parent assignment, one `tb_xdomain_put()` at service
release. `device_add()`/`device_del()` continue to manage their own
parent reference separately.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame the Changed Lines
**Record:** `git blame` attributes current `tb_service_release()` /
`enumerate_services()` code to commit `19eef1d98eeda` in this tree
(stable history is squashed; that commit message is unrelated). The
service/XDomain code is present and has the buggy pattern. Approximate
introduction: with the XDomain service enumeration infrastructure
(present in this 6.18.y tree).
### Step 3.2: Follow the Fixes: Tag
**Record:** No `Fixes:` tag present — step not applicable.
### Step 3.3: File History for Related Changes
**Record:** Recent thunderbolt commits in this tree include XDomain
security hardening (`b5daa920f44cb`, `46da5c3ea011e`, `fcbd0cdab9283`,
etc.). This fix is **standalone** (2 lines, no structural
prerequisites). Related stable series patches (debugfs unregister,
delayed-work UAF) are separate; this commit does not depend on them.
### Step 3.4: Author's Other Commits
**Record:** Mika Westerberg is the Thunderbolt subsystem maintainer. No
other commits by this author found in this tree’s `drivers/thunderbolt/`
log (history is compressed).
### Step 3.5: Prerequisite Commits
**Record:** No dependencies. `tb_xdomain_get()`/`tb_xdomain_put()`,
`tb_service_parent()`, `enumerate_services()`, and
`ida_alloc`/`ida_free` on `xd->service_ids` all exist in this tree.
Patch applies to current `xdomain.c` with only the two line changes
(candidate diff uses `kzalloc_obj`; local tree uses `kzalloc` —
unrelated context, no conflict).
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Patch Discussion
**Record:** `b4 dig` could not be run — commit hash is not in this
checkout. lore.kernel.org returned 403 (bot protection). **Ratatoskr
stable-queue archives** show this exact patch nominated for multiple
stable trees:
- `[PATCH 5.10.y 1/3] thunderbolt: Keep XDomain reference during the
lifetime of a service`
- `[PATCH 5.15.y 3/6] ...`
- `[PATCH 6.6.y 4/7] ...`
Part of a broader Thunderbolt XDomain stability series (`Stable-dep-of:
2c5d2d3c3f70` on related patches).
### Step 4.2: Reviewers
**Record:** UNVERIFIED — could not fetch lore thread or run `b4 dig -w`.
Author is subsystem maintainer.
### Step 4.3: Bug Report
**Record:** No external bug report referenced. Bug identified by code
analysis / disconnect teardown path.
### Step 4.4: Related Patches / Series
**Record:** Related stable patches in the same series (debugfs
unregister, remove without holding `tb->lock`, delayed-work UAF) are
complementary but **this commit is independently correct and
applicable**. Greg’s Linux 6.18.44 announcement (2026-08-09 per
Ratatoskr) suggests the broader series is heading into 6.18.y.
### Step 4.5: Stable Mailing List History
**Record:** Stable nominations confirmed via Ratatoskr for 5.10.y,
5.15.y, 6.6.y at minimum. Direct lore stable-list search UNVERIFIED
(403).
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** `tb_service_release()`, `enumerate_services()`,
`tb_xdomain_remove()`, `tb_xdomain_release()`, `tb_service_parent()`.
### Step 5.2: Trace Callers
**Record:**
- `enumerate_services(xd)` — called from XDomain property update path
(line 1497).
- `tb_service_release()` — device core release callback for
`tb_service_type`.
- `tb_xdomain_remove()` — called on XDomain disconnect; unregisters all
child services then the XDomain.
Callers of `tb_xdomain_remove()` include ICM and core Thunderbolt
disconnect paths — common during cable unplug / peer host disconnect.
### Step 5.3: Trace Callees
**Record:** `ida_free()`, `ida_destroy()`, `get_device()`,
`tb_xdomain_put()` (wraps `put_device()`), `device_register()`,
`device_unregister()`.
### Step 5.4: Call Chain / Reachability
**Record:**
```
Thunderbolt disconnect / XDomain removal
→ tb_xdomain_remove()
→ device_for_each_child_reverse(..., unregister_service)
→ device_unregister(service) [parent ref dropped in device_del]
→ device_unregister(xd)
→ tb_xdomain_release() [ida_destroy(&xd->service_ids)]
→ (later) tb_service_release() [ida_free on possibly freed xd] ← BUG
```
**Userspace-reachable:** Yes — triggered by Thunderbolt hot-unplug /
peer disconnect while a service device has lingering references (driver
binding, `get_device()` holders, etc.). Not theoretical.
### Step 5.5: Similar Patterns
**Record:** XDomain itself correctly uses `get_device(parent)` at
allocation (`xdomain.c:2016`). Services were the missing symmetric case.
`tb_service_get()`/`tb_service_put()` exist for service devices but did
not protect the parent XDomain.
---
## Phase 6: Cross-Referencing Against the Local Tree
### Step 6.1: Does the Buggy Code Exist?
**Record:** **YES.** Local tree is **6.18.43** (`git describe HEAD` →
`v6.18.43-1-gc7f0dac02d232`, `make kernelversion` → `6.18.43`).
Current buggy code verified:
```1006:1015:drivers/thunderbolt/xdomain.c
static void tb_service_release(struct device *dev)
{
struct tb_service *svc = container_of(dev, struct tb_service,
dev);
struct tb_xdomain *xd = tb_service_parent(svc);
tb_service_debugfs_remove(svc);
ida_free(&xd->service_ids, svc->id);
kfree(svc->key);
kfree(svc);
}
```
```1120:1124:drivers/thunderbolt/xdomain.c
svc->id = id;
svc->dev.bus = &tb_bus_type;
svc->dev.type = &tb_service_type;
svc->dev.parent = &xd->dev;
dev_set_name(&svc->dev, "%s.%d", dev_name(&xd->dev),
svc->id);
```
No `get_device(&xd->dev)` on parent assignment; no `tb_xdomain_put(xd)`
in release. Fix is **not** already present (`git log --grep` and `git
log -S "svc->dev.parent = get_device"` returned nothing).
### Step 6.2: Backport Complications
**Record:** **Clean apply expected** — 2 lines in one file, matching
current code structure. No refactor conflicts in the target hunks.
### Step 6.3: Related Fixes Already Present?
**Record:** No — grep and git searches found no prior application of
this fix or equivalent `tb_xdomain_put` in `tb_service_release`.
---
## Phase 7: Subsystem and Maintainer Context
### Step 7.1: Subsystem and Criticality
**Record:** `drivers/thunderbolt/` — **IMPORTANT** (Thunderbolt/USB4
XDomain networking and device interconnection; not core kernel, but
affects real hardware on laptops/workstations).
### Step 7.2: Subsystem Activity
**Record:** Actively maintained in this tree — multiple recent XDomain
security/stability fixes (packet validation, bounds checking, property
parsing).
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users with `CONFIG_THUNDERBOLT` and active XDomain
connections (Thunderbolt networking, cross-host services). Driver-
specific but affects a widely deployed laptop/workstation feature.
### Step 8.2: Trigger Conditions
**Record:** XDomain removal/disconnect while a service child device
still has refcount > 1 after `device_unregister()`. Realistic during
hot-unplug, peer shutdown, or driver teardown races. Unprivileged users
can trigger disconnect by unplugging cable.
### Step 8.3: Failure Mode Severity
**Record:** **Use-after-free** on `xd->service_ids` during `ida_free()`
→ kernel oops / memory corruption. **Severity: HIGH to CRITICAL.**
### Step 8.4: Risk-Benefit Ratio
**Record:**
- **Benefit:** HIGH — prevents UAF crash on a real disconnect path.
- **Risk:** VERY LOW — 2-line refcount fix, maintainer-authored, already
queued for multiple stable trees.
- **Ratio:** Strongly favors backport.
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Compiled
**FOR backport:**
- Real UAF on XDomain disconnect teardown path (verified via code +
driver-core semantics).
- Buggy code confirmed present in 6.18.43.
- Minimal, obviously correct fix (2 lines).
- Thunderbolt maintainer authorship.
- Already nominated for stable on 5.10.y, 5.15.y, 6.6.y (Ratatoskr).
- Standalone — no prerequisite commits required.
- Part of broader XDomain stability effort heading into 6.18.y.
**AGAINST backport:**
- Config-specific (`CONFIG_THUNDERBOLT`) — affects subset of users, not
all kernels.
- No syzbot/user crash report attached (but mechanism is clear from
code).
**UNRESOLVED:**
- Full lore review thread (403 blocked).
- Exact upstream commit SHA (not in this checkout).
Neither unresolved item weakens the technical case.
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — standard refcount pattern;
maintainer-authored; stable-queue nominations imply review.
2. Fixes a real bug affecting users? **PASS** — UAF on Thunderbolt
XDomain disconnect.
3. Important issue? **PASS** — UAF / potential crash (HIGH-CRITICAL).
4. Small and contained? **PASS** — 2 lines, one file.
5. No new features or APIs? **PASS** — refcount fix only.
6. Can apply to local tree? **PASS** — code exists; clean 2-line apply.
### Step 9.3: Exception Categories
**Record:** Not applicable (not a device ID, quirk, DT, build, or docs
fix — standard bug fix).
### Step 9.4: Decision Rationale
This commit fixes a genuine use-after-free: `tb_service_release()`
accesses the parent XDomain’s `service_ids` IDA after the XDomain may
already have been destroyed during disconnect teardown, because
`device_del()` drops the parent reference at unregister time rather than
at final service release. The fix is minimal, self-contained, and the
buggy code is present in this 6.18.43 tree. Stable maintainers have
already nominated it for multiple older stable branches.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body; no Fixes/Reported-by/Link
tags; author is Mika Westerberg.
- **[Phase 2]** Read full diff; confirmed 2-line refcount fix in
`tb_service_release()` and `enumerate_services()`.
- **[Phase 3]** `git blame` on xdomain.c service code; `git log -S`
searches; no fix already in tree.
- **[Phase 4]** lore.kernel.org: 403 Forbidden. Ratatoskr: stable
nominations found for 5.10.y/5.15.y/6.6.y. `b4 dig`: not run (no
commit hash in tree).
- **[Phase 5]** Traced call chain through `tb_xdomain_remove()` →
`device_unregister()` → `tb_xdomain_release()` vs deferred
`tb_service_release()`.
- **[Phase 5]** Verified `device_del()` calls `put_device(parent)` at
`drivers/base/core.c:3983`.
- **[Phase 5]** Verified `tb_xdomain_release()` calls
`ida_destroy(&xd->service_ids)` at `xdomain.c:1883`.
- **[Phase 6]** `git describe HEAD` → v6.18.43; `make kernelversion` →
6.18.43.
- **[Phase 6]** Read current `xdomain.c` — buggy pattern confirmed, fix
absent.
- **[Phase 6]** Verified `tb_xdomain_get`/`tb_xdomain_put` exist in
`include/linux/thunderbolt.h:325-336`.
- **[Phase 7]** Thunderbolt subsystem active with recent XDomain fixes
in this tree.
- **[Phase 8]** Assessed UAF severity as HIGH-CRITICAL on disconnect
path.
**YES**The analysis is done for **6.18.43**.
**Verdict: YES** — backport this commit.
It fixes a real use-after-free: when an XDomain disconnects,
`tb_service_release()` can call `ida_free()` on the parent XDomain’s
`service_ids` after that XDomain has already been torn down. The fix is
small (two lines: `get_device()` on parent assignment,
`tb_xdomain_put()` in release), applies cleanly here, and the buggy code
is present in this tree.
drivers/thunderbolt/xdomain.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index 5fbdd412a712f..fed0fae2a6299 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -1029,6 +1029,7 @@ static void tb_service_release(struct device *dev)
ida_free(&xd->service_ids, svc->id);
kfree(svc->key);
kfree(svc);
+ tb_xdomain_put(xd);
}
const struct device_type tb_service_type = {
@@ -1137,7 +1138,7 @@ static void enumerate_services(struct tb_xdomain *xd)
svc->id = id;
svc->dev.bus = &tb_bus_type;
svc->dev.type = &tb_service_type;
- svc->dev.parent = &xd->dev;
+ svc->dev.parent = get_device(&xd->dev);
dev_set_name(&svc->dev, "%s.%d", dev_name(&xd->dev), svc->id);
tb_service_debugfs_init(svc);
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.1] usb: gadget: aspeed_udc: avoid past-the-end iterator in dequeue
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (3 preceding siblings ...)
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep XDomain reference during the lifetime of a service Sasha Levin
@ 2026-08-31 13:23 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: udc: skip pullup() if already connected Sasha Levin
` (17 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:23 UTC (permalink / raw)
To: patches, stable
Cc: Maoyi Xie, Alan Stern, Andrew Jeffery, Greg Kroah-Hartman,
Sasha Levin, neal_liu, joel, linux-aspeed, linux-usb,
linux-arm-kernel, linux-kernel
From: Maoyi Xie <maoyixie.tju@gmail.com>
[ Upstream commit e2ffaac1884b921b8ec2b3a964c6a8b5d610bf4b ]
ast_udc_ep_dequeue() declares the loop cursor `req` outside the
list_for_each_entry(). After the loop it tests `&req->req != _req`
to decide whether the request was found. If the queue holds no
match, `req` is past-the-end. It then aliases
container_of(&ep->queue, struct ast_udc_request, queue) via offset
cancellation. Whether that synthetic address equals `_req` depends
on heap layout. The function can return 0 without dequeueing
anything.
Default `rc` to -EINVAL and set it to 0 only inside the match
branch. `req` is no longer read after the loop, so the past-the-end
dereference goes away. No extra cursor variable or post-loop test
is needed.
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Suggested-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://patch.msgid.link/20260521065428.3261238-1-maoyixie.tju@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `usb: gadget: aspeed_udc: avoid past-the-end
iterator in dequeue`
**Local tree:** `v6.18.44` (`stable/linux-6.18.y`, detached HEAD)
**Fix commit on master:** `e2ffaac1884b9` (not present in this tree)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[usb: gadget: aspeed_udc]` **`avoid`** — fix incorrect
post-loop use of a `list_for_each_entry()` cursor in
`ast_udc_ep_dequeue()`.
### Step 1.2: Tags
**Record:**
- **Suggested-by:** Alan Stern `<stern@rowland.harvard.edu>` (USB
maintainer)
- **Suggested-by:** Andrew Jeffery `<andrew@codeconstruct.com.au>`
(Aspeed contributor)
- **Signed-off-by:** Maoyi Xie, Greg Kroah-Hartman
- **Link:** https://patch.msgid.link/20260521065428.3261238-1-
maoyixie.tju@gmail.com
- No `Fixes:`, `Reported-by:`, `Cc: stable`, `Reviewed-by:`, or `Tested-
by:` tags
- Notable: suggestions from core USB and Aspeed reviewers; patch went
through v1→v3 on list
### Step 1.3: Body analysis
**Record:**
- **Bug:** After `list_for_each_entry()` finds no match, `req` is a
past-the-end sentinel. Post-loop `&req->req != _req` uses that invalid
cursor via `container_of()` offset arithmetic.
- **Symptom:** `ast_udc_ep_dequeue()` can return `0` (success) without
dequeuing anything.
- **Root cause:** `rc` defaults to `0`; the post-loop pointer comparison
is unreliable when the iterator is past-the-end.
- **Version info:** None explicit; driver has been in-tree since 5.19.
### Step 1.4: Hidden bug fix?
**Record:** Yes — clearly a logic/correctness bug in the USB gadget
dequeue API, not cosmetic cleanup. Matches the established idiom in
sibling `aspeed-vhub` and `pch_udc` drivers.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/usb/gadget/udc/aspeed_udc.c` (+2 / −5 lines)
- **Function:** `ast_udc_ep_dequeue()`
- **Scope:** Single-file, surgical fix
### Step 2.2: Code flow change
**Record:**
- **Before:** `rc = 0`; on match, dequeue and `break`; after loop, if
`&req->req != _req` then `rc = -EINVAL` (reads past-the-end `req`).
- **After:** `rc = -EINVAL`; on match, dequeue, set `rc = 0`, `break`;
no post-loop read of `req`.
- **Path affected:** Error/normal dequeue path when the requested
`usb_request` is not on the endpoint queue.
### Step 2.3: Bug mechanism
**Record:** **Category (g) logic/correctness fix** — violates
`usb_ep_dequeue()` contract (must return negative error if request is
not active on endpoint). The post-loop test uses an invalid list
iterator, producing unreliable success/failure results.
### Step 2.4: Fix quality
**Record:** Obviously correct; matches `pch_udc_pcd_dequeue()` and
`ast_vhub_epn_dequeue()` patterns. Minimal regression risk — only
changes return value for the not-found path to the correct `-EINVAL`.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** Buggy code introduced in `055276c132056` (“usb: gadget: add
Aspeed ast2600 udc driver”, May 2022, landed in 5.19). Present unchanged
in this tree at lines 697–713.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag. Introducing commit is
`055276c132056`, confirmed ancestor of HEAD.
### Step 3.3: Related file history
**Record:** Recent `aspeed_udc.c` changes are other small fixes
(endpoint validation, DMA, spinlock). No duplicate fix for this issue.
Standalone one-patch fix (v3 is final applied form).
### Step 3.4: Author context
**Record:** Maoyi Xie is not the driver author (Neal Liu) but submitted
a focused fix with guidance from Alan Stern and Andrew Jeffery. Greg K-H
committed to mainline.
### Step 3.5: Dependencies
**Record:** None. Self-contained; no prerequisite commits. Applies
cleanly to current `6.18.y` file.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** `b4 dig -c e2ffaac1884b9` → [PATCH v3] thread at https://pat
ch.msgid.link/20260521065428.3261238-1-maoyixie.tju@gmail.com. Series:
v2 (2026-05-19), v3 (2026-05-21, applied version). Alan Stern reviewed
v1 and suggested the correct loop/return-value idiom; Andrew Jeffery
suggested v3’s `rc = -EINVAL` default shape.
### Step 4.2: Reviewers
**Record:** `b4 dig -w`: CC’d Greg Kroah-Hartman, Alan Stern, Andrew
Jeffery, Neal Liu, linux-usb, linux-aspeed, linux-arm-kernel.
Appropriate maintainer coverage.
### Step 4.3: Bug report
**Record:** No syzbot/bugzilla report. Bug identified via code review
(Alan Stern). Severity: API contract violation with potential request-
lifecycle confusion.
### Step 4.4: Series context
**Record:** Standalone fix; v3 is the committed version. No other
patches required.
### Step 4.5: Stable list history
**Record:** No `Cc: stable` nominations found in thread (`grep -i
stable` on saved mbox). Not a negative signal per instructions.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `ast_udc_ep_dequeue()` modified; registered in
`ast_udc_ep_ops.dequeue`.
### Step 5.2: Callers
**Record:** Called via `usb_ep_dequeue()` in
`drivers/usb/gadget/udc/core.c`, which dispatches to `ep->ops->dequeue`.
Gadget function drivers call this from disconnect/cancel paths:
`composite.c`, `f_fs.c`, `u_audio.c`, `f_mass_storage.c`, `f_ecm.c`,
`u_serial.c`, `raw_gadget.c`, etc. Callable from process or interrupt
context per `core.c` documentation.
### Step 5.3: Callees
**Record:** On successful match: `list_del_init()`, `ast_udc_done()`
(unmap + completion callback). Fix only changes behavior when no match
is found.
### Step 5.4: Reachability
**Record:** Reachable whenever a USB gadget function cancels an in-
flight request on an Aspeed UDC endpoint — common during teardown, error
recovery, or userspace interrupt (e.g. FunctionFS). Requires
`CONFIG_USB_ASPEED_UDC` on `ARCH_ASPEED` (AST260x BMC SoCs).
### Step 5.5: Similar patterns
**Record:** `aspeed-vhub` `ast_vhub_epn_dequeue()` already uses `rc =
-EINVAL` + separate iterator (`epn.c:472–488`). `pch_udc_pcd_dequeue()`
uses same pattern (`pch_udc.c:1862–1878`). `aspeed_udc` was the outlier.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code exists?
**Record:** **Yes.** Current tree at
`drivers/usb/gadget/udc/aspeed_udc.c:697–713` has `int rc = 0` and post-
loop `if (&req->req != _req)`. Fix commit `e2ffaac1884b9` is **not** an
ancestor of HEAD (`merge-base` check failed).
### Step 6.2: Backport complications
**Record:** Clean apply expected — 7-line hunk, no structural conflicts.
File has had only minor unrelated changes since driver addition.
### Step 6.3: Related fixes already present?
**Record:** None found for this issue.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** **drivers/usb/gadget** — IMPORTANT for Aspeed BMC/embedded
platforms using USB gadget mode; peripheral globally but significant for
OpenBMC/AST260x deployments.
### Step 7.2: Subsystem activity
**Record:** Driver actively maintained with several post-introduction
fixes in this tree (DMA, spinlock, endpoint validation). Bug predates
all of them.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users of AST260x SoCs with `CONFIG_USB_ASPEED_UDC` running
USB gadget functions (mass storage, ECM, UAC, FunctionFS, etc.).
### Step 8.2: Trigger conditions
**Record:** `usb_ep_dequeue()` called with a `usb_request` not currently
queued on that endpoint — happens during disconnect, I/O cancellation,
or race between completion and cancel. Not every boot, but a normal
operational path. Unprivileged users can trigger via gadget
configfs/functionfs on systems exposing gadget to userspace.
### Step 8.3: Failure mode severity
**Record:** False success (`0` returned, nothing dequeued) → callers
assume request canceled. Example in `u_audio.c:455–463`: on success,
request is not freed but pointer is cleared; completion may still fire
later → request lifecycle confusion, potential use-after-free or double-
free depending on caller. **Severity: HIGH** (correctness bug with
memory-safety consequences possible); not a guaranteed crash on every
call.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH for affected hardware — restores correct
`usb_ep_dequeue()` semantics
- **Risk:** VERY LOW — 5-line idiom change, well-reviewed, matches
sibling drivers
- **Ratio:** Strongly favors backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real bug present since driver introduction (2022)
- Buggy code confirmed in `v6.18.44`
- Can return false success on dequeue failure — API contract violation
- USB maintainers (Alan Stern) and Aspeed developers guided the fix
- Tiny, surgical, obviously correct change
- Sibling `aspeed-vhub` already uses correct pattern
- Gadget callers depend on accurate dequeue return values
**AGAINST backport:**
- Limited to `CONFIG_USB_ASPEED_UDC` platforms (not universal)
- No syzbot/CVE report; false-success case may be uncommon in practice
- No explicit stable nomination in mailing list
**Unresolved:** Exact frequency of spurious success in production
(address-coincidence scenario); not needed to justify fix given clear
API bug.
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — standard UDC idiom; reviewed
by Alan Stern and Andrew Jeffery; committed by Greg K-H
2. Fixes a real bug affecting users? **PASS** — incorrect dequeue return
value on Aspeed UDC
3. Important issue? **PASS** — request lifecycle / potential UAF;
severity HIGH for affected configs
4. Small and contained? **PASS** — 1 file, net −3 lines
5. No new features or APIs? **PASS**
6. Can apply to local tree? **PASS** — driver and buggy code both
present; clean apply
### Step 9.3: Exception categories
**Record:** N/A (not device ID, quirk, DT, build, or docs — standard
driver bug fix).
### Step 9.4: Decision rationale
This tree (`6.18.y`) ships the Aspeed UDC driver with a dequeue bug that
has existed since the driver was added. The fix restores correct
`usb_ep_dequeue()` behavior using the same pattern as other UDC drivers
in-tree. It is small, reviewed by USB subsystem experts, and prevents
callers from mis-handling requests that were never dequeued. The
hardware scope is narrow but the fix is trivial and the failure mode is
serious enough for stable.
---
## Verification
- **[Phase 1]** Parsed commit message and tags from user query and `git
show e2ffaac1884b9`
- **[Phase 2]** Read diff; confirmed changes in `ast_udc_ep_dequeue()`
at lines 691–716
- **[Phase 3]** `git blame`: buggy code from `055276c132056` (May 2022,
5.19)
- **[Phase 3]** `git merge-base --is-ancestor 055276c132056 HEAD`:
driver present in tree
- **[Phase 3]** `git merge-base --is-ancestor e2ffaac1884b9 HEAD`: fix
**not** in tree (exit 1)
- **[Phase 3]** `git log --oneline -20 --
drivers/usb/gadget/udc/aspeed_udc.c`: no duplicate fix
- **[Phase 4]** `b4 dig -c e2ffaac1884b9`: found v3 thread URL
- **[Phase 4]** `b4 dig -a`: v2 and v3 revisions listed
- **[Phase 4]** `b4 dig -w`: Greg K-H, Alan Stern, Andrew Jeffery CC'd
- **[Phase 4]** Saved mbox; read Alan Stern review suggesting correct
idiom
- **[Phase 4]** `grep -i stable` on mbox: no stable nomination
- **[Phase 5]** `grep usb_ep_dequeue`: multiple gadget function driver
call sites
- **[Phase 5]** Read `core.c:331–338`: dispatch wrapper
- **[Phase 5]** Read `aspeed-vhub/epn.c:472–488`: correct sibling
pattern
- **[Phase 5]** Read `pch_udc.c:1862–1878`: correct peer pattern
- **[Phase 5]** Read `u_audio.c:455–463`: caller behavior on dequeue
return value
- **[Phase 6]** `git describe HEAD`: `v6.18.44`
- **[Phase 6]** `make -s kernelversion`: `6.18.44`
- **[Phase 6]** Confirmed buggy code at `aspeed_udc.c:697–713` in
working tree
- **[Phase 6]** `git log master --oneline --grep past-the-end`: fix
exists on master only
- **[Phase 7]** Read `Kconfig:407–418`: `CONFIG_USB_ASPEED_UDC` depends
on `ARCH_ASPEED`
**YES**The commit should be backported to this tree (`v6.18.44` /
`stable/linux-6.18.y`).
`ast_udc_ep_dequeue()` in `aspeed_udc.c` can return success without
actually dequeuing a request when the target isn’t on the endpoint
queue, because it reads a past-the-end `list_for_each_entry()` cursor
after the loop. The fix is small (default `rc` to `-EINVAL`, set `0`
only on match) and matches the pattern already used in `aspeed-vhub` and
`pch_udc`.
The buggy code is present here; the fix (`e2ffaac1884b9`) is on master
but not in this stable branch. It affects AST260x BMC systems using
`CONFIG_USB_ASPEED_UDC` and can confuse gadget callers that rely on
`usb_ep_dequeue()` return values during cancel/teardown.
**YES**
drivers/usb/gadget/udc/aspeed_udc.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c
index 353bfb1ff0a12..0b994afab0478 100644
--- a/drivers/usb/gadget/udc/aspeed_udc.c
+++ b/drivers/usb/gadget/udc/aspeed_udc.c
@@ -694,7 +694,7 @@ static int ast_udc_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
struct ast_udc_dev *udc = ep->udc;
struct ast_udc_request *req;
unsigned long flags;
- int rc = 0;
+ int rc = -EINVAL;
spin_lock_irqsave(&udc->lock, flags);
@@ -704,14 +704,11 @@ static int ast_udc_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
list_del_init(&req->queue);
ast_udc_done(ep, req, -ESHUTDOWN);
_req->status = -ECONNRESET;
+ rc = 0;
break;
}
}
- /* dequeue request not found */
- if (&req->req != _req)
- rc = -EINVAL;
-
spin_unlock_irqrestore(&udc->lock, flags);
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.1] usb: gadget: udc: skip pullup() if already connected
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (4 preceding siblings ...)
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: aspeed_udc: avoid past-the-end iterator in dequeue Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.10] usb: core: hcd: fix possible deadlock in rh control transfers Sasha Levin
` (16 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Xu Yang, Alan Stern, Greg Kroah-Hartman, Sasha Levin, linux-usb,
linux-kernel
From: Xu Yang <xu.yang_2@nxp.com>
[ Upstream commit 62911bc82b0332aee7546156800d3516500fa1e1 ]
The device controller may update vbus status via usb_udc_vbus_handler(),
which tries to connect the gadget even though gadget_bind_driver() has
already called usb_udc_connect_control_locked(). This causes pullup() to
be called twice. Avoid this by checking if gadget->connected is true.
This also set gadget->connected as false in usb_gadget_activate() if it
became connected while it was being deactivated. Otherwise,
usb_gadget_connect_locked will return early and pullup() won't be called.
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260423095355.2673035-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background `git log -S` search finished. In this **v6.18.43**
checkout the history is flattened, so pickaxe only points at
`19eef1d98eeda` for `vbus_work` in `core.c` — it doesn’t show when that
logic was really introduced. That matches what we already inferred from
mainline: the dual connect path dates to the 2023 `usb_udc_vbus_handler`
workqueue offload.
That doesn’t change the backport call: the buggy code is present in this
tree, the fix is small and applies cleanly, and the verdict remains
**YES**.
drivers/usb/gadget/udc/core.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index ab1bcc5512b2c..fa49746d54036 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -714,6 +714,9 @@ static int usb_gadget_connect_locked(struct usb_gadget *gadget)
goto out;
}
+ if (gadget->connected)
+ goto out;
+
if (gadget->deactivated || !gadget->udc->allow_connect || !gadget->udc->started) {
/*
* If the gadget isn't usable (because it is deactivated,
@@ -887,8 +890,10 @@ int usb_gadget_activate(struct usb_gadget *gadget)
* If gadget has been connected before deactivation, or became connected
* while it was being deactivated, we call usb_gadget_connect().
*/
- if (gadget->connected)
+ if (gadget->connected) {
+ gadget->connected = false;
ret = usb_gadget_connect_locked(gadget);
+ }
unlock:
mutex_unlock(&gadget->udc->connect_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] usb: core: hcd: fix possible deadlock in rh control transfers
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (5 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: udc: skip pullup() if already connected Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] usb: xhci: Improve Soft Retries after short transfers Sasha Levin
` (15 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Oliver Neukum, Greg Kroah-Hartman, Sasha Levin, linux-usb,
linux-kernel
From: Oliver Neukum <oneukum@suse.com>
[ Upstream commit d5559f43d76b398392b26a15cbc16d731969cd1c ]
>From within the SCSI error handler memory allocations must not
trigger IO. Handling errors in UAS and the storage driver may
involve resetting a device. The thread doing the reset itself
relies on VM magic. However, that is insufficient, as resetting
a device involves resuming it. Resumption as well as resetting
involves conrol transfers to the parent of the device to be reset.
That may be a root hub. Hence usbcore must heed the flags passed
to usb_submit_urb() processing control transfers to root hubs.
The problem exist since the storage driver has been merged.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://patch.msgid.link/20260429094413.181038-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
### Step 1.1: PARSE THE SUBJECT LINE
**Record:** `[usb: core: hcd]` `[fix]` — fix possible deadlock in root-
hub (rh) control transfers.
### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
**Record:**
- **Fixes:** — not present (expected for manual review)
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by / Acked-by:** — none
- **Link:**
`https://patch.msgid.link/20260429094413.181038-1-oneukum@suse.com`
- **Cc: stable@vger.kernel.org** — not present (not a negative signal)
- **Signed-off-by:** Oliver Neukum `<oneukum@suse.com>`, Greg Kroah-
Hartman `<gregkh@linuxfoundation.org>`
- **Notable:** Greg K-H merge; same author (Oliver Neukum) has prior USB
deadlock fixes nominated for stable (e.g. UAS EH deadlock, commit
`f6cc6093a729e`)
### Step 1.3: ANALYZE THE COMMIT BODY TEXT
**Record:**
- **Bug:** SCSI error-handler context must not perform allocations that
trigger I/O. USB storage/UAS error recovery can reset devices;
reset/resume issues control transfers to the parent hub, which may be
the root hub. `usbcore` ignored `mem_flags` from `usb_submit_urb()`
for root-hub control transfers.
- **Symptom:** Possible deadlock when storage error recovery resets a
device on a root-hub port.
- **Root cause:** `rh_call_control()` hardcodes `kzalloc(...,
GFP_KERNEL)` while callers (e.g. `usb_start_wait_urb()`) submit with
`GFP_NOIO`.
- **Version info:** “The problem exist since the storage driver has been
merged” — longstanding, not a recent regression.
### Step 1.4: DETECT HIDDEN BUG FIXES
**Record:** Not disguised — explicit deadlock fix. Propagating
`mem_flags` is the correct API behavior documented in
`drivers/usb/core/urb.c`.
---
## Phase 2: Diff Analysis
### Step 2.1: INVENTORY THE CHANGES
**Record:**
- **Files:** `drivers/usb/core/hcd.c` only (~15 lines changed)
- **Functions:** `rh_call_control()`, `rh_urb_enqueue()`,
`usb_hcd_submit_urb()`
- **Scope:** Single-file surgical fix
### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
**Record:**
- **Hunk 1 (`rh_call_control`):** Before: `kzalloc(tbuf_size,
GFP_KERNEL)`. After: `kzalloc(tbuf_size, mem_flags)` with new `gfp_t
mem_flags` parameter.
- **Hunk 2 (`rh_urb_enqueue`):** Before: calls `rh_call_control(hcd,
urb)` without flags. After: passes `mem_flags` through.
- **Hunk 3 (`usb_hcd_submit_urb`):** Before: `rh_urb_enqueue(hcd, urb)`
drops caller flags. After: `rh_urb_enqueue(hcd, urb, mem_flags)` —
matches the non-root-hub path that already passes `mem_flags` to
`hcd->driver->urb_enqueue()`.
### Step 2.3: IDENTIFY THE BUG MECHANISM
**Record:**
- **Category:** Deadlock / incorrect GFP context in block/SCSI error-
recovery path
- **Mechanism:** `usb_submit_urb(urb, GFP_NOIO)` →
`usb_hcd_submit_urb(urb, mem_flags)` → for root-hub devices,
`rh_call_control()` allocated with `GFP_KERNEL`, which can trigger
reclaim/I/O. In SCSI error-handler context (recovering a stuck block
device), that can deadlock waiting on I/O from the same device stack.
### Step 2.4: ASSESS THE FIX QUALITY
**Record:**
- **Quality:** Obviously correct — mirrors existing non-root-hub
behavior; minimal change
- **Regression risk:** Very low — only affects root-hub control path;
honors caller intent
- **Red flags:** None
---
## Phase 3: Git History Investigation
### Step 3.1: BLAME THE CHANGED LINES
**Record:**
- `kzalloc(tbuf_size, GFP_KERNEL)` introduced in `e57e780b346a72` (“usb:
rh_call_control tbuf overflow fix”, 2013-08-13)
- Buggy pattern present since 2013; relevant since USB storage error
paths use `GFP_NOIO`
### Step 3.2: FOLLOW THE FIXES: TAG
**Record:** No `Fixes:` tag — N/A
### Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
**Record:** Recent `hcd.c` changes are unrelated (SuperSpeed root hub
wMaxPacketSize, kcov, dma-noncoherent API). Standalone fix, not part of
a series.
### Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
**Record:** Oliver Neukum is an experienced USB contributor; prior
stable-nominated deadlock fixes in USB storage/UAS (`f6cc6093a729e`).
### Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
**Record:** No dependencies — self-contained signature/plumbing change
within one file. Applies standalone.
---
## Phase 4: Mailing List and External Research
### Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
**Record:** `b4 dig -c` failed (commit not in this tree).
Lore/patch.msgid.link fetch blocked (403/Anubis). **UNVERIFIED:** full
review thread content.
### Step 4.2: CHECK WHO REVIEWED THE PATCH
**Record:** **UNVERIFIED** (thread inaccessible). Greg K-H merge is a
strong quality signal.
### Step 4.3: SEARCH FOR THE BUG REPORT
**Record:** No external bug report or syzbot link. Mechanism explained
in commit message and verifiable in code.
### Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
**Record:** Standalone 1-patch fix; related theme with author’s UAS EH
deadlock fix but independent.
### Step 4.5: CHECK STABLE MAILING LIST HISTORY
**Record:** **UNVERIFIED** (could not search lore). No evidence against
stable suitability.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
**Record:** `rh_call_control()`, `rh_urb_enqueue()`,
`usb_hcd_submit_urb()`
### Step 5.2: TRACE CALLERS
**Record:**
- `usb_hcd_submit_urb()` ← `usb_submit_urb()` (`drivers/usb/core/urb.c`)
- `usb_submit_urb(urb, GFP_NOIO)` used widely in block/storage paths:
- `usb_start_wait_urb()` → `usb_control_msg()` path (`message.c:62`)
- `usb_stor_msg_common()` → `transport.c:143`
- `hub.c` hub operations (`usb_clear_port_feature`, port reset/resume)
- SCSI error handler → `eh_device_reset_handler` → e.g.
`uas_eh_device_reset_handler()` → `usb_reset_device()` (`uas.c:796`),
or `usb_stor_port_reset()` → `usb_reset_device()` (`transport.c:1455`)
- `usb_reset_device()` performs hub port reset/resume; parent may be
root hub → root-hub control transfers
### Step 5.3: TRACE CALLEES
**Record:** `rh_call_control()` calls `kzalloc()` (the problematic
allocation), `usb_hcd_link_urb_to_ep()`, hub descriptor handling.
### Step 5.4: FOLLOW THE CALL CHAIN
**Record:**
```
SCSI EH thread → eh_device_reset_handler → usb_reset_device()
→ hub_port_reset / usb_port_resume → usb_control_msg /
usb_submit_urb(GFP_NOIO)
→ usb_hcd_submit_urb(mem_flags=GFP_NOIO) → rh_urb_enqueue →
rh_call_control
→ kzalloc(GFP_KERNEL) [BUG]
```
Reachable from normal storage error recovery on root-hub ports (common
on laptops/embedded).
### Step 5.5: SEARCH FOR SIMILAR PATTERNS
**Record:** `usb_reset_device()` already uses `memalloc_noio_save()` as
a partial workaround (`hub.c:6384–6436`), but root-hub path still
violated the explicit `GFP_NOIO` contract. Non-root-hub `urb_enqueue`
already honors `mem_flags`; root hub was the outlier.
---
## Phase 6: Cross-Referencing Against the Local Tree
### Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
**Record:** **YES.** Tree is **v6.18.44** (`VERSION=6`, `PATCHLEVEL=18`,
`SUBLEVEL=44`). Buggy code at `hcd.c:489` (`kzalloc(tbuf_size,
GFP_KERNEL)`) and `hcd.c:1540` (`rh_urb_enqueue(hcd, urb)` without
`mem_flags`). Fix not yet applied.
### Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
**Record:** Expected **clean apply** — local file matches the “before”
state in the provided diff; low recent churn in this area.
### Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
**Record:** No equivalent fix found (`grep` for
`rh_call_control.*mem_flags` returns nothing). `usb_reset_device()`’s
`memalloc_noio_save()` workaround exists but does not replace this fix.
---
## Phase 7: Subsystem and Maintainer Context
### Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
**Record:** **USB core** (`drivers/usb/core/`) — **CORE/IMPORTANT**.
Affects all USB users; deadlock hits common storage error-recovery path.
### Step 7.2: ASSESS SUBSYSTEM ACTIVITY
**Record:** Actively maintained; Greg K-H USB tree. Fix addresses
longstanding API inconsistency.
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: DETERMINE WHO IS AFFECTED
**Record:** Users with USB mass-storage/UAS devices, especially on root-
hub ports, during I/O errors triggering SCSI error-handler device reset.
### Step 8.2: DETERMINE THE TRIGGER CONDITIONS
**Record:** Storage I/O error → SCSI EH device/bus reset → USB port
reset/resume on root hub. Not every boot, but realistic during error
recovery. Unprivileged users can trigger via normal block I/O to USB
storage.
### Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
**Record:** **Deadlock / hung task** in SCSI error-handler context —
**CRITICAL** (storage stuck, system may require reboot; no clean
recovery).
### Step 8.4: CALCULATE RISK-BENEFIT RATIO
**Record:**
- **Benefit:** HIGH — prevents real deadlock in error recovery
- **Risk:** VERY LOW — ~15 lines, propagates existing parameter, matches
non-root-hub behavior
- **Ratio:** Strongly favors backport
---
## Phase 9: Final Synthesis
### Step 9.1: COMPILE THE EVIDENCE
**FOR backport:**
- Real deadlock in SCSI/USB storage error recovery
- CRITICAL severity (system hang)
- Small, surgical, obviously correct
- Buggy code confirmed in v6.18.44
- Honors documented `GFP_NOIO` contract in `urb.c`
- Greg K-H merged; author has track record of similar stable fixes
- No new features/APIs
**AGAINST backport:**
- No syzbot/user report (mechanism-based fix)
- Mailing list review details unverified
**UNRESOLVED:**
- Full lore review thread inaccessible
### Step 9.2: STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — logic is clear; Greg K-H
merge
2. Fixes a real bug affecting users? **PASS** — SCSI EH + USB storage
reset path
3. Important issue? **PASS** — deadlock/hang, CRITICAL
4. Small and contained? **PASS** — single file, ~15 lines
5. No new features or APIs? **PASS** — internal plumbing only
6. Can apply to local tree? **PASS** — buggy code present; clean apply
expected
### Step 9.3: EXCEPTION CATEGORIES
**Record:** N/A — standard bug fix, not a quirk/ID/DT/docs exception.
### Step 9.4: Problem Summary for Stable Users
When USB storage error recovery resets a device on a root-hub port,
control transfers to the root hub go through `rh_call_control()`, which
ignored the caller’s `GFP_NOIO` and allocated with `GFP_KERNEL`. That
can trigger I/O during reclaim while the SCSI error handler is trying to
recover the same block device — a classic deadlock. The fix threads
`mem_flags` from `usb_hcd_submit_urb()` through `rh_urb_enqueue()` into
`rh_call_control()`, matching behavior already used for non-root-hub
devices.
---
## Verification
- [Phase 1] Parsed subject, tags, body from provided commit message
- [Phase 1] Identified Link tag; no Fixes/Reported-by/syzbot
- [Phase 2] Diff analysis: 3 functions changed in `hcd.c`; `GFP_KERNEL`
→ `mem_flags` in `kzalloc`
- [Phase 3] `git describe HEAD`: v6.18.44
- [Phase 3] `git blame -L 488,489 hcd.c`: `GFP_KERNEL` since
`e57e780b346a72` (2013)
- [Phase 3] `git log --oneline -20 -- drivers/usb/core/hcd.c`: no
duplicate fix
- [Phase 3] Author history: Oliver Neukum UAS deadlock fix
`f6cc6093a729e` with `Cc: stable`
- [Phase 4] `b4 dig -c HEAD`: no match (commit not in tree) — expected
- [Phase 4] `b4 dig -c f6cc6093a729e -w`: b4 works; related author patch
found
- [Phase 4] Lore/patch.msgid.link fetch: **UNVERIFIED** (403/bot
protection)
- [Phase 5] `grep usb_submit_urb.*GFP_NOIO`: storage, hub, message paths
confirmed
- [Phase 5] Traced `uas_eh_device_reset_handler` → `usb_reset_device`
(`uas.c:796`)
- [Phase 5] Traced `usb_stor_port_reset` → `usb_reset_device`
(`transport.c:1455`)
- [Phase 5] Read `usb_start_wait_urb`: `usb_submit_urb(urb, GFP_NOIO)`
(`message.c:62`)
- [Phase 5] Read `urb.c:349-350`: documents `GFP_NOIO` for block/storage
error paths
- [Phase 5] Read `usb_reset_device`: `memalloc_noio_save()` at
`hub.c:6384` (partial workaround, not substitute)
- [Phase 6] Confirmed buggy code at `hcd.c:489`, `814-819`, `1539-1540`
- [Phase 6] `grep rh_call_control.*mem_flags`: no match — fix not
present
- [Phase 8] Failure mode: deadlock in SCSI EH — CRITICAL
**YES**
drivers/usb/core/hcd.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index e11a8818af74a..4f198351ca9bb 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -450,7 +450,8 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len)
/* Root hub control transfers execute synchronously */
-static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
+static int rh_call_control(struct usb_hcd *hcd,
+ struct urb *urb, gfp_t mem_flags)
{
struct usb_ctrlrequest *cmd;
u16 typeReq, wValue, wIndex, wLength;
@@ -485,8 +486,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
* tbuf should be at least as big as the
* USB hub descriptor.
*/
- tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
- tbuf = kzalloc(tbuf_size, GFP_KERNEL);
+ tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
+ tbuf = kzalloc(tbuf_size, mem_flags);
if (!tbuf) {
status = -ENOMEM;
goto err_alloc;
@@ -811,12 +812,13 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
return retval;
}
-static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)
+static int rh_urb_enqueue(struct usb_hcd *hcd,
+ struct urb *urb, gfp_t mem_flags)
{
if (usb_endpoint_xfer_int(&urb->ep->desc))
return rh_queue_status (hcd, urb);
if (usb_endpoint_xfer_control(&urb->ep->desc))
- return rh_call_control (hcd, urb);
+ return rh_call_control(hcd, urb, mem_flags);
return -EINVAL;
}
@@ -1537,7 +1539,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
*/
if (is_root_hub(urb->dev)) {
- status = rh_urb_enqueue(hcd, urb);
+ status = rh_urb_enqueue(hcd, urb, mem_flags);
} else {
status = map_urb_for_dma(hcd, urb, mem_flags);
if (likely(status == 0)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.12] usb: xhci: Improve Soft Retries after short transfers
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (6 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.10] usb: core: hcd: fix possible deadlock in rh control transfers Sasha Levin
@ 2026-08-31 13:26 ` Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Verify Router Ready bit is set after router enumeration Sasha Levin
` (14 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:26 UTC (permalink / raw)
To: patches, stable
Cc: Michal Pecio, Mathias Nyman, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb, linux-kernel
From: Michal Pecio <michal.pecio@gmail.com>
[ Upstream commit e765ab012f73717238c95ab9c34bfc3c767fa48c ]
A short transfer is a successful one, so reset the error count.
Otherwise, endpoints which always complete short are limited to
three retries per endpoint life rather than per URB.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260603091132.1110849-7-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.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: xhci]` `[Improve]` – Improve soft-retry error counting
after short bulk/interrupt transfers.
**Step 1.2 – Tags**
Record:
- `Signed-off-by: Michal Pecio <michal.pecio@gmail.com>` (author)
- `Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>` (xHCI
maintainer)
- `Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>` (USB
maintainer)
- `Link: https://patch.msgid.link/20260603091132.1110849-7-
mathias.nyman@linux.intel.com` (patch 7/7 in a series)
- No `Fixes:`, `Reported-by:`, `Cc: stable`, `Tested-by:`, or `Reviewed-
by:` tags
**Step 1.3 – Body analysis**
Record:
- **Bug:** `ep->err_count` is not cleared on `COMP_SHORT_PACKET`, even
though a short transfer is a successful completion.
- **Symptom:** Endpoints that routinely complete short are limited to
three soft retries over the endpoint’s lifetime, not per URB/transfer.
- **Root cause:** `err_count` is reset on `COMP_SUCCESS` but not on
`COMP_SHORT_PACKET`, so successful short transfers do not reset the
counter.
- **Version info:** None in the message.
**Step 1.4 – Hidden bug fix?**
Record: **Yes.** Although the subject says “Improve,” this is a
correctness bug in xHCI soft-retry error accounting, not a cosmetic
cleanup.
---
## Phase 2: Diff Analysis
**Step 2.1 – Inventory**
Record:
- **Files:** `drivers/usb/host/xhci-ring.c` (+1 line)
- **Function:** `process_bulk_intr_td()`
- **Scope:** Single-file, one-line surgical fix
**Step 2.2 – Code flow change**
Record:
- **Before:** `COMP_SHORT_PACKET` sets `td->status = 0` only;
`ep->err_count` is unchanged.
- **After:** `COMP_SHORT_PACKET` also sets `ep->err_count = 0`, matching
`COMP_SUCCESS`.
- **Path:** Bulk/interrupt transfer completion in
`process_bulk_intr_td()`, called from `handle_tx_event()` for non-
control, non-isoc endpoints.
**Step 2.3 – Bug mechanism**
Record: **Logic / error-recovery bug.** `MAX_SOFT_RETRY` is 3. On
`COMP_USB_TRANSACTION_ERROR`, `ep->err_count` is incremented; if it
exceeds 3, soft retry is skipped and the error path proceeds without
`xhci_handle_halted_endpoint(..., EP_SOFT_RESET)`. Successful
completions should reset the counter, but short completions did not.
**Step 2.4 – Fix quality**
Record:
- **Obviously correct:** Short packet is a successful transfer
(`td->status = 0`); resetting `err_count` matches `COMP_SUCCESS` and
the design intent.
- **Minimal:** One line.
- **Regression risk:** Very low; only resets a counter on a success
path.
---
## Phase 3: Git History Investigation
**Step 3.1 – Blame**
Record:
- Soft retry introduced in `f8f80be501aa2` (2018): `ep_ring->err_count =
0` on `COMP_SUCCESS`.
- `err_count` moved to endpoint in `a1575120972ec` (Nov 2022, backported
with `Cc: stable`).
- `COMP_SHORT_PACKET` handling dates to 2017; never reset `err_count`.
- Bug present since soft-retry accounting was added (~2018).
**Step 3.2 – Fixes: tag**
Record: N/A – no `Fixes:` tag.
**Step 3.3 – Related file history**
Record:
- Related short-packet work by Michal Pecio: `9e3a28793d2fd` (“Fix Short
Packet handling rework ignoring errors”), affecting UAC, UVC, serial,
UAS.
- This fix is standalone; no dependency on other series patches for
correctness.
**Step 3.4 – Author context**
Record: Michal Pecio is an active xHCI contributor; Mathias Nyman is the
xHCI maintainer. Both signed off.
**Step 3.5 – Dependencies**
Record: **Standalone.** One-line addition; no new symbols or structures.
Patch 7/7 in submission, but this hunk is self-contained.
---
## Phase 4: Mailing List and External Research
**Step 4.1 – Original discussion**
Record: Link points to patch 7/7 in a Mathias Nyman series (2026-06-03).
`b4 dig` did not find the committed hash (commit not in this tree).
`patch.msgid.link` and `lore.kernel.org` were blocked (403/Anubis).
Discussion content could not be fetched.
**Step 4.2 – Reviewers**
Record: UNVERIFIED from lore. Commit has SOBs from author, xHCI
maintainer, and USB maintainer.
**Step 4.3 – Bug report**
Record: No external bug report or syzbot link. Bug inferred from code
analysis and commit message.
**Step 4.4 – Series context**
Record: Patch 7/7; this change does not appear to require earlier series
patches.
**Step 4.5 – Stable list**
Record: UNVERIFIED – could not search lore stable archives due to access
restrictions.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 – Key functions**
Record: `process_bulk_intr_td()`, caller `handle_tx_event()`.
**Step 5.2 – Callers**
Record: `handle_tx_event()` is the main xHCI transfer-event handler,
invoked from the xhci interrupt path for every bulk/interrupt transfer
completion. High-traffic, common path.
**Step 5.3 – Callees**
Record: On transaction error with `err_count <= MAX_SOFT_RETRY`, calls
`xhci_handle_halted_endpoint(..., EP_SOFT_RESET)`. When limit exceeded,
soft retry is skipped and `finish_td()` runs with `-EPROTO`.
**Step 5.4 – Reachability**
Record: **Highly reachable.** Any bulk/interrupt endpoint can hit this.
Critically, in `handle_tx_event()`:
```2707:2712:drivers/usb/host/xhci-ring.c
case COMP_SUCCESS:
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) !=
0) {
trb_comp_code = COMP_SHORT_PACKET;
xhci_dbg(xhci, "Successful completion on short
TX for slot %u ep %u with last td comp code %d\n",
slot_id, ep_index,
ep_ring->old_trb_comp_code);
}
```
Short transfers reported as `COMP_SUCCESS` are converted to
`COMP_SHORT_PACKET` before `process_bulk_intr_td()` runs. So the
`COMP_SUCCESS` `err_count` reset does **not** apply to short transfers
on typical hosts; they go through `COMP_SHORT_PACKET` without resetting
the counter.
**Step 5.5 – Similar patterns**
Record: `ep->err_count = 0` exists only on `COMP_SUCCESS` in
`process_bulk_intr_td()`. `handle_transferless_tx_event()` increments
`err_count` on stream transaction errors but never resets it on success.
This fix addresses the bulk/intr path only.
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 – Buggy code in this tree?**
Record: **Yes.** Local tree is **v6.18.44** (`git describe HEAD`, `make
kernelversion`). At lines 2572–2574, `COMP_SHORT_PACKET` does not reset
`ep->err_count`. The candidate commit is not yet applied.
**Step 6.2 – Backport complications**
Record: **Clean apply expected** – single line in a stable function with
no recent churn at that hunk.
**Step 6.3 – Related fixes already present?**
Record: `git log --grep='Soft Retries'` returned nothing. No equivalent
fix in this tree.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 – Subsystem**
Record: `drivers/usb/host/` – USB xHCI host controller driver.
**Criticality: IMPORTANT** (core USB path for most modern systems).
**Step 7.2 – Activity**
Record: Active subsystem; recent xhci fixes include HCE interrupt storm,
memory leaks, and short-packet handling.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 – Who is affected**
Record: Users of xHCI with bulk/interrupt endpoints that complete short
(serial, UVC, UAC, storage status pipes, interrupt IN with fixed
buffers). Essentially all xHCI users with typical USB devices.
**Step 8.2 – Trigger conditions**
Record:
- Endpoint sees successful short transfers (very common).
- Plus occasional `COMP_USB_TRANSACTION_ERROR` (transient bus errors).
- After 3 such errors, `err_count` stays elevated because short
successes never reset it.
- **Likelihood:** Moderate for long-lived endpoints with occasional bus
noise.
**Step 8.3 – Failure mode severity**
Record:
- Soft retry stops after 3 transaction errors over endpoint lifetime.
- Subsequent errors skip `EP_SOFT_RESET` and proceed to error completion
/ harder recovery.
- **Severity: MEDIUM-HIGH** – device malfunction, transfer failures,
possible disconnect; not a kernel oops, but real user-visible USB
breakage.
**Step 8.4 – Risk vs benefit**
Record:
- **Benefit:** HIGH for affected endpoints – restores intended per-
transfer error accounting.
- **Risk:** VERY LOW – one line, mirrors existing `COMP_SUCCESS`
behavior.
- **Ratio:** Strong benefit, minimal risk.
---
## Phase 9: Final Synthesis
**Step 9.1 – Evidence**
**FOR:**
- Real, long-standing logic bug in soft-retry accounting
- Affects a very common path (short bulk/interrupt transfers)
- `handle_tx_event()` converts success-with-remaining to
`COMP_SHORT_PACKET`, so most short transfers hit the buggy path
- After 3 transaction errors, error recovery degrades permanently for
that endpoint
- One-line, obviously correct fix
- Signed off by xHCI and USB maintainers
- Bug present in v6.18.44; fix applies cleanly
**AGAINST:**
- No syzbot report or user bug report in commit message
- Failure mode is degraded recovery, not kernel crash
- Lore discussion could not be verified
**UNRESOLVED:**
- Full mailing-list review thread inaccessible
- No explicit stable nomination found
**Step 9.2 – Stable rules checklist**
1. Obviously correct and tested? **PASS** – logic is clear; maintainer
SOBs present; no runtime test cited.
2. Fixes a real bug affecting users? **PASS** – short transfers are
routine; error accounting is wrong.
3. Important issue? **PASS (MEDIUM-HIGH)** – USB communication failures
on common device classes.
4. Small and contained? **PASS** – 1 line, 1 file.
5. No new features or APIs? **PASS**.
6. Can apply to local tree? **PASS** – buggy code confirmed in v6.18.44.
**Step 9.3 – Exception categories**
Record: None (not device ID, quirk, DT, build, or docs). Standard bug
fix.
**Step 9.4 – Decision rationale**
This is a clear correctness bug in xHCI error recovery. Because
`handle_tx_event()` rewrites success-with-short-data to
`COMP_SHORT_PACKET`, the existing `err_count` reset on `COMP_SUCCESS`
does not cover the common short-transfer case. Endpoints that routinely
short-packet can exhaust their three soft retries permanently after only
three transient transaction errors, causing degraded USB error recovery.
The fix is minimal, obviously correct, and low risk.
---
## Verification
- **[Phase 1]** Parsed subject, tags, and body from provided commit
message.
- **[Phase 2]** Confirmed diff: +1 line `ep->err_count = 0` in
`COMP_SHORT_PACKET` case.
- **[Phase 3]** `git blame -L 2560,2595 drivers/usb/host/xhci-ring.c`:
soft retry from 2018, `err_count` on endpoint from 2022.
- **[Phase 3]** `git show f8f80be501aa2`: original soft retry added
`err_count` reset on `COMP_SUCCESS` only.
- **[Phase 3]** `git show a1575120972ec`: moved `err_count` to endpoint;
had `Cc: stable`.
- **[Phase 3]** `git log --oneline -20 -- drivers/usb/host/xhci-ring.c`:
recent xhci activity confirmed.
- **[Phase 4]** `b4 dig`: no match (commit not in tree).
Lore/patch.msgid.link: blocked (403/Anubis). **UNVERIFIED:** review
thread content.
- **[Phase 5]** `grep process_bulk_intr_td`: called from
`handle_tx_event()` line 2982.
- **[Phase 5]** Read `handle_tx_event()` lines 2707–2712: `COMP_SUCCESS`
with remaining length converted to `COMP_SHORT_PACKET`.
- **[Phase 5]** `grep err_count drivers/usb/host/`: only reset on
`COMP_SUCCESS` in xhci-ring.c.
- **[Phase 6]** `git describe HEAD` → v6.18.44; `make kernelversion` →
6.18.44.
- **[Phase 6]** Read lines 2572–2574: bug present (no reset on
`COMP_SHORT_PACKET`).
- **[Phase 6]** `git log --grep='Soft Retries'`: no existing fix in
tree.
- **[Phase 8]** `MAX_SOFT_RETRY` = 3 in `drivers/usb/host/xhci.h` line
1272.
- **[Phase 8]** Read `COMP_USB_TRANSACTION_ERROR` path: when `err_count
> 3`, soft retry skipped.
**YES**
drivers/usb/host/xhci-ring.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 2bb7569c95054..3f1a6089a01ce 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2570,6 +2570,7 @@ static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
td->status = 0;
break;
case COMP_SHORT_PACKET:
+ ep->err_count = 0;
td->status = 0;
break;
case COMP_STOPPED_SHORT_PACKET:
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.6] thunderbolt: Verify Router Ready bit is set after router enumeration
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (7 preceding siblings ...)
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] usb: xhci: Improve Soft Retries after short transfers Sasha Levin
@ 2026-08-31 13:26 ` Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Avoid reserved fields in path config space for USB4 routers Sasha Levin
` (13 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:26 UTC (permalink / raw)
To: patches, stable
Cc: Gil Fine, Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Gil Fine <gil.fine@linux.intel.com>
[ Upstream commit 062023c4364ffdc72978ed2de1d1435e5d4eee43 ]
The USB4 Connection Manager guide specifies that after enumerating a
router, the Connection Manager shall verify that the Router Ready bit
(ROUTER_CS_6.RR) has been set to ensure hardware configuration has completed.
Currently, this step is missing from the enumeration sequence.
Add this check to follow the Connection Manager guide more closely.
Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.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:** `[thunderbolt]` `[verify]` — After USB4 router enumeration,
verify that the Router Ready bit (`ROUTER_CS_6.RR`) is set before
continuing.
### Step 1.2: Commit Message Tags
**Record:**
- **Fixes:** — not present (expected for manual review)
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by / Acked-by / Cc: stable:** — none in the committed
message
- **Link:** — none
- **Signed-off-by:** Gil Fine, Mika Westerberg (ignore any pipeline-
added SOBs)
Notable pattern: no fuzzer report, no user report, no explicit stable
nomination.
### Step 1.3: Commit Body Analysis
**Record:**
- **Bug described:** USB4 Connection Manager guide requires verifying
`ROUTER_CS_6.RR` after router enumeration to confirm hardware
configuration is complete; Linux omits this step.
- **Symptom/failure mode:** Not spelled out as a crash or user report.
Implied failure mode is continuing enumeration before the router is
ready, which can cause flaky or failed device bring-up.
- **Version info:** none
- **Root cause:** Missing mandatory hardware-ready polling in the USB4
enumeration sequence.
### Step 1.4: Hidden Bug Fix Detection
**Record:** Yes, likely a hidden correctness bug. The message frames it
as CM-guide compliance, but the mechanism is a missing hardware-ready
wait in a hot enumeration path — the same class of fix as the existing
Configuration Ready (`ROUTER_CS_6.CR`) wait already in this driver.
---
## Phase 2: Diff Analysis
### Step 2.1: Change Inventory
**Record:**
- `drivers/thunderbolt/tb_regs.h`: +1 line (`ROUTER_CS_6_RR`)
- `drivers/thunderbolt/usb4.c`: +6 / -1 lines in `usb4_switch_setup()`
- **Functions modified:** `usb4_switch_setup()`
- **Scope:** single-function, 2-file surgical fix
### Step 2.2: Code Flow Change
**Record:**
- **Hunk 1 (`tb_regs.h`):** Adds `ROUTER_CS_6_RR` (`BIT(24)`).
- **Hunk 2 (`usb4.c`):**
- **Before:** `usb4_switch_setup()` wrote `ROUTER_CS_5` and returned
immediately.
- **After:** checks `tb_sw_write()` return value, then waits up to 500
ms for `ROUTER_CS_6_RR` via `tb_switch_wait_for_bit()`.
- **Path affected:** USB4 router enumeration setup in
`tb_switch_configure()` → `usb4_switch_setup()`.
### Step 2.3: Bug Mechanism
**Record:**
- **Category:** synchronization / hardware-readiness race
- **Mechanism:** Without waiting for RR, the CM can proceed to plug-
event enablement and later configuration/tunnel setup while the router
may still be finishing hardware configuration. The fix blocks until RR
is set or returns `-ETIMEDOUT`.
### Step 2.4: Fix Quality
**Record:**
- **Quality:** High. Mirrors the existing CR wait in
`usb4_switch_configuration_valid()`.
- **Regression risk:** Low. `tb_switch_wait_for_bit()` returns
immediately when the bit is already set; 500 ms is a max timeout, not
a fixed sleep.
- **Red flags:** none significant.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame / Introduction of Buggy Code
**Record:**
- `usb4_switch_setup()` introduced in `d49b4f043d63b` (2022-10-11),
refined in later commits.
- The direct-return `tb_sw_write()` path dates to original USB4 support
(`b04079837b209`, 2019-12-18).
- **Bug present since initial USB4 support** in this subsystem.
### Step 3.2: Fixes: Tag
**Record:** N/A — no `Fixes:` tag.
### Step 3.3: Related File History
**Record:**
- Part of Gil Fine’s 5-patch series `[PATCH 0/5] CM fixes to follow CM
guide more closely` on lore.
- Related upstream-only commits on `master` not in `linux-6.18.y`:
- `ba2cc38511012` — increase CR timeout to 500 ms
- `e24f3c0df4837` — increase notification timeout
- `69a7b98770b7e` — verify PCIe adapter detect state before tunnel
setup
- **This patch is standalone**; it does not depend on the other series
members.
### Step 3.4: Author Context
**Record:** Gil Fine is a regular Thunderbolt contributor; prior work
includes moving/wait-bit infrastructure (`1639664fb74f3`). Mika
Westerberg committed/applied it.
### Step 3.5: Prerequisites
**Record:**
- `tb_switch_wait_for_bit()` exists in this tree (`switch.c`, declared
in `tb.h`).
- `usb4_switch_setup()` exists and matches the patch context.
- `git apply --check` on the upstream patch: **clean apply**.
- **Standalone:** yes.
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Discussion
**Record:**
- `b4 dig -c 062023c4364ff` → https://patch.msgid.link/20260126220606.34
76657-4-gil.fine@linux.intel.com
- Series: v1 only, `[PATCH 3/5]`
- Cover letter: “improves Connection Manager implementation to better
align with the CM Guide”
- **No stable nomination found** in the downloaded thread.
### Step 4.2: Reviewers
**Record:** `b4 dig -w` CC’d `mika.westerberg@linux.intel.com`, `linux-
usb@vger.kernel.org`, Andreas Noever, YehezkelShB, Lukas Wunner. No
`Reviewed-by` / `Acked-by` captured in the committed result.
### Step 4.3: Bug Report
**Record:** No external bug report, syzbot link, or `Reported-by:`.
### Step 4.4: Series Context
**Record:** 5-patch CM-guide alignment series. Other patches include log
cleanup, PCIe LTSSM check, CR timeout increase, and notification timeout
increase. Only patch 3 is under review here.
### Step 4.5: Stable List History
**Record:** No stable-list discussion found for this specific patch.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** `usb4_switch_setup()`, `tb_switch_wait_for_bit()`,
`tb_switch_configure()`
### Step 5.2: Callers
**Record:**
- `usb4_switch_setup()` called from `tb_switch_configure()` in
`switch.c` for USB4 routers.
- `tb_switch_configure()` called from:
- hotplug path in `tb.c` (`~1344`) during downstream router discovery
- resume/reconfigure paths (`switch.c`, `tb.c`)
**Context:** device hotplug/enumeration and resume — common, user-
visible paths.
### Step 5.3: Callees
**Record:** `tb_sw_read()`, `tb_sw_write()`, `tb_switch_wait_for_bit()`
— standard router config-space access and polling.
### Step 5.4: Reachability
**Record:**
- Triggered by USB4/Thunderbolt hotplug, resume, and domain
initialization.
- Requires `CONFIG_USB4` / Thunderbolt stack; not universal, but
important on modern laptops and docks.
- **Userspace-reachable indirectly** via physical hotplug/connect
events.
### Step 5.5: Similar Patterns
**Record:** Existing CR wait in `usb4_switch_configuration_valid()`:
```329:330:drivers/thunderbolt/usb4.c
return tb_switch_wait_for_bit(sw, ROUTER_CS_6, ROUTER_CS_6_CR,
ROUTER_CS_6_CR, 50);
```
The RR wait is the missing earlier-stage counterpart after enumeration
setup.
---
## Phase 6: Cross-Reference Against Local Tree
### Step 6.1: Does Buggy Code Exist Here?
**Record:** **Yes.**
- Local tree: `stable/linux-6.18.y`, `v6.18.44`
- `ROUTER_CS_6_RR` is **not** present
- `usb4_switch_setup()` still returns directly after `tb_sw_write()`:
```294:297:drivers/thunderbolt/usb4.c
/* TBT3 supported by the CM */
val &= ~ROUTER_CS_5_CNS;
return tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);
```
- Commit `062023c4364ff` is on `master` but **not** in this `6.18.y`
checkout.
### Step 6.2: Backport Complications
**Record:** **Clean apply expected.** `git apply --check` succeeded with
no conflicts.
### Step 6.3: Related Fixes Already Present?
**Record:** No equivalent RR wait already in `6.18.y`. Related dock
timing fix `bd646c768a934` is already present, but it addresses a
different issue (sideband polling delay), not RR verification.
---
## Phase 7: Subsystem and Maintainer Context
### Step 7.1: Subsystem Criticality
**Record:** `drivers/thunderbolt` — **IMPORTANT**. Affects
USB4/Thunderbolt device enumeration on laptops, docks, and peripherals.
### Step 7.2: Subsystem Activity
**Record:** Actively maintained; recent stable-relevant fixes include
dock connection and wake issues.
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users with USB4/Thunderbolt hardware and
`CONFIG_USB4`/Thunderbolt enabled — common on Intel/Apple/modern AMD
laptops and docks.
### Step 8.2: Trigger Conditions
**Record:**
- USB4 router enumeration during hotplug, resume, or domain setup
- Race manifests when software proceeds before router sets RR
- **Likelihood:** intermittent/timing-dependent; bug has existed since
2019 without a cited report, but the race window is real on a
mandatory spec step
### Step 8.3: Failure Mode Severity
**Record:**
- **Without fix:** possible flaky enumeration, failed router bring-up,
downstream tunnel/device failures
- **With fix:** explicit success or `-ETIMEDOUT` instead of proceeding
on unready hardware
- **Severity:** **MEDIUM-HIGH** for affected hardware paths; not a
kernel oops, but can make docks/devices fail to connect
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** improves correctness of USB4 enumeration; prevents use of
a router before hardware configuration completes
- **Risk:** very low — tiny patch, existing helper, immediate return
when bit already set
- **Ratio:** favorable
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Summary
**For backport:**
- Real missing hardware-ready wait in USB4 enumeration
- Small, surgical, cleanly applies to `6.18.y`
- Uses existing `tb_switch_wait_for_bit()` infrastructure
- Consistent with existing CR wait in same driver
- Failure aborts enumeration cleanly instead of continuing in a bad
state
- Maintainer-authored/applied Thunderbolt fix
**Against backport:**
- No user report, syzbot, or crash trace
- Framed as CM-guide compliance rather than fixing a reported regression
- Issue present since 2019 without demonstrated widespread impact
- Part of a broader spec-alignment series
- No explicit stable nomination or `Cc: stable`
**Unresolved:**
- No proof of a specific production failure this patch fixes
- No `Tested-by` on hardware
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — logic is clear; no runtime
test evidence
2. Fixes a real bug affecting users? **PASS** — missing mandatory
hardware-ready check in enumeration
3. Important issue? **PASS** — can cause device/dock enumeration failure
4. Small and contained? **PASS** — 7 lines, 2 files
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS**
### Step 9.3: Exception Categories
**Record:** Not a device-ID/quirk/DT/build/docs exception. This is a
driver correctness/hardware-readiness fix.
### Step 9.4: Decision Rationale
For **linux-6.18.y**, this is worth backporting. The missing RR
verification is not just documentation polish: it allows the connection
manager to continue router bring-up before the hardware signals
configuration completion. That is a real race in a user-visible hotplug
path. The fix is tiny, uses established driver infrastructure, applies
cleanly, and matches an existing pattern already present in this tree
for `ROUTER_CS_6_CR`. The lack of a specific bug report weakens the
case, but stable policy favors small correctness fixes that prevent
hardware-init races on commonly used laptop/dock paths when risk is
minimal.
---
## Verification
- [Phase 1] Parsed subject/tags/body from provided commit and `git show
062023c4364ff`
- [Phase 2] Diff analysis: 2 files, `usb4_switch_setup()` only; adds RR
define and wait
- [Phase 3] `git describe HEAD` → `v6.18.44`; tree is `6.18.44`
- [Phase 3] `git blame` on `usb4.c:295-297` → path present since USB4
bring-up
- [Phase 3] `usb4_switch_setup` introduced via `b04079837b209` /
`d49b4f043d63bd`
- [Phase 3] `tb_switch_wait_for_bit` present since `1639664fb74f3`
- [Phase 3] Commit not in `stable/linux-6.18.y`; present on `master` as
`062023c4364ff`
- [Phase 4] `b4 dig -c 062023c4364ff` found lore thread
- [Phase 4] `b4 dig -a` found v1 series only
- [Phase 4] `b4 dig -w` listed Thunderbolt/USB maintainers/reviewers
- [Phase 4] Downloaded mbox; cover letter confirms CM-guide alignment
series; no stable CC found
- [Phase 5] `grep usb4_switch_setup` → called from
`tb_switch_configure()`
- [Phase 5] `grep tb_switch_configure` → hotplug path in `tb.c:1344`
- [Phase 5] Verified existing CR wait in
`usb4_switch_configuration_valid()`
- [Phase 6] Confirmed `ROUTER_CS_6_RR` absent in current `6.18.y`
checkout
- [Phase 6] `git apply --check` on upstream patch → clean apply
- [Phase 6] Verified prerequisites `tb_switch_wait_for_bit` and USB4
support are ancestors of HEAD
- [Phase 8] Read failure handling in `tb.c:1344-1346` — configure
failure drops switch and aborts bring-up
**YES****Verdict: YES** — backport to `linux-6.18.y`.
The commit adds a missing Router Ready (`ROUTER_CS_6.RR`) wait in
`usb4_switch_setup()` after USB4 router enumeration. Without it, the
driver can continue before hardware configuration finishes, which can
cause flaky dock/device bring-up. The fix is small (7 lines), applies
cleanly to `6.18.y`, and follows the same pattern as the existing
Configuration Ready wait in the Thunderbolt driver.
The main weakness is the lack of a reported bug or crash trace — it's
framed as CM-guide compliance — but the correctness issue in a hot
enumeration path and the low risk still make it a reasonable stable
candidate.
drivers/thunderbolt/tb_regs.h | 1 +
drivers/thunderbolt/usb4.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 97404d8d878bf..7f2dcb309e928 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -216,6 +216,7 @@ struct tb_regs_switch_header {
#define ROUTER_CS_6_WOPS BIT(2)
#define ROUTER_CS_6_WOUS BIT(3)
#define ROUTER_CS_6_HCI BIT(18)
+#define ROUTER_CS_6_RR BIT(24)
#define ROUTER_CS_6_CR BIT(25)
#define ROUTER_CS_7 0x07
#define ROUTER_CS_9 0x09
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index 9430bed07c468..6383fd43203d7 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -294,7 +294,12 @@ int usb4_switch_setup(struct tb_switch *sw)
/* TBT3 supported by the CM */
val &= ~ROUTER_CS_5_CNS;
- return tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);
+ ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);
+ if (ret)
+ return ret;
+
+ return tb_switch_wait_for_bit(sw, ROUTER_CS_6, ROUTER_CS_6_RR,
+ ROUTER_CS_6_RR, 500);
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.12] thunderbolt: Avoid reserved fields in path config space for USB4 routers
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (8 preceding siblings ...)
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Verify Router Ready bit is set after router enumeration Sasha Levin
@ 2026-08-31 13:26 ` Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Improve multi-display DisplayPort tunnel allocation Sasha Levin
` (12 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:26 UTC (permalink / raw)
To: patches, stable
Cc: Gil Fine, Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Gil Fine <gil.fine@linux.intel.com>
[ Upstream commit 7e49bb89df860bb7352974100cd5dd48752bb646 ]
According to USB4 spec, USB4 Connection Manager shall not change value
of any fields that are defined as "RsvdZ" or "VD". Specifically fields:
Path Credits Allocated, IFC, ISE fields in path config space shall not
be written by CM. To handle this, CM shall first read current path
config space from the hardware, change only the fields that can be
changed, and then write back the path config space.
Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `thunderbolt: Avoid reserved fields in path
config space for USB4 routers`
**Local tree:** `v6.18.43` (`linux-6.18.y`, detached HEAD at
`c7f0dac02d232`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[thunderbolt] [avoid] Avoid writing reserved/vendor-defined
path config fields on USB4 routers`
### Step 1.2: Tags
**Record:**
- `Signed-off-by: Gil Fine <gil.fine@linux.intel.com>` (author)
- `Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>`
(subsystem maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
stable@vger.kernel.org`, or `Link:` tags
- Notable: maintainer sign-off from Intel Thunderbolt lead; no
syzbot/fuzzer report
### Step 1.3: Body analysis
**Record:**
- **Bug:** USB4 Connection Manager must not write `RsvdZ`/`VD` fields in
path config space — specifically Path Credits Allocated, IFC, and ISE
on protocol adapters
- **Symptom/failure mode:** Undefined behavior per USB4 spec when CM
writes reserved fields; can break tunnel path programming on USB4
routers
- **Root cause:** Driver zero-initialized hop config and wrote all
fields unconditionally, clobbering vendor-defined/reserved bits on
USB4 protocol adapters
- **Fix approach:** Read-modify-write path config; only modify fields CM
is allowed to change; preserve reserved fields on USB4 protocol
adapters; program credits/FC only on pre-USB4 routers and lane (null)
adapters
### Step 1.4: Hidden bug fix detection
**Record:** Yes — despite "Avoid" wording rather than "fix", this is a
spec-compliance bug fix. The deactivate path already had a partial USB4
guard (`!tb_switch_is_usb4`), showing prior awareness; activation was
never updated.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/thunderbolt/path.c` only (+~20 net lines)
- **Functions:** `__tb_path_deactivate_hop()`, `tb_path_activate()`
- **Scope:** Single-file surgical fix
### Step 2.2: Code flow changes
**Hunk 1 — `__tb_path_deactivate_hop()` (clear_fc path):**
- **Before:** Skip clearing `ingress_fc`/`ingress_shared_buffer` on all
USB4 ports
- **After:** Clear those fields on lane adapters (`tb_port_is_null`) OR
pre-USB4 routers; still skip on USB4 protocol adapters
- **Path:** Hop deactivation during tunnel teardown/reconfiguration
**Hunk 2 — `tb_path_activate()`:**
- **Before:** `struct tb_regs_hop hop = { 0 }`, set all fields including
`initial_credits`, `ingress_fc`, `ingress_shared_buffer`, write to
hardware
- **After:** Read existing hop config from hardware first; set only
permitted fields; conditionally set credits/ingress FC only for
`tb_port_is_null()` or `!tb_switch_is_usb4()`
- **Path:** Every tunnel activation hop write
### Step 2.3: Bug mechanism
**Record:** **Logic/correctness + hardware spec compliance bug**
- Writing zero-initialized values to vendor-defined/reserved USB4 path
config fields
- Incomplete deactivate logic: lane adapters on USB4 never had ingress
FC cleared
- Same pattern already fixed elsewhere in this tree (e.g.
`tb_port_add_nfc_credits()` skips NFC programming on USB4 protocol
adapters)
### Step 2.4: Fix quality
**Record:**
- Obviously correct read-modify-write aligned with USB4 CM requirements
- Minimal, follows existing `tb_port_is_null` / `tb_switch_is_usb4`
conventions
- Low regression risk: pre-USB4 behavior unchanged; USB4 lane adapters
get correct programming; USB4 protocol adapters preserve hardware
state
- No API/struct changes
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** Buggy activation code present since base import
`19eef1d98eeda` in this stable tree. Partial deactivate guard
(`!tb_switch_is_usb4`) also from that import. USB4 support is mature in
6.18.y.
### Step 3.2: Fixes tag
**Record:** N/A — no `Fixes:` tag present.
### Step 3.3: Related file history
**Record:** Recent stable backports in this tree include multiple
thunderbolt/USB4 fixes (`da40583823153`, `b5daa920f44cb`, property
validation series). This fits the established USB4 compliance fix
pattern. Patch submitted as `[PATCH 01/12]` in a larger series (per web
index), but this hunk is self-contained in `path.c` only.
### Step 3.4: Author context
**Record:** Gil Fine (Intel), signed off by Mika Westerberg (Thunderbolt
subsystem maintainer). Authors are core Thunderbolt maintainers.
### Step 3.5: Dependencies
**Record:** No dependencies. Uses `tb_port_is_null()` and
`tb_switch_is_usb4()` — both present in this tree (`tb.h` lines 631–634,
1319–1322). Standalone, no prerequisite commits required.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** Web search found submission as `[PATCH 01/12]` on 2026-04-27
to linux-usb (Mika Westerberg series). Part of broader "Make the driver
USB4 CM guide compliant" effort. `b4 dig -c <sha>` not possible — commit
hash not in local remotes. Lore direct fetch blocked (403/Anubis).
### Step 4.2: Reviewers
**Record:** UNVERIFIED — could not fetch full thread. Maintainer SOB
from Mika Westerberg is a strong quality signal.
### Step 4.3: Bug reports
**Record:** No external bug report or syzbot link in commit message. Bug
identified via USB4 spec compliance review.
### Step 4.4: Series context
**Record:** Part of 12-patch series, but this patch only touches
`path.c` and is independently applicable. Later series patches (e.g.
activation order reversal) are separate changes.
### Step 4.5: Stable list history
**Record:** UNVERIFIED — could not search lore stable list due to access
restrictions.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Modified functions
**Record:** `__tb_path_deactivate_hop()`, `tb_path_activate()`
### Step 5.2: Callers
**Record:**
- `tb_path_activate()` → `tb_tunnel_activate()` (`tunnel.c:2402`) →
tunnel setup for PCIe, USB3, DisplayPort, DMA, etc.
- `tb_tunnel_activate()` called from `tb.c` (USB3 tunnel creation ~975,
PCIe ~2038, hotplug paths ~2298, ~2348, ~3156, ~3266)
- `__tb_path_deactivate_hop()` → `tb_path_deactivate()`,
`tb_path_activate()` (re-activation), `tb_path_deactivate_hop()` →
`switch.c:1620` (reset)
### Step 5.3: Key callees
**Record:** `tb_port_read()`, `tb_port_write()` — direct hardware config
space access on Thunderbolt/USB4 routers
### Step 5.4: Reachability
**Record:** Triggered on every tunnel activation/deactivation on USB4
hardware — device hotplug, dock attach, PCIe tunnel, USB3 tunnel,
DisplayPort tunnel. Common user-facing paths, not obscure debug-only
code.
### Step 5.5: Similar patterns
**Record:** `switch.c:581` already guards NFC credit programming: `if
(tb_switch_is_usb4(port->sw) && !tb_port_is_null(port)) return 0;` —
same USB4 lane-vs-protocol adapter distinction. This fix completes the
same pattern for path config space.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code exists?
**Record:** **YES.** Current `path.c` at lines 429–432 (incomplete
deactivate guard) and 543–572 (zero-init + unconditional field writes in
`tb_path_activate`) match pre-fix state exactly.
### Step 6.2: Backport complications
**Record:** Expected **clean apply**. Line-by-line comparison of diff
context against local `path.c` matches. `tb_port_is_null` and
`tb_switch_is_usb4` exist. No conflicting refactors in recent stable
history for this file.
### Step 6.3: Related fixes already present?
**Record:** Partial fix in deactivate (`!tb_switch_is_usb4` guard)
exists but activation bug remains unfixed. No duplicate fix for this
specific issue in stable history.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/thunderbolt/` — **IMPORTANT** peripheral driver,
but tunnel activation affects PCIe, USB3, DisplayPort over TB/USB4 on
widely deployed laptop/dock hardware.
### Step 7.2: Subsystem activity
**Record:** Active — multiple thunderbolt stable backports in 6.18.y
recently (security, XDomain, property validation, debugfs).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users with USB4-compliant routers (Intel Tiger Lake+, AMD
USB4, modern docks/hubs). Requires `CONFIG_THUNDERBOLT`. Affects tunnel
establishment on protocol adapters.
### Step 8.2: Trigger conditions
**Record:** Every path activation through USB4 protocol adapters — dock
plug, eGPU, USB4 hub, DP tunnel setup. Common, not race-dependent.
### Step 8.3: Failure mode severity
**Record:** USB4 spec undefined behavior from illegal register writes →
tunnel activation failures, intermittent connectivity, possible router
misconfiguration. **Severity: MEDIUM-HIGH** (serious functional impact;
not demonstrated as kernel crash/CVE, but real hardware impact).
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH for USB4 users — fixes spec violation on common
hotplug/tunnel paths
- **Risk:** LOW — ~25 lines, one file, preserves existing pre-USB4
behavior, follows established in-tree pattern
- **Ratio:** Strong benefit, minimal risk
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Fixes real USB4 spec violation with undefined-behavior consequences
- Affects common tunnel activation paths (PCIe/USB3/DP)
- Small, surgical, maintainer-authored fix
- Buggy code confirmed present in 6.18.43
- No dependencies; helpers already in tree
- Consistent with existing USB4 compliance guards in same driver
- Intel maintainer sign-off
**AGAINST backport:**
- No explicit user crash report or CVE
- Part of larger series (but this patch is self-contained)
- No `Fixes:` tag pointing to when bug was introduced (bug predates USB4
support maturity)
**UNRESOLVED:**
- Full lore review thread and explicit stable nomination comments
- Commit hash not in local git remotes for `b4 dig`
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — read-modify-write per USB4
CM spec; maintainer SOB; aligns with existing driver patterns
2. Fixes a real bug? **PASS** — illegal writes to reserved/vendor-
defined path config fields
3. Important issue? **PASS** — MEDIUM-HIGH functional impact on USB4
tunnel establishment
4. Small and contained? **PASS** — one file, ~25 lines
5. No new features/APIs? **PASS** — spec compliance only
6. Can apply to local tree? **PASS** — code present, helpers exist,
clean apply expected
### Step 9.3: Exception categories
**Record:** Hardware workaround / spec compliance fix for USB4 routers —
qualifies similarly to existing USB4 quirks in this driver.
### Step 9.4: Decision rationale
For **linux-6.18.y**, USB4 router support is fully present and widely
used. The driver currently violates the USB4 spec by writing reserved
path config fields during every tunnel activation on protocol adapters.
The fix is minimal, obviously correct, self-contained, and from the
subsystem maintainers. The stable tree already carries related USB4
compliance fixes in the same driver. The benefit to dock/laptop users on
USB4 hardware outweighs the negligible backport risk.
---
## Verification
- [Phase 1] `git describe HEAD` → `v6.18.43-1-gc7f0dac02d232`; Makefile
→ 6.18.43
- [Phase 1] Parsed tags: only Gil Fine + Mika Westerberg SOBs; no
Fixes/Reported-by/Link
- [Phase 2] Read `drivers/thunderbolt/path.c` lines 392–590: confirmed
pre-fix code matches diff "before" state
- [Phase 2] Read `tb_regs.h` lines 502–527: `initial_credits`,
`ingress_fc`, `ingress_shared_buffer` fields confirmed
- [Phase 3] `git log --oneline -S "only for pre-USB4 adapters" --
drivers/thunderbolt/path.c` → `19eef1d98eeda` (bug present since
import)
- [Phase 3] `git show 19eef1d98eeda:drivers/thunderbolt/path.c` →
confirmed buggy activation code in base
- [Phase 3] `git log origin --oneline -S "Needed for USB4 routers"` →
commit not in local origin
- [Phase 4] Web search → found `[PATCH 01/12]` 2026-04-27 on linux-usb;
part of USB4 CM compliance series
- [Phase 4] `b4 dig` / lore fetch → blocked (no commit hash; lore
403/Anubis)
- [Phase 5] `grep tb_path_activate` → callers in `tunnel.c:2402`, `tb.c`
(975, 2038, 2298, 2348, 3156, 3266)
- [Phase 5] `grep tb_tunnel_activate` → USB3/PCIe hotplug paths
confirmed
- [Phase 5] Read `switch.c:577-582` → existing USB4 lane-vs-protocol NFC
guard pattern
- [Phase 6] Read `tb.h:631-634, 1319-1322` → `tb_port_is_null()` and
`tb_switch_is_usb4()` exist
- [Phase 6] Manual diff context comparison → lines 429, 543–572 match;
clean apply expected
- [Phase 7] `git log --oneline -20 --grep="thunderbolt"` → active
thunderbolt stable backports in 6.18.y
- [Phase 8] Failure mode assessed from USB4 spec language in commit
message + code analysis
- **UNVERIFIED:** Full lore review thread; explicit stable@ nomination;
automated `git apply --check` (heredoc corrupt; manual comparison used
instead)
**YES**The analysis is complete for **linux-6.18.y** (`v6.18.43`).
**Verdict: YES** — backport this commit.
The driver currently zero-initializes path config and writes
reserved/vendor-defined USB4 fields (`initial_credits`, `ingress_fc`,
`ingress_shared_buffer`) on protocol adapters during tunnel activation.
That violates the USB4 spec and can break PCIe/USB3/DisplayPort tunnel
setup on USB4 routers. The fix is small (~25 lines in `path.c`), self-
contained, uses helpers already in the tree (`tb_port_is_null`,
`tb_switch_is_usb4`), and matches existing USB4 compliance patterns
elsewhere in the driver.
A search of local `sasha-next` and `linux-next` branches did not find
the commit hash yet (it appears to be a newer mainline patch from the
April 2026 series), but the buggy code is present in this stable tree
and the patch should apply cleanly.
drivers/thunderbolt/path.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c
index f9b11dadfbdd5..d8e547286127a 100644
--- a/drivers/thunderbolt/path.c
+++ b/drivers/thunderbolt/path.c
@@ -426,7 +426,8 @@ static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index,
* in the USB4 spec so we clear them
* only for pre-USB4 adapters.
*/
- if (!tb_switch_is_usb4(port->sw)) {
+ if (tb_port_is_null(port) ||
+ !tb_switch_is_usb4(port->sw)) {
hop.ingress_fc = 0;
hop.ingress_shared_buffer = 0;
}
@@ -546,15 +547,18 @@ int tb_path_activate(struct tb_path *path)
__tb_path_deactivate_hop(path->hops[i].in_port,
path->hops[i].in_hop_index, path->clear_fc);
- /* dword 0 */
+ /* Needed for USB4 routers, read path config space before write */
+ res = tb_port_read(path->hops[i].in_port, &hop, TB_CFG_HOPS,
+ 2 * path->hops[i].in_hop_index, 2);
+ if (res)
+ goto err;
+
hop.next_hop = path->hops[i].next_hop_index;
hop.out_port = path->hops[i].out_port->port;
- hop.initial_credits = path->hops[i].initial_credits;
hop.pmps = path->hops[i].pm_support;
hop.unknown1 = 0;
hop.enable = 1;
- /* dword 1 */
out_mask = (i == path->path_length - 1) ?
TB_PATH_DESTINATION : TB_PATH_INTERNAL;
in_mask = (i == 0) ? TB_PATH_SOURCE : TB_PATH_INTERNAL;
@@ -564,12 +568,21 @@ int tb_path_activate(struct tb_path *path)
hop.drop_packages = path->drop_packages;
hop.counter = path->hops[i].in_counter_index;
hop.counter_enable = path->hops[i].in_counter_index != -1;
- hop.ingress_fc = path->ingress_fc_enable & in_mask;
hop.egress_fc = path->egress_fc_enable & out_mask;
- hop.ingress_shared_buffer = path->ingress_shared_buffer
- & in_mask;
- hop.egress_shared_buffer = path->egress_shared_buffer
- & out_mask;
+ hop.egress_shared_buffer = path->egress_shared_buffer & out_mask;
+ /*
+ * Protocol adapters IFC and ISE bits, and Path Credits
+ * Allocated are vendor defined in the USB4 spec so we
+ * program them only for pre-USB4 and lane adapters.
+ */
+ if (tb_port_is_null(path->hops[i].in_port) ||
+ !tb_switch_is_usb4(path->hops[i].in_port->sw)) {
+ hop.initial_credits = path->hops[i].initial_credits;
+ hop.ingress_fc = path->ingress_fc_enable & in_mask;
+ hop.ingress_shared_buffer =
+ path->ingress_shared_buffer & in_mask;
+ }
+
hop.unknown3 = 0;
tb_port_dbg(path->hops[i].in_port, "Writing hop %d\n", i);
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.6] thunderbolt: Improve multi-display DisplayPort tunnel allocation
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (9 preceding siblings ...)
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Avoid reserved fields in path config space for USB4 routers Sasha Levin
@ 2026-08-31 13:26 ` Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-6.1] thunderbolt: Don't create multiple DMA tunnels on firmware connection manager Sasha Levin
` (11 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:26 UTC (permalink / raw)
To: patches, stable
Cc: Alan Borzeszkowski, Mika Westerberg, Sasha Levin, andreas.noever,
westeri, YehezkelShB, linux-usb, linux-kernel
From: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
[ Upstream commit afe9021d63b46233f5c87d52b820fa26e7f562cd ]
When 3 monitors are connected through Thunderbolt dock to the system at
once, one of the monitors might fail to establish DisplayPort tunnel.
This happens during DP bandwidth negotiation - each monitor takes
maximum bandwidth that is supported and there might not be enough for
3rd display. In this case Thunderbolt driver drops DP tunnel and
'forgets' about it but with DP bandwidth allocation mode, that comes in
later, some bandwidth might be freed.
Make Thunderbolt driver check again if DP tunnel can be established
after DP bandwidth consumption changed.
Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The analysis is complete. A background `git log --all` search timed out
(as expected with that flag), but the review was finished using targeted
history lookups instead.
**Verdict for v6.18.44: YES**
This is a small, low-risk fix for a real multi-monitor Thunderbolt dock
bug: when three displays negotiate bandwidth, a failed third DP tunnel
is never retried after allocation mode frees bandwidth. The patch adds
`tb_tunnel_dp()` on the success path of
`tb_handle_dp_bandwidth_request()`, matching an existing pattern
elsewhere in `tb.c`, and applies cleanly to this tree.
drivers/thunderbolt/tb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index b516b1ad83a19..c8dcb3ca45152 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -2847,6 +2847,9 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work)
/* Update other clients about the allocation change */
tb_recalc_estimated_bandwidth(tb);
+
+ tb_dbg(tb, "checking if more DP tunnels can be established now\n");
+ tb_tunnel_dp(tb);
}
put_sw:
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.1] thunderbolt: Don't create multiple DMA tunnels on firmware connection manager
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (10 preceding siblings ...)
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Improve multi-display DisplayPort tunnel allocation Sasha Levin
@ 2026-08-31 13:27 ` Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] usb: gadget: goku_udc: avoid NULL deref of dev->driver in INT_USBRESET log Sasha Levin
` (10 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:27 UTC (permalink / raw)
To: patches, stable
Cc: Alan Borzeszkowski, Mika Westerberg, Sasha Levin, andreas.noever,
westeri, YehezkelShB, linux-usb, linux-kernel
From: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
[ Upstream commit cf0c38ee554c3e9062408cc3a38325483d52ecd0 ]
Firmware connection manager supports only one DMA tunnel per XDomain
connection. Firmware prior Intel Titan Ridge failed the operation
directly but the same does not happen anymore on Titan Ridge and
forward. For this reason add an explicit check, and fail the operation
accordingly in the driver.
Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Background task results:
1. **`git log --all -S` (failed)** — The search with `--all` hung and
produced no output; it was killed.
2. **`git log -S` without `--all` (succeeded)** — Completed in ~52s. In
this 6.18.y tree, `icm_fr_approve_xdomain_paths` shows up at the
`Linux 6.18-rc7` import (`ac3fd01e4c1ef`) and the bulk history point
`19eef1d98eeda`. That confirms the ICM XDomain approve path is
present in this tree; it doesn’t give a clean “introduced in mainline
at commit X” answer because of how this checkout’s history is
structured.
3. **Kernel.org subject search (succeeded, empty)** — A grep on
torvalds/linux.git for the commit subject returned only the cgit page
shell with no matching commits, so the patch wasn’t in mainline
master at search time (or hadn’t landed yet).
None of this changes the earlier **YES** verdict: the buggy ICM path
exists in 6.18.43, the fix isn’t present, and the change is still
appropriate for stable.
drivers/thunderbolt/icm.c | 10 ++++++++++
drivers/thunderbolt/xdomain.c | 25 +++++++++++++++++++------
include/linux/thunderbolt.h | 2 ++
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index f213d9174dc57..961d66c2f81db 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -587,6 +587,11 @@ static int icm_fr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
struct icm_fr_pkg_approve_xdomain request;
int ret;
+ if (atomic_read(&xd->ntunnels) >= 1) {
+ tb_warn(tb, "only one tunnel is supported by the firmware\n");
+ return -EOPNOTSUPP;
+ }
+
memset(&request, 0, sizeof(request));
request.hdr.code = ICM_APPROVE_XDOMAIN;
request.link_info = xd->depth << ICM_LINK_INFO_DEPTH_SHIFT | xd->link;
@@ -1157,6 +1162,11 @@ static int icm_tr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
struct icm_tr_pkg_approve_xdomain request;
int ret;
+ if (atomic_read(&xd->ntunnels) >= 1) {
+ tb_warn(tb, "only one tunnel is supported by the firmware\n");
+ return -EOPNOTSUPP;
+ }
+
memset(&request, 0, sizeof(request));
request.hdr.code = ICM_APPROVE_XDOMAIN;
request.route_hi = upper_32_bits(xd->route);
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index 1eb149445fa05..e2c46366c8160 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -2021,6 +2021,7 @@ struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
INIT_DELAYED_WORK(&xd->state_work, tb_xdomain_state_work);
INIT_DELAYED_WORK(&xd->properties_changed_work,
tb_xdomain_properties_changed);
+ atomic_set(&xd->ntunnels, 0);
xd->local_uuid = kmemdup(local_uuid, sizeof(uuid_t), GFP_KERNEL);
if (!xd->local_uuid)
@@ -2302,9 +2303,15 @@ int tb_xdomain_enable_paths(struct tb_xdomain *xd, int transmit_path,
int transmit_ring, int receive_path,
int receive_ring)
{
- return tb_domain_approve_xdomain_paths(xd->tb, xd, transmit_path,
- transmit_ring, receive_path,
- receive_ring);
+ int ret;
+
+ ret = tb_domain_approve_xdomain_paths(xd->tb, xd, transmit_path,
+ transmit_ring, receive_path,
+ receive_ring);
+ if (ret)
+ return ret;
+ atomic_inc(&xd->ntunnels);
+ return 0;
}
EXPORT_SYMBOL_GPL(tb_xdomain_enable_paths);
@@ -2327,9 +2334,15 @@ int tb_xdomain_disable_paths(struct tb_xdomain *xd, int transmit_path,
int transmit_ring, int receive_path,
int receive_ring)
{
- return tb_domain_disconnect_xdomain_paths(xd->tb, xd, transmit_path,
- transmit_ring, receive_path,
- receive_ring);
+ int ret;
+
+ ret = tb_domain_disconnect_xdomain_paths(xd->tb, xd, transmit_path,
+ transmit_ring, receive_path,
+ receive_ring);
+ if (ret)
+ return ret;
+ atomic_dec(&xd->ntunnels);
+ return 0;
}
EXPORT_SYMBOL_GPL(tb_xdomain_disable_paths);
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index 7204586c10c3e..466f315f0be7b 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -230,6 +230,7 @@ enum tb_link_width {
* changed notification
* @bonding_possible: True if lane bonding is possible on local side
* @target_link_width: Target link width from the remote host
+ * @ntunnels: Keeps track of how many tunnels go through this XDomain
* @link: Root switch link the remote domain is connected (ICM only)
* @depth: Depth in the chain the remote domain is connected (ICM only)
*
@@ -276,6 +277,7 @@ struct tb_xdomain {
int properties_changed_retries;
bool bonding_possible;
u8 target_link_width;
+ atomic_t ntunnels;
u8 link;
u8 depth;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] usb: gadget: goku_udc: avoid NULL deref of dev->driver in INT_USBRESET log
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (11 preceding siblings ...)
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-6.1] thunderbolt: Don't create multiple DMA tunnels on firmware connection manager Sasha Levin
@ 2026-08-31 13:27 ` Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] thunderbolt: Verify PCIe adapter in detect state before tunnel setup Sasha Levin
` (9 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:27 UTC (permalink / raw)
To: patches, stable
Cc: Stepan Ionichev, Greg Kroah-Hartman, Sasha Levin, linux-usb,
linux-kernel
From: Stepan Ionichev <sozdayvek@gmail.com>
[ Upstream commit 5bf5e3fba9bc7dfd69701521dbe9809f8ccbdb02 ]
goku_irq() handles a number of bus events under a single ep0 path.
It already guards the gadget driver suspend/resume callbacks against a
NULL ->driver:
if (dev->gadget.speed != USB_SPEED_UNKNOWN
&& dev->driver
&& dev->driver->resume) {
spin_unlock(&dev->lock);
dev->driver->resume(&dev->gadget);
...
}
but the very next branch unconditionally dereferences dev->driver
when an INT_USBRESET arrives:
if (stat & INT_USBRESET) {
ACK(INT_USBRESET);
INFO(dev, "USB reset done, gadget %s\n",
dev->driver->driver.name);
}
If the controller raises INT_USBRESET before any gadget driver has
been bound (or after one has been unbound), dev->driver is NULL and
the printk dereferences NULL.
smatch flags the inconsistency:
drivers/usb/gadget/udc/goku_udc.c:1618 goku_irq() error:
we previously assumed 'dev->driver' could be null (see line 1607)
Fall back to a placeholder when the gadget driver is not bound.
No functional change while a gadget driver is bound.
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
Link: https://patch.msgid.link/20260509110636.19762-1-sozdayvek@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.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: gadget: goku_udc]` `[avoid]` — avoid NULL dereference
of `dev->driver` in the `INT_USBRESET` logging path inside `goku_irq()`.
### Step 1.2: Commit Message Tags
**Record:**
- **Fixes:** — not present (expected for manual review)
- **Reported-by:** — none (smatch static analysis instead)
- **Tested-by:** — none
- **Reviewed-by:** — none in message
- **Acked-by:** — none
- **Link:**
`https://patch.msgid.link/20260509110636.19762-1-sozdayvek@gmail.com`
- **Cc: stable:** — not present (expected)
- **Signed-off-by:** Stepan Ionichev `<sozdayvek@gmail.com>`, Greg
Kroah-Hartman `<gregkh@linuxfoundation.org>`
- **Notable:** smatch-detected inconsistency; Greg KH merged it (USB
maintainer)
### Step 1.3: Commit Body Analysis
**Record:**
- **Bug:** `goku_irq()` unconditionally dereferences
`dev->driver->driver.name` on `INT_USBRESET`, while adjacent
suspend/resume code already treats `dev->driver` as possibly NULL.
- **Symptom:** NULL pointer dereference in interrupt context → kernel
oops.
- **Trigger:** `INT_USBRESET` before a gadget driver is bound, or after
one is unbound.
- **Root cause:** Inconsistent NULL handling in the same function;
logging path missed the guard.
- **Version info:** None stated; code dates to original driver import
(2005).
### Step 1.4: Hidden Bug Fix Detection
**Record:** Not disguised — this is an explicit NULL-deref fix. smatch
flagged the inconsistency between line 1607 (NULL check) and line 1619
(unconditional deref).
---
## Phase 2: Diff Analysis
### Step 2.1: Change Inventory
**Record:**
- **File:** `drivers/usb/gadget/udc/goku_udc.c` (+2 / -1)
- **Function:** `goku_irq()`
- **Scope:** Single-file, surgical fix (one logging expression)
### Step 2.2: Code Flow Change
**Record:**
- **Before:** `INFO(dev, "USB reset done, gadget %s\n",
dev->driver->driver.name);` — always dereferences `dev->driver`.
- **After:** Ternary: `dev->driver ? dev->driver->driver.name : "<not
bound>"`.
- **Path:** IRQ handler, `INT_USBRESET` branch under `INT_DEVWIDE`;
normal USB bus-reset event path.
### Step 2.3: Bug Mechanism
**Record:** **Category:** NULL pointer dereference. **Mechanism:** `%s`
format argument evaluates `dev->driver->driver.name` before `printk`;
when `dev->driver` is NULL, this faults in IRQ context.
### Step 2.4: Fix Quality
**Record:** Obviously correct. Matches the existing pattern at line 1158
in the same file (`dev->driver ? dev->driver->driver.name : "(none)"`).
Minimal change, no behavior change when a driver is bound. Regression
risk: very low.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame
**Record:** Buggy lines introduced in `1da177e4c3f41` (Linus Torvalds,
2005-04-16) — present since initial import. Long-standing latent bug.
### Step 3.2: Fixes: Tag
**Record:** N/A — no `Fixes:` tag.
### Step 3.3: Related File History
**Record:** Related commits in this tree:
- `0d66e04875c5a` — probe-time NULL deref fix (different bug)
- `37a757e31d992` — cast cleanup on `driver.name`
- `2a334cfaf3931` — memory leak in `goku_probe()`
- Standalone one-patch fix; not part of a series.
### Step 3.4: Author Context
**Record:** Stepan Ionichev has other NULL-deref fixes in this tree
(e.g. `1f6a4aec0d366` rtc/msc313). Not the goku_udc maintainer, but
submits credible static-analysis-driven fixes.
### Step 3.5: Dependencies
**Record:** No dependencies. Patch applies cleanly (`git apply --check`
succeeded). Self-contained.
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Patch Discussion
**Record:** `b4 am` retrieved the mbox from lore. `b4 dig -c` failed
(commit not in this tree). lore.kernel.org blocked by bot protection;
full thread not readable via WebFetch. Mbox contains only the initial
patch, no review replies.
### Step 4.2: Reviewers
**Record:** `b4 dig -w` unavailable (no commit hash). Mbox shows only
author SOB; Greg KH SOB on committed version indicates maintainer
acceptance.
### Step 4.3: Bug Report
**Record:** smatch static analysis report in commit message. No syzbot,
no user crash reports. smatch cross-reference to line 1607 is concrete
evidence.
### Step 4.4: Related Patches
**Record:** Standalone; no series dependencies.
### Step 4.5: Stable List History
**Record:** Not searched (lore blocked). No stable nomination found in
available sources.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** `goku_irq()` (modified), context: `ep0_start()`,
`udc_enable()`, `goku_udc_start()`, `goku_udc_stop()`.
### Step 5.2: Callers
**Record:** `goku_irq()` registered via `request_irq()` in
`goku_probe()` at line 1805. Runs in hard/IRQ context on every
controller interrupt.
### Step 5.3: Callees
**Record:** `readl()`, `writel()`, `ACK()` macro, `INFO()` macro (wraps
`printk`), `ep0_setup()`, suspend/resume callbacks.
### Step 5.4: Call Chain / Reachability
**Record:** Reachable path verified in code:
1. `goku_probe()` registers IRQ (line 1805) before any gadget driver
binds.
2. On USB connect, `INT_PWRDETECT` → `ep0_start()` (line 1566) enables
`INT_DEVWIDE | INT_EP0` (line 1340), which includes `INT_USBRESET`.
3. `ep0_start()` can run with `dev->driver == NULL` (driver binds later
via `goku_udc_start()` at line 1378).
4. Host USB reset → `INT_USBRESET` → unconditional
`dev->driver->driver.name` deref → oops.
Also reachable after `goku_udc_stop()` sets `dev->driver = NULL` (line
1410) or `INT_SYSERROR` clears it (line 1559).
### Step 5.5: Similar Patterns
**Record:** Same file line 1158 already uses `dev->driver ?
dev->driver->driver.name : "(none)"`. `pxa25x_udc.c` uses the same
idiom. This fix brings `goku_irq()` in line with established convention.
---
## Phase 6: Cross-Reference Against Local Tree
### Step 6.1: Buggy Code Present?
**Record:** **YES.** Local tree is **v6.18.44** (`VERSION=6`,
`PATCHLEVEL=18`, `SUBLEVEL=44`). Buggy code at lines 1618–1619:
```1616:1620:drivers/usb/gadget/udc/goku_udc.c
if (stat & INT_USBRESET) { /* hub reset
done */
ACK(INT_USBRESET);
INFO(dev, "USB reset done, gadget %s\n",
dev->driver->driver.name);
}
```
Bug present since 2005 import; not introduced after this tree branched.
### Step 6.2: Backport Complications
**Record:** Clean apply confirmed. No conflicting changes in this hunk.
Expected difficulty: **clean apply**.
### Step 6.3: Related Fixes Already Present?
**Record:** `0d66e04875c5a` (probe crash fix) is present. This specific
`INT_USBRESET` NULL-deref fix is **not** present.
---
## Phase 7: Subsystem and Maintainer Context
### Step 7.1: Subsystem Criticality
**Record:** `drivers/usb/gadget/udc/` — USB gadget UDC driver.
**PERIPHERAL** (niche Toshiba TC86C001 PCI hardware, `CONFIG_USB_GOKU`).
### Step 7.2: Subsystem Activity
**Record:** Low churn recently; mostly header moves and minor cleanups.
Mature, legacy driver.
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users with `CONFIG_USB_GOKU` (Toshiba TC86C001 "Goku-S" PCI
UDC). Small but real embedded/legacy population.
### Step 8.2: Trigger Conditions
**Record:** USB cable connect → host bus reset before gadget driver
bind; or reset after driver unbind/error. **Moderately likely** during
normal enumeration. Not userspace-syscall reachable; requires the
hardware and USB activity.
### Step 8.3: Failure Mode Severity
**Record:** NULL deref in IRQ handler → **kernel oops** (system crash).
**Severity: HIGH** for affected hardware.
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** Prevents IRQ-context crash on a normal enumeration path;
smatch-verified real bug.
- **Risk:** Minimal (2-line ternary, matches existing file pattern).
- **Ratio:** Favorable — low risk, real crash prevention.
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Summary
**FOR backport:**
- Real NULL pointer dereference in IRQ handler
- Reachable before gadget driver bind (verified call chain)
- Kernel oops when triggered
- smatch static analysis confirmation
- 2-line surgical fix, obviously correct
- Matches existing pattern in same file (line 1158)
- Applies cleanly to v6.18.44
- Greg KH merged (USB maintainer)
- Bug present since 2005 — affects all stable trees with this driver
**AGAINST backport:**
- Niche hardware (`CONFIG_USB_GOKU`)
- Only affects logging path (but deref happens evaluating format args,
so it still crashes)
- No user crash reports or syzbot report
- Limited mailing-list review visibility
**Unresolved:** Full lore review thread not accessible (bot protection).
No explicit stable nomination found.
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — trivial ternary, smatch-
verified, maintainer-merged.
2. Fixes a real bug affecting users? **PASS** — NULL deref on real
hardware enumeration path.
3. Important issue? **PASS** — IRQ-context NULL deref → kernel oops
(HIGH severity for affected users).
4. Small and contained? **PASS** — 2 lines, one function.
5. No new features or APIs? **PASS** — logging safety only.
6. Can apply to local tree? **PASS** — clean apply verified.
### Step 9.3: Exception Categories
**Record:** None (not device ID, quirk, DT, build fix, or docs).
Standard bug fix.
### Step 9.4: Decision Rationale
For **this tree (6.18.44)**, the buggy code exists and is reachable:
`ep0_start()` enables `INT_USBRESET` handling on USB connect before any
gadget driver binds, so a host bus reset can trigger a NULL dereference
in `goku_irq()`. The fix is minimal, follows an existing idiom in the
same driver, and prevents a kernel oops on affected hardware. While the
driver serves niche legacy hardware, stable trees routinely accept small
NULL-deref fixes in drivers when the crash path is real and the fix is
obviously safe.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body from user-provided commit
message and mbox file
- **[Phase 1]** Confirmed: no Fixes:/Reported-by:/Cc: stable tags;
smatch reference in body
- **[Phase 2]** Diff: +2/-1 in `goku_irq()`, ternary NULL guard on
`dev->driver`
- **[Phase 3]** `git blame -L 1616,1620`: buggy code from
`1da177e4c3f41` (2005)
- **[Phase 3]** `git log --oneline -20 --
drivers/usb/gadget/udc/goku_udc.c`: related fixes listed; no duplicate
of this fix
- **[Phase 3]** `git apply --check`: patch applies cleanly
- **[Phase 4]** `b4 dig -c ac2a984c2f87e`: failed (commit not in tree)
- **[Phase 4]** `b4 am` on message-id: retrieved mbox with patch content
- **[Phase 4]** WebFetch lore URL: blocked by bot protection
(UNVERIFIED: review thread content)
- **[Phase 5]** Read `goku_irq()`, `ep0_start()`, `goku_probe()`,
`goku_udc_start/stop`: confirmed reachable NULL-deref path
- **[Phase 5]** `grep dev->driver`: line 1158 has existing NULL-guard
pattern; line 1619 does not
- **[Phase 5]** `goku_udc.h`: `INT_USBRESET` part of `INT_DEVWIDE`;
enabled by `ep0_start()`
- **[Phase 6]** `git describe HEAD`: v6.18.44
- **[Phase 6]** `head Makefile`: VERSION=6, PATCHLEVEL=18, SUBLEVEL=44
- **[Phase 6]** Read lines 1616–1620: buggy code confirmed present
- **[Phase 7]** Kconfig: `CONFIG_USB_GOKU` — Toshiba TC86C001 PCI device
- **[Phase 8]** Failure mode: IRQ NULL deref → oops, severity HIGH for
affected hardware
**YES**The commit **should be backported** to this tree (v6.18.44).
**Summary:** `goku_irq()` can NULL-dereference `dev->driver` when
handling `INT_USBRESET` during USB connect/reset before a gadget driver
is bound — a path `ep0_start()` enables on cable connect. The fix is a
2-line ternary that matches an existing pattern in the same file (line
1158), applies cleanly, and prevents an IRQ-context kernel oops on
`CONFIG_USB_GOKU` hardware.
**Verdict: YES**
drivers/usb/gadget/udc/goku_udc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c
index b860c2e764494..c262749a29cc7 100644
--- a/drivers/usb/gadget/udc/goku_udc.c
+++ b/drivers/usb/gadget/udc/goku_udc.c
@@ -1616,7 +1616,8 @@ static irqreturn_t goku_irq(int irq, void *_dev)
if (stat & INT_USBRESET) { /* hub reset done */
ACK(INT_USBRESET);
INFO(dev, "USB reset done, gadget %s\n",
- dev->driver->driver.name);
+ dev->driver ? dev->driver->driver.name :
+ "<not bound>");
}
// and INT_ERR on some endpoint's crc/bitstuff/... problem
}
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18] thunderbolt: Verify PCIe adapter in detect state before tunnel setup
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (12 preceding siblings ...)
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] usb: gadget: goku_udc: avoid NULL deref of dev->driver in INT_USBRESET log Sasha Levin
@ 2026-08-31 13:27 ` Sasha Levin
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18-5.10] usbip: vhci_hcd: fix NULL deref in status_show_vhci Sasha Levin
` (8 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:27 UTC (permalink / raw)
To: patches, stable
Cc: Gil Fine, Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Gil Fine <gil.fine@linux.intel.com>
[ Upstream commit 69a7b98770b7e80deec0465d97710611a0e51774 ]
The USB4 Connection Manager guide suggests that a PCIe downstream and
PCIe upstream adapters of the USB4 router is in the Detect state before
setting up a PCIe tunnel.
Add this check by verifying the LTSSM field in ADP_PCIE_CS_0 before
tunnel setup.
Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.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 line**
Record: `[thunderbolt] [verify] Verify PCIe adapter in detect state
before tunnel setup` — USB4/Thunderbolt driver change that adds a pre-
tunnel LTSSM state check.
**Step 1.2 — Tags**
Record:
- `Signed-off-by: Gil Fine <gil.fine@linux.intel.com>` (author)
- `Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>`
(subsystem maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, `Link:`, or `Cc: stable@vger.kernel.org` (absence of stable tags
is expected per pipeline instructions)
**Step 1.3 — Body analysis**
Record:
- **Bug described:** PCIe tunnel setup may proceed before USB4 PCIe
upstream/downstream adapters reach LTSSM DETECT, violating the USB4
Connection Manager (CM) guide.
- **Symptom/failure mode:** Premature PCIe tunnel activation on USB4
routers; can cause PCIe tunnel activation failures or unreliable
Thunderbolt PCIe device bring-up (not explicitly described as
crash/oops).
- **Version info:** None in commit message.
- **Root cause (author):** Missing LTSSM state verification on
`ADP_PCIE_CS_0` before tunnel activation.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Although framed as CM-guide compliance, this is a
timing/race fix: activation can run before adapters are ready. It adds a
bounded wait (500 ms) and fails cleanly (`-ETIMEDOUT`) instead of
proceeding in an invalid state.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- `drivers/thunderbolt/tb.h`: +1 line (declare
`usb4_pci_port_ltssm_state()`)
- `drivers/thunderbolt/tb_regs.h`: +15 lines
(`ADP_PCIE_CS_0_LTSSM_MASK`, `enum tb_pcie_ltssm_state`)
- `drivers/thunderbolt/tunnel.c`: +35 lines
(`tb_pci_port_ltssm_state_detect()`, `tb_pci_pre_activate()`, hook
assignment)
- `drivers/thunderbolt/usb4.c`: +24 lines
(`usb4_pci_port_ltssm_state()`)
- **Total:** ~75 lines added, 0 removed
- **Functions modified/added:** `tb_pci_port_ltssm_state_detect`,
`tb_pci_pre_activate`, `tb_tunnel_alloc_pci`,
`usb4_pci_port_ltssm_state`
- **Scope:** Single-subsystem, surgical fix across 4 related files
**Step 2.2 — Code flow (per hunk)**
Record:
- **tb_regs.h:** Adds LTSSM bitfield mask and state enum for PCIe
adapter CS register.
- **usb4.c:** New helper reads `ADP_PCIE_CS_0` LTSSM field via
`tb_port_read()`.
- **tunnel.c — detect helper:** Polls every 50 ms for up to 500 ms until
`USB4_PCIE_LTSSM_DETECT`; returns 0 on success, `-ETIMEDOUT` on
timeout.
- **tunnel.c — pre_activate:** For USB4 routers only, checks downstream
then upstream adapter; non-USB4 routers skip (return 0).
- **tunnel.c — alloc:** Sets `tunnel->pre_activate =
tb_pci_pre_activate` before activation.
- **tb.h:** Exposes LTSSM read helper.
**Before → After:**
Before: `tb_tunnel_alloc_pci()` goes straight to `tb_tunnel_activate()`
→ path enable → `tb_pci_activate()`.
After: `tb_tunnel_activate()` first calls `pre_activate`, which waits
for DETECT on USB4 PCIe adapters.
**Step 2.3 — Bug mechanism**
Record:
- **Category:** Timing/race / correctness in device initialization
- **Mechanism:** Tunnel activation can start before PCIe adapters are in
the required LTSSM DETECT state. Fix inserts a synchronization wait in
the existing `pre_activate` hook (same pattern as DP/USB3 tunnels).
**Step 2.4 — Fix quality**
Record:
- Logic is straightforward and matches existing thunderbolt polling
patterns (`fsleep`, bounded timeout).
- Minimal, no unrelated changes.
- **Regression risk:** Low–medium. Only applies to `tb_switch_is_usb4()`
routers; bounded 500 ms wait; failure path is clean abort. Risk of
false `-ETIMEDOUT` if hardware is never in DETECT at this point is
unverified but maintainer-reviewed.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: `tb_tunnel_alloc_pci()` dates to 2017 (Mika Westerberg). The
missing LTSSM check has been absent since PCIe tunnel support existed;
USB4-specific exposure grew with USB4 router support (e.g.
`usb4_pci_port_set_ext_encapsulation` from 2024).
**Step 3.2 — Fixes: tag**
Record: Not applicable — no `Fixes:` tag present.
**Step 3.3 — Related file history**
Record:
- Prior related fix in tree: `54967f4177d3d` (2023-12-14) — "Make PCIe
tunnel setup and teardown follow CM guide"
- `pre_activate` infrastructure added Jan 2025 (`ae765788936d9`,
`d6d458d42e1e1`) — used by DP/USB3, not yet PCI
- This commit is **patch 5/8** in series "Make the driver follow CM
guide more closely" (May 2026); patches 4/6/7/8 (path hop order,
Router Ready bit, timeout increases) are **not** in this tree
- **Standalone:** This patch compiles and functions independently; no
hard dependency on other series patches
**Step 3.4 — Author context**
Record: Gil Fine is an active Intel thunderbolt contributor; Mika
Westerberg is subsystem maintainer. Multiple prior CM-guide compliance
commits from same authors are already in this tree.
**Step 3.5 — Dependencies**
Record: No prerequisite commits required. Local tree already has
`pre_activate` hook, `tb_switch_is_usb4()`,
`usb4_pci_port_set_ext_encapsulation()`, and `ADP_PCIE_CS_0` register
definitions.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record:
- `b4 dig -c HEAD`: No match (commit not in local tree)
- Web search found patch at [ratatoskr](https://ratatoskr.run/linux-
usb/2026/05/8999078) as **[PATCH 5/8]** in series sent 2026-05-12 by
Mika Westerberg
- Series cover: "Make the driver follow CM guide more closely"
- Follow-up from maintainer 2026-05-20; no stable nomination found in
available metadata
- lore.kernel.org blocked by bot protection; full thread not readable
**Step 4.2 — Reviewers**
Record: Maintainer (Mika Westerberg) is author/submitter of series. Full
recipient list from `b4 dig -w` unavailable (commit not in tree).
**Step 4.3 — Bug reports**
Record: No `Reported-by:`, syzbot, or bugzilla links. Issue inferred
from USB4 CM guide requirement and driver behavior analysis.
**Step 4.4 — Series context**
Record: 8-patch series; this is one CM-compliance piece. Other patches
address DP allocation, lane bonding log, Router Ready bit, path hop
activation order, and timeout increases. This patch is independently
applicable but full CM compliance may need the rest of the series
eventually.
**Step 4.5 — Stable list history**
Record: Could not search lore stable list (bot protection). No stable
nomination found in ratatoskr metadata.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `usb4_pci_port_ltssm_state`, `tb_pci_port_ltssm_state_detect`,
`tb_pci_pre_activate`, `tb_tunnel_alloc_pci`, `tb_tunnel_activate`
**Step 5.2 — Callers**
Record:
- `tb_tunnel_alloc_pci()` called from `tb.c:tb_tunnel_pci()` and KUnit
tests
- `tb_tunnel_activate()` called from `tb.c` at lines 975, 2038, 2298,
2348, 3156, 3266 — hotplug, chain construction, resume paths
- `pre_activate` invoked in `tb_tunnel_activate()` at
`tunnel.c:2395-2398` before path activation
**Step 5.3 — Callees**
Record: `usb4_pci_port_ltssm_state` → `tb_port_read()`; detect helper →
`fsleep(50)`; pre_activate → `tb_switch_is_usb4()`
**Step 5.4 — Reachability**
Record: Triggered during Thunderbolt/USB4 device hotplug and PCIe tunnel
creation — common path for docks, eGPUs, NVMe enclosures. Requires
`CONFIG_THUNDERBOLT` and USB4 hardware. Not directly userspace-syscall
reachable, but triggered by normal plug events.
**Step 5.5 — Similar patterns**
Record: DP tunnel uses `tb_dp_pre_activate()` with USB4-specific checks
(`tunnel.c:987-1011`). USB3 uses `tb_usb3_pre_activate()`.
`usb4_port_wait_for_bit()` in `usb4.c` is the established polling
pattern for USB4 register readiness.
---
## Phase 6: Cross-Reference Against Local Tree (v6.18.44)
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is `v6.18.44` (`VERSION=6, PATCHLEVEL=18,
SUBLEVEL=44`). Grep confirms no `ltssm`, `usb4_pci_port_ltssm_state`, or
`tb_pci_pre_activate`. `tb_tunnel_alloc_pci()` at `tunnel.c:504-514`
sets only `tunnel->activate = tb_pci_activate` with no `pre_activate`.
Bug has been present since PCIe tunnel support; USB4 exposure is
relevant for all USB4 routers in this tree.
**Step 6.2 — Backport complications**
Record: **Clean apply expected.** `pre_activate` hook,
`tb_switch_is_usb4()`, `ADP_PCIE_CS_0`, and
`usb4_pci_port_set_ext_encapsulation()` all exist. No conflicting recent
churn in the target hunks.
**Step 6.3 — Related fixes already present?**
Record: Prior CM guide fix `54967f4177d3d` (PCIe enable order) is in
tree. This LTSSM check is **not** present. No duplicate fix found.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem criticality**
Record: `drivers/thunderbolt/` — **IMPORTANT** (peripheral driver, but
affects Thunderbolt/USB4 docking, storage, displays, networking on
laptops/workstations).
**Step 7.2 — Activity**
Record: Actively maintained; recent commits include UAF fix
(`67600ccfc4f38`), wake-on-connect fix, documentation updates.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users with USB4/Thunderbolt hardware using PCIe tunneling (docks
with PCIe slots, external GPUs, etc.). Config-specific
(`CONFIG_THUNDERBOLT`), platform-specific (systems with TB/USB4
controllers).
**Step 8.2 — Trigger conditions**
Record: USB4 router PCIe tunnel activation during hotplug/chain setup
when adapters have not yet reached LTSSM DETECT. Timing-dependent race —
more likely on slower enumeration or under load. Not unprivileged-
syscall triggered; triggered by physical plug events or resume.
**Step 8.3 — Failure mode severity**
Record:
- **Without fix:** Proceed with tunnel setup in wrong LTSSM state → PCIe
tunnel activation failure or unreliable PCIe device enumeration.
Severity: **MEDIUM-HIGH** (functional failure, no proven
crash/corruption).
- **With fix:** Wait up to 500 ms; succeed when DETECT reached, or fail
cleanly with `-ETIMEDOUT` → logged "PCIe tunnel activation failed,
aborting" in `tb.c:2298-2302`.
**Step 8.4 — Risk/benefit**
Record:
- **Benefit:** Prevents incorrect PCIe tunnel activation timing on USB4;
improves dock/eGPU reliability. Moderate-high for affected users.
- **Risk:** Low — ~75 lines, USB4-only guard, bounded wait, uses
existing hook pattern.
- **Ratio:** Benefit outweighs risk for this stable tree.
---
## Phase 9: Final Synthesis
**Evidence FOR backport:**
- Fixes a real timing bug in PCIe tunnel activation on USB4 routers
- User-visible impact: Thunderbolt PCIe devices may fail to come up
- Small, self-contained (~75 lines), maintainer-signed
- All prerequisites exist in v6.18.44; expected clean apply
- Follows established `pre_activate` pattern already used for DP/USB3
- Precedent: prior CM-guide PCIe tunnel fix (`54967f4177d3d`) already in
tree
**Evidence AGAINST backport:**
- No explicit bug report, crash trace, or syzbot finding
- Part of 8-patch CM-guide series; full fix may need companion patches
- Strict stable wording emphasizes crashes/security/corruption; this is
robustness/functional
- Commit not yet in this tree; limited soak time in this release line
**Unresolved questions:**
- Whether adapters are always expected to reach DETECT within 500 ms at
this point (maintainer assumption, not independently verified)
- Whether other series patches (4/6/7/8) are needed alongside this for
complete fix
- Full lore review thread unavailable (bot protection)
### Stable Rules Checklist
1. Obviously correct and tested? **PASS** — clear logic, maintainer-
reviewed; no `Tested-by`
2. Fixes real bug affecting users? **PASS** — timing bug in USB4 PCIe
tunnel setup
3. Important issue? **PASS (MEDIUM-HIGH)** — PCIe tunnel failure on
Thunderbolt hardware, not crash/corruption
4. Small and contained? **PASS** — ~75 lines, 4 files
5. No new features/APIs? **PASS** — internal driver helpers only
6. Can apply to local tree? **PASS** — prerequisites confirmed in
v6.18.44
### Exception category
Record: Hardware workaround / CM-guide compliance for existing USB4
Thunderbolt hardware (similar to accepted quirk/workaround category).
### Problem summary for stable users
Without this check, the driver can activate PCIe tunnels before USB4
PCIe adapters reach LTSSM DETECT, violating the USB4 CM guide
sequencing. That can cause intermittent or complete failure of PCIe
tunnel bring-up — Thunderbolt docks, eGPUs, and NVMe enclosures may not
enumerate. The fix waits up to 500 ms for the correct state and aborts
cleanly on timeout.
---
## Verification
- [Phase 1] Parsed subject, tags, body from provided commit message
- [Phase 1] Confirmed no `Fixes:`, `Reported-by:`, or stable tags
- [Phase 2] Diff analysis: 4 files, ~75 lines, pre_activate hook + LTSSM
polling
- [Phase 3] `git describe HEAD`: v6.18.44
- [Phase 3] `git blame` on `tb_tunnel_alloc_pci`: function present since
2017
- [Phase 3] `git log --grep="CM guide"`: found `54967f4177d3d` in tree
- [Phase 3] `git log` on author Gil Fine: multiple thunderbolt commits
in tree
- [Phase 3] Grep: `pre_activate` hook present since Jan 2025
(`ae765788936d9`)
- [Phase 4] `b4 dig -c HEAD`: no match (commit not in tree)
- [Phase 4] Web search: found as [PATCH 5/8], series "Make the driver
follow CM guide more closely", 2026-05-12
- [Phase 4] UNVERIFIED: Full lore thread and stable nominations (bot
protection)
- [Phase 5] Grep callers: `tb_tunnel_alloc_pci` in `tb.c:2294`,
`tb_tunnel_activate` at 6 call sites
- [Phase 5] Read `tb_tunnel_activate()`: `pre_activate` called before
path activation (lines 2395-2398)
- [Phase 5] Read `tb_tunnel_pci()`: activation failure logs and returns
`-EIO` (lines 2298-2302)
- [Phase 6] Grep: no `ltssm`/`usb4_pci_port_ltssm_state` in tree — buggy
code confirmed present
- [Phase 6] Grep: `ADP_PCIE_CS_0`,
`usb4_pci_port_set_ext_encapsulation`, `tb_switch_is_usb4` all present
- [Phase 6] Grep: series patches 4/6/7/8 not in tree
- [Phase 7] `git log -5` on thunderbolt files: active subsystem with
recent bug fixes
- [Phase 8] Failure mode: PCIe tunnel activation failure, severity
MEDIUM-HIGH
**YES**
drivers/thunderbolt/tb.h | 1 +
drivers/thunderbolt/tb_regs.h | 15 +++++++++++++++
drivers/thunderbolt/tunnel.c | 35 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/usb4.c | 24 ++++++++++++++++++++++++
4 files changed, 75 insertions(+)
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 8e2762ff8d517..775ed48cc299a 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -1478,6 +1478,7 @@ int usb4_dp_port_allocate_bandwidth(struct tb_port *port, int bw);
int usb4_dp_port_requested_bandwidth(struct tb_port *port);
int usb4_pci_port_set_ext_encapsulation(struct tb_port *port, bool enable);
+int usb4_pci_port_ltssm_state(struct tb_port *port);
static inline bool tb_is_usb4_port_device(const struct device *dev)
{
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 4e43b47f9f119..97404d8d878bf 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -473,10 +473,25 @@ struct tb_regs_port_header {
/* PCIe adapter registers */
#define ADP_PCIE_CS_0 0x00
+#define ADP_PCIE_CS_0_LTSSM_MASK GENMASK(28, 25)
#define ADP_PCIE_CS_0_PE BIT(31)
#define ADP_PCIE_CS_1 0x01
#define ADP_PCIE_CS_1_EE BIT(0)
+enum tb_pcie_ltssm_state {
+ USB4_PCIE_LTSSM_DETECT,
+ USB4_PCIE_LTSSM_POLLING,
+ USB4_PCIE_LTSSM_CONFIG,
+ USB4_PCIE_LTSSM_CONFIG_IDLE,
+ USB4_PCIE_LTSSM_RECOVERY,
+ USB4_PCIE_LTSSM_RECOVERY_IDLE,
+ USB4_PCIE_LTSSM_L0,
+ USB4_PCIE_LTSSM_L1,
+ USB4_PCIE_LTSSM_L2,
+ USB4_PCIE_LTSSM_DISABLED,
+ USB4_PCIE_LTSSM_HOT_RESET,
+};
+
/* USB adapter registers */
#define ADP_USB3_CS_0 0x00
#define ADP_USB3_CS_0_V BIT(30)
diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index bfa0607b55744..6066355388b7f 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -296,6 +296,40 @@ static inline void tb_tunnel_changed(struct tb_tunnel *tunnel)
tunnel->src_port, tunnel->dst_port);
}
+static int tb_pci_port_ltssm_state_detect(struct tb_port *port)
+{
+ ktime_t timeout = ktime_add_ms(ktime_get(), 500);
+
+ do {
+ int ret;
+
+ ret = usb4_pci_port_ltssm_state(port);
+ if (ret < 0)
+ return ret;
+ if (ret == USB4_PCIE_LTSSM_DETECT)
+ return 0;
+
+ fsleep(50);
+ } while (ktime_before(ktime_get(), timeout));
+
+ return -ETIMEDOUT;
+}
+
+static int tb_pci_pre_activate(struct tb_tunnel *tunnel)
+{
+ struct tb_port *down = tunnel->src_port;
+ struct tb_port *up = tunnel->dst_port;
+ int ret;
+
+ ret = tb_switch_is_usb4(down->sw) ?
+ tb_pci_port_ltssm_state_detect(down) : 0;
+ if (ret)
+ return ret;
+
+ return tb_switch_is_usb4(up->sw) ?
+ tb_pci_port_ltssm_state_detect(up) : 0;
+}
+
static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable)
{
struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw);
@@ -511,6 +545,7 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,
if (!tunnel)
return NULL;
+ tunnel->pre_activate = tb_pci_pre_activate;
tunnel->activate = tb_pci_activate;
tunnel->src_port = down;
tunnel->dst_port = up;
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index 76f01713a8754..276c25c7d37e6 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -3145,3 +3145,27 @@ int usb4_pci_port_set_ext_encapsulation(struct tb_port *port, bool enable)
return tb_port_write(port, &val, TB_CFG_PORT,
port->cap_adap + ADP_PCIE_CS_1, 1);
}
+
+/**
+ * usb4_pci_port_ltssm_state() - Read PCIe adapter LTSSM state
+ * @port: PCIe adapter
+ *
+ * Return:
+ * * LTSSM state of @port.
+ * * Negative errno - On failure.
+ */
+int usb4_pci_port_ltssm_state(struct tb_port *port)
+{
+ u32 val;
+ int ret;
+
+ if (!tb_port_is_pcie_down(port) && !tb_port_is_pcie_up(port))
+ return -EINVAL;
+
+ ret = tb_port_read(port, &val, TB_CFG_PORT,
+ port->cap_adap + ADP_PCIE_CS_0, 1);
+ if (ret)
+ return ret;
+
+ return FIELD_GET(ADP_PCIE_CS_0_LTSSM_MASK, val);
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] usbip: vhci_hcd: fix NULL deref in status_show_vhci
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (13 preceding siblings ...)
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] thunderbolt: Verify PCIe adapter in detect state before tunnel setup Sasha Levin
@ 2026-08-31 13:28 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Set tb->root_switch to NULL when domain is stopped Sasha Levin
` (7 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:28 UTC (permalink / raw)
To: patches, stable
Cc: Adrian Wowk, Shuah Khan, Greg Kroah-Hartman, Sasha Levin,
valentina.manea.m, shuah, linux-usb, linux-kernel
From: Adrian Wowk <dev@adrianwowk.com>
[ Upstream commit bc150783542ba2e7c1257d1299c6f3269bdba270 ]
platform_get_drvdata() can return NULL if a VHCI host controller's
probe failed (e.g. due to USB bus number exhaustion). status_show_vhci()
checked for a NULL pdev but not for a NULL hcd returned by
platform_get_drvdata(). Passing NULL to hcd_to_vhci_hcd() does not
return NULL - it returns a pointer offset of 0x260, causing a NULL
pointer dereference when that value is subsequently dereferenced.
Add a NULL check on hcd before calling hcd_to_vhci_hcd(). Move
status_show_not_ready() above status_show_vhci() to make it callable
from the new error path without a forward declaration.
Signed-off-by: Adrian Wowk <dev@adrianwowk.com>
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://patch.msgid.link/20260414010050.158064-2-dev@adrianwowk.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `usbip: vhci_hcd: fix NULL deref in
status_show_vhci`
**Local tree:** `v6.18.44` (`stable/linux-6.18.y`, `make kernelversion`
→ 6.18.44)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[usbip: vhci_hcd]` `[fix]` — NULL pointer dereference in
`status_show_vhci()` when reading VHCI sysfs status.
### Step 1.2: Tags
**Record:**
- **Signed-off-by:** Adrian Wowk, Greg Kroah-Hartman (ignore pipeline
SOB)
- **Reviewed-by:** Shuah Khan (USB/usbip maintainer)
- **Link:**
https://patch.msgid.link/20260414010050.158064-2-dev@adrianwowk.com
- No `Fixes:`, `Reported-by:`, `Cc: stable`, or `Tested-by:` tags
- Notable: maintainer review present; no syzbot report
### Step 1.3: Body analysis
**Record:**
- **Bug:** `status_show_vhci()` checks `pdev` for NULL but not `hcd`
from `platform_get_drvdata()`.
- **Trigger:** VHCI host controller probe failure (e.g. USB bus number
exhaustion); `pdev` exists but `hcd` is NULL.
- **Mechanism:** `hcd_to_vhci_hcd(NULL)` does not return NULL; it yields
a pointer at offset `0x260` into `struct usb_hcd`, then
`vhci_hcd->vhci` dereferences that address → kernel oops.
- **Symptom:** NULL pointer dereference / kernel crash on sysfs read.
- **Fix:** NULL-check `hcd`; fall back to existing
`status_show_not_ready()`; move that helper above `status_show_vhci()`
to avoid forward declaration.
### Step 1.4: Hidden bug fix?
**Record:** No — explicitly labeled and clearly a NULL-deref bug fix,
not disguised cleanup.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/usb/usbip/vhci_sysfs.c` only
- **Scope:** ~12 lines added (NULL check + debug message), function
reorder (no logic change to `status_show_not_ready`)
- **Functions:** `status_show_not_ready()` (moved up),
`status_show_vhci()` (NULL guard added)
- **Classification:** Single-file surgical fix
### Step 2.2: Code flow change
**Record:**
- **Hunk 1 (reorder):** `status_show_not_ready()` moved above
`status_show_vhci()` — behavior unchanged.
- **Hunk 2 (`status_show_vhci`):**
- **Before:** `hcd = platform_get_drvdata(pdev);` → immediate
`hcd_to_vhci_hcd(hcd)` → `vhci_hcd->vhci` (crash if `hcd == NULL`).
- **After:** If `!hcd`, log debug message and return
`status_show_not_ready(pdev_nr, out)` (safe placeholder output).
- **Path affected:** Sysfs `status` / `status.N` read when controller
probe failed.
### Step 2.3: Bug mechanism
**Record:**
- **Category:** NULL pointer dereference (memory safety)
- **Mechanism:** `hcd_to_vhci_hcd()` is:
```149:152:drivers/usb/usbip/vhci.h
static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd)
{
return (struct vhci_hcd *) (hcd->hcd_priv);
}
```
With `hcd == NULL`, `hcd->hcd_priv` is invalid; the resulting pointer
is then dereferenced at line 80 (`vhci_hcd->vhci`).
### Step 2.4: Fix quality
**Record:**
- **Quality:** High — matches the existing pattern in `attach_store()`
and `detach_store()` in the same file (lines 250–254, 344–348).
- **Regression risk:** Very low — only adds an error path using existing
helper already used from `status_show()`.
- **No red flags:** No API changes, no locking changes, no cross-
subsystem impact.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:**
- Buggy `platform_get_drvdata()` → `hcd_to_vhci_hcd()` path introduced
in **03cd00d538a6f** (2017-06-08, "usbip: vhci-hcd: Set the vhci
structure up to work").
- `pdev` NULL check added in **0775a9cbc694e** (2016-06-13, multi-
controller extension).
- `attach_store()` / `detach_store()` gained `hcd == NULL` checks in the
same **0775a9cbc694e** commit; `status_show_vhci()` was never updated
— a long-standing oversight.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag in commit message.
### Step 3.3: Related file history
**Record:**
- Recent fixes in this file: race/GPF fix (718ad9693e365, 2021),
sysfs_lock (4e9c93af7279b), stream socket check (f55a0571690c4).
- This fix is standalone; not part of a multi-patch series.
- **Prerequisites:** None identified.
### Step 3.4: Author context
**Record:** Adrian Wowk has no prior usbip commits in this tree (commit
is mainline candidate not yet merged here). Reviewed by Shuah Khan
(active usbip maintainer).
### Step 3.5: Dependencies
**Record:** No dependencies. `status_show_not_ready()` already exists in
this tree and is callable from `status_show()`.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** `b4 dig -c <commit>` not possible — commit not in local
tree. Link fetch to patch.msgid.link and lore.kernel.org blocked (Anubis
bot protection). **UNVERIFIED:** full mailing-list thread content.
### Step 4.2: Reviewers
**Record:** **UNVERIFIED** via `b4 dig -w`. Commit message documents
**Reviewed-by: Shuah Khan** and **Signed-off-by: Greg Kroah-Hartman**.
### Step 4.3: Bug report
**Record:** No external bug report or syzbot link. Bug identified by
code-path analysis (inconsistency with attach/detach NULL checks).
### Step 4.4: Related patches
**Record:** Standalone 1-file fix; no series dependency.
### Step 4.5: Stable list history
**Record:** **UNVERIFIED** — lore stable search blocked. Prior usbip
stable fixes (e.g. 718ad9693e365) included `Cc: stable@vger.kernel.org`.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `status_show_vhci()`, `status_show_not_ready()`,
`status_show()` (caller), `hcd_to_vhci_hcd()` (inline macro).
### Step 5.2: Callers
**Record:**
- `status_show_vhci()` called only from `status_show()` (line 160).
- `status_show()` registered as sysfs `.show` for `status` / `status.N`
attributes (line 471).
- User-triggered via reading `/sys/devices/platform/vhci_hdc/status` (or
`status.N`).
### Step 5.3: Callees
**Record:** `platform_get_drvdata()`, `hcd_to_vhci_hcd()`,
`spin_lock_irqsave()`, port iteration — all skipped on NULL `hcd` after
fix.
### Step 5.4: Reachability
**Record:**
- **Reachable:** Yes — any process that can read the sysfs file.
- `vhcis[pdev_nr].pdev` is set during `vhci_hcd_init()` before probe; if
`vhci_hcd_probe()` fails before `usb_create_hcd()` sets drvdata (via
`dev_set_drvdata` in `__usb_create_hcd()`), `platform_get_drvdata()`
returns NULL while `pdev` is non-NULL.
- `vhci_hcd_suspend()` already guards `if (!hcd) return 0;` (line
1452–1454), confirming NULL `hcd` is an expected state.
### Step 5.5: Similar patterns
**Record:** Same-file NULL checks already present:
```250:254:drivers/usb/usbip/vhci_sysfs.c
hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
if (hcd == NULL) {
dev_err(dev, "port is not ready %u\n", port);
return -EAGAIN;
}
```
`status_show_vhci()` was the missing case.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code present?
**Record:** **YES.** Current tree at `v6.18.44` has no `hcd` NULL check
in `status_show_vhci()` (lines 78–80). Bug present since at least 2017.
### Step 6.2: Backport complications
**Record:** **Clean apply expected** — only reorders one static function
and adds a small guard block. No conflicting recent changes to this
function.
### Step 6.3: Fix already present?
**Record:** **NO** — grep shows no `hcd is NULL` check in
`status_show_vhci()`. Fix not in this tree.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem
**Record:** `drivers/usb/usbip/` — USB/IP virtual host controller
(VHCI). **Criticality: PERIPHERAL** (optional `CONFIG_USBIP_VHCI_HCD`
module), but crash severity is high when enabled.
### Step 7.2: Activity
**Record:** Moderately active; recent fixes for races, locking, and
sysfs safety in 2021–2025.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users with `CONFIG_USBIP_VHCI_HCD` built/loaded who read
VHCI status sysfs after a controller probe failure.
### Step 8.2: Trigger conditions
**Record:**
- VHCI probe fails (ENOMEM, USB bus number exhaustion, `usb_add_hcd`
failure paths).
- User or tool reads `status` sysfs entry.
- Uncommon but realistic on systems with many USB controllers or
resource exhaustion.
- Sysfs permissions typically restrict to root; still a kernel bug worth
fixing.
### Step 8.3: Failure mode
**Record:** NULL pointer dereference → kernel oops / possible panic.
**Severity: HIGH** (crash), **breadth: LOW** (usbip VHCI users only).
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** Prevents kernel crash on sysfs read; completes parity
with attach/detach error handling.
- **Risk:** Minimal — uses existing fallback helper, reviewed by
maintainer.
- **Ratio:** Favorable for backport.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real NULL-deref bug with clear crash mechanism
- Bug present in 6.18.y since 2017; attach/detach already handle this
case
- Small, surgical, obviously correct fix
- Reviewed by Shuah Khan; signed off by Greg K-H
- Same class of fix as prior stable usbip commits (e.g. 718ad9693e365)
**AGAINST backport:**
- Affects optional `CONFIG_USBIP_VHCI_HCD` module only (narrow user
base)
- No syzbot/user report in commit message
- Trigger requires probe failure (uncommon)
**Unresolved:**
- Exact `hcd_priv` offset 0x260 not independently measured (mechanism
verified from source)
- Mailing-list thread not readable (bot protection)
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — mirrors existing in-file
pattern; maintainer reviewed.
2. Fixes a real bug? **PASS** — NULL deref on sysfs read.
3. Important issue? **PASS** — kernel oops (HIGH severity, narrow
scope).
4. Small and contained? **PASS** — single file, ~20 lines touched.
5. No new features/APIs? **PASS** — defensive error path only.
6. Can apply to local tree? **PASS** — buggy code present; clean apply
expected.
### Step 9.3: Exception categories
**Record:** N/A — standard bug fix, not a quirk/ID/DT/build/doc
exception.
### Step 9.4: Decision rationale
For **linux-6.18.y** at `v6.18.44`, the buggy code is present and
unfixed. The patch is a minimal NULL guard consistent with decade-old
attach/detach handling in the same file. It prevents a kernel oops when
users read VHCI status after probe failure. Scope is narrow (usbip VHCI
module) but the fix is low-risk and meets all stable criteria.
---
## Verification
- [Phase 1] Parsed subject, tags, body from provided commit message
- [Phase 2] Read current `vhci_sysfs.c` and `vhci.h`; confirmed missing
NULL check and `hcd_to_vhci_hcd` macro behavior
- [Phase 3] `git describe HEAD` → v6.18.44; `git blame` on lines 63–95 →
bug since 03cd00d538a6f (2017)
- [Phase 3] `git show 0775a9cbc694e` → attach/detach had `hcd == NULL`
checks since 2016; status_show_vhci did not
- [Phase 3] `git log --oneline -20 -- drivers/usb/usbip/vhci_sysfs.c` →
no duplicate fix
- [Phase 4] `b4 dig` failed (commit not in tree); lore/patch.msgid.link
blocked by Anubis — **UNVERIFIED** thread content
- [Phase 4] Reviewed-by Shuah Khan and Greg K-H SOB taken from commit
message only
- [Phase 5] Grep callers: `status_show_vhci` called only from
`status_show()`; sysfs `.show` at line 471
- [Phase 5] Verified attach/detach NULL checks at lines 250–254, 344–348
- [Phase 5] Read `vhci_hcd_probe()` and `vhci_hcd_suspend()` NULL-hcd
handling
- [Phase 5] Read `__usb_create_hcd()` — `dev_set_drvdata(dev, hcd)` at
hcd.c:2589 for primary HCD
- [Phase 6] `make kernelversion` → 6.18.44; buggy code confirmed at
lines 78–80
- [Phase 6] No existing fix in tree
- [Phase 8] CONFIG dependency: `USBIP_VHCI_HCD` in
`drivers/usb/usbip/Kconfig`
- **UNVERIFIED:** Exact 0x260 byte offset of `hcd_priv` (stated in
commit message; macro mechanism confirmed)
**YES**The background git searches finished and match what the earlier
analysis already found:
- **Fix in history:** No commit for `usbip: vhci_hcd: fix NULL deref in
status_show_vhci` in this tree — the bug is still present in
`v6.18.44`.
- **Author search:** Adrian Wowk has no usbip commits here (this is a
mainline candidate). The only `hcd is NULL` hit was an unrelated `usb:
chipidea` merge from 2013.
**Verdict unchanged: YES** — small, low-risk NULL-deref fix for sysfs
status reads when VHCI probe fails; worth backporting to `linux-6.18.y`.
drivers/usb/usbip/vhci_sysfs.c | 52 +++++++++++++++++++---------------
1 file changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index d5865460e82d5..336fb4d92c6f5 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -59,6 +59,29 @@ static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vd
*out += sprintf(*out, "\n");
}
+static ssize_t status_show_not_ready(int pdev_nr, char *out)
+{
+ char *s = out;
+ int i = 0;
+
+ for (i = 0; i < VHCI_HC_PORTS; i++) {
+ out += sprintf(out, "hs %04u %03u ",
+ (pdev_nr * VHCI_PORTS) + i,
+ VDEV_ST_NOTASSIGNED);
+ out += sprintf(out, "000 00000000 0000000000000000 0-0");
+ out += sprintf(out, "\n");
+ }
+
+ for (i = 0; i < VHCI_HC_PORTS; i++) {
+ out += sprintf(out, "ss %04u %03u ",
+ (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
+ VDEV_ST_NOTASSIGNED);
+ out += sprintf(out, "000 00000000 0000000000000000 0-0");
+ out += sprintf(out, "\n");
+ }
+ return out - s;
+}
+
/* Sysfs entry to show port status */
static ssize_t status_show_vhci(int pdev_nr, char *out)
{
@@ -76,6 +99,12 @@ static ssize_t status_show_vhci(int pdev_nr, char *out)
}
hcd = platform_get_drvdata(pdev);
+
+ if (!hcd) {
+ usbip_dbg_vhci_sysfs("show status error (hcd is NULL)\n");
+ return status_show_not_ready(pdev_nr, out);
+ }
+
vhci_hcd = hcd_to_vhci_hcd(hcd);
vhci = vhci_hcd->vhci;
@@ -104,29 +133,6 @@ static ssize_t status_show_vhci(int pdev_nr, char *out)
return out - s;
}
-static ssize_t status_show_not_ready(int pdev_nr, char *out)
-{
- char *s = out;
- int i = 0;
-
- for (i = 0; i < VHCI_HC_PORTS; i++) {
- out += sprintf(out, "hs %04u %03u ",
- (pdev_nr * VHCI_PORTS) + i,
- VDEV_ST_NOTASSIGNED);
- out += sprintf(out, "000 00000000 0000000000000000 0-0");
- out += sprintf(out, "\n");
- }
-
- for (i = 0; i < VHCI_HC_PORTS; i++) {
- out += sprintf(out, "ss %04u %03u ",
- (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
- VDEV_ST_NOTASSIGNED);
- out += sprintf(out, "000 00000000 0000000000000000 0-0");
- out += sprintf(out, "\n");
- }
- return out - s;
-}
-
static int status_name_to_id(const char *name)
{
char *c;
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] thunderbolt: Set tb->root_switch to NULL when domain is stopped
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (14 preceding siblings ...)
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18-5.10] usbip: vhci_hcd: fix NULL deref in status_show_vhci Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Don't disable lane adapter if XDomain lane bonding isn't possible Sasha Levin
` (6 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit e56249d8a68e712f3b60e1f3fdbb5b4fea146468 ]
Similarly what we do with the firmware connection manager. This makes
tb_xdp_handle_request() return error to the remote host. However, we
need to make sure we keep the uuid alive so that we can reply until the
whole domain is released.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background `git branch -a --contains` lookup timed out — this repo
has too many branches for that to finish quickly.
The analysis itself is complete. **Verdict: YES** for backport to this
tree (`linux-6.18.y` at v6.18.43).
The fix is missing from your current checkout and from
`stable/linux-6.18.y`, but is already present in mainline
(`origin/master`). It's a small teardown fix: `tb_stop()` leaves a
dangling `tb->root_switch` after switch removal, which can cause a UAF
crash when in-flight XDomain request work runs during driver unload. The
patch mirrors what `icm_stop()` already does and applies cleanly
here.The `git branch -a --contains e56249d8a68e7` lookup timed out again
— too many branches in this repo for that to finish in a reasonable
time.
I checked the important branches directly instead: the fix is **not** in
your current `6.18.43` checkout or `stable/linux-6.18.y`, but **is** in
`origin/master`. That supports the earlier **YES** backport verdict.
drivers/thunderbolt/tb.c | 1 +
drivers/thunderbolt/xdomain.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 041a4c8e10fb9..b516b1ad83a19 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -2952,6 +2952,7 @@ static void tb_stop(struct tb *tb)
tb_tunnel_put(tunnel);
}
tb_switch_remove(tb->root_switch);
+ tb->root_switch = NULL;
tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */
}
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index fed0fae2a6299..1eb149445fa05 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -756,7 +756,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
mutex_lock(&tb->lock);
if (tb->root_switch)
- uuid = tb->root_switch->uuid;
+ uuid = kmemdup(tb->root_switch->uuid, sizeof(*uuid), GFP_KERNEL);
else
uuid = NULL;
mutex_unlock(&tb->lock);
@@ -870,6 +870,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
}
out:
+ kfree(uuid);
kfree(xw->pkg);
kfree(xw);
@@ -2344,6 +2345,9 @@ static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,
{
struct tb_port *port;
+ if (!sw)
+ return NULL;
+
tb_switch_for_each_port(sw, port) {
struct tb_xdomain *xd;
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.12] thunderbolt: Don't disable lane adapter if XDomain lane bonding isn't possible
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (15 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Set tb->root_switch to NULL when domain is stopped Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] usb: host: add ARCH_AIROHA in XHCI MTK dependency Sasha Levin
` (5 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit 7c7345bcde6c611fa8fa13e624207c6005798aa8 ]
This happens when firmware connection manager is being used. It will
deal with disabling the lane 1 adapter after the tunnel has been
established and re-enabling it afterwards. For this reason only do this
when we know that lane bonding is possible (e.g running software
connection manager).
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background `git log --all` search was killed — it was hanging on
this repo, as expected.
A follow-up `git log -S 'tb_xdomain_link_exit'` (without `--all`)
finished after ~48s, but the hits (`19eef1d98eeda`, `ac3fd01e4c1ef`) are
base-import commits, not a clean “introduced in commit X” answer. That’s
normal on this 6.18.y tree where history is squashed.
The backport analysis doesn’t depend on that: the buggy
`tb_xdomain_link_exit()` path is present in 6.18.43, and the verdict
remains **YES**.
drivers/thunderbolt/xdomain.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index 6b16fc7254b8e..b27ef872edeac 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -1951,7 +1951,13 @@ static void tb_xdomain_link_exit(struct tb_xdomain *xd)
if (tb_port_get_link_generation(down) >= 4) {
down->bonded = false;
down->dual_link_port->bonded = false;
- } else if (xd->link_width > TB_LINK_WIDTH_SINGLE) {
+ return;
+ }
+
+ if (!xd->bonding_possible)
+ return;
+
+ if (xd->link_width > TB_LINK_WIDTH_SINGLE) {
/*
* Just return port structures back to way they were and
* update credits. No need to update userspace because
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] usb: host: add ARCH_AIROHA in XHCI MTK dependency
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (16 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Don't disable lane adapter if XDomain lane bonding isn't possible Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] USB: cdc-acm: start bulk-IN polling when ALWAYS_POLL_CTRL is set Sasha Levin
` (4 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Christian Marangi, Greg Kroah-Hartman, Sasha Levin, linux-usb,
linux-kernel
From: Christian Marangi <ansuelsmth@gmail.com>
[ Upstream commit ffeaf31f05d664581aa436d9cb92b4d1d8d301ce ]
Airoha SoC use the same register map and logic of the Mediatek xHCI
driver, hence add it to the dependency list to permit compilation also
on this ARCH.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Link: https://patch.msgid.link/20260519164903.31258-1-ansuelsmth@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `usb: host: add ARCH_AIROHA in XHCI MTK
dependency`
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Parse the Subject Line
**Record:** `[usb: host]` `[add]` — Add `ARCH_AIROHA` to the Kconfig
dependency list for `USB_XHCI_MTK` so the MediaTek xHCI driver can be
selected when building for Airoha SoCs.
### Step 1.2: Parse All Commit Message Tags
**Record:**
- **Signed-off-by:** Christian Marangi `<ansuelsmth@gmail.com>` (author)
- **Link:**
https://patch.msgid.link/20260519164903.31258-1-ansuelsmth@gmail.com
- **Signed-off-by:** Greg Kroah-Hartman `<gregkh@linuxfoundation.org>`
(USB maintainer acceptance)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable@vger.kernel.org`
- Notable: USB maintainer sign-off; no bug report or syzbot involvement
### Step 1.3: Analyze Commit Body
**Record:**
- **Bug described:** Airoha SoCs reuse the MediaTek xHCI register map
and logic, but `USB_XHCI_MTK` Kconfig does not list `ARCH_AIROHA` in
its `depends on`, so the driver cannot be enabled on Airoha platform
builds.
- **Symptom:** Kconfig hides/unselectable `CONFIG_USB_XHCI_MTK` when
`CONFIG_ARCH_AIROHA=y`; kernel builds for Airoha cannot compile in the
xhci-mtk driver without `COMPILE_TEST` workarounds.
- **Version info:** None stated.
- **Root cause:** Kconfig dependency oversight — platform added without
updating all reused Mediatek IP driver dependencies.
### Step 1.4: Detect Hidden Bug Fixes
**Record:** Not disguised as cleanup. This is an explicit
**Kconfig/build dependency fix**. It falls under the stable “build fix”
exception category rather than a runtime crash fix.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory the Changes
**Record:**
- **Files:** `drivers/usb/host/Kconfig` — 1 line changed (+1 token in
`depends on`)
- **Functions modified:** None (Kconfig only)
- **Scope:** Single-file, surgical Kconfig change
### Step 2.2: Code Flow Change
**Record:**
- **Hunk (USB_XHCI_MTK depends):**
- **Before:** `depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK ||
COMPILE_TEST`
- **After:** `depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK ||
ARCH_AIROHA || COMPILE_TEST`
- **Path affected:** Kernel configuration time only; no runtime code
path changes.
### Step 2.3: Bug Mechanism
**Record:**
- **Category:** Build/configuration fix (Kconfig dependency)
- **Mechanism:** `ARCH_AIROHA` builds satisfy none of the original
dependencies (unless `COMPILE_TEST`), so `USB_XHCI_MTK` is
unavailable. Adding `ARCH_AIROHA` aligns this driver with other
Mediatek-derived drivers already enabled for Airoha (PCIe, pinctrl,
clk, gpio, ethernet, etc.).
### Step 2.4: Fix Quality Assessment
**Record:**
- **Quality:** Obviously correct; mirrors the established pattern used
for `PCIE_MEDIATEK` (`b3b76fc86f0fb`, 2022).
- **Regression risk:** Very low — only makes an existing tristate option
visible/selectable on `ARCH_AIROHA`; does not auto-enable anything.
- **Red flags:** None.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame the Changed Lines
**Record:**
- `USB_XHCI_MTK` `depends on` line introduced by John Crispin,
2016-12-20 (`808cf33d4817c7`), as `(MIPS && SOC_MT7621) ||
ARCH_MEDIATEK || COMPILE_TEST`.
- `ARCH_AIROHA` added to this tree in `428ae88ef519f` (merged May 2024):
“arm64: add Airoha EN7581 platform”.
- **Bug introduced:** When `ARCH_AIROHA` was added (~6.9 timeframe);
xhci-mtk dependency was never updated.
### Step 3.2: Follow Fixes Tag
**Record:** No `Fixes:` tag present. N/A.
### Step 3.3: Related File History
**Record:**
- `git log -S'ARCH_AIROHA' -- drivers/usb/host/Kconfig` returns empty —
`ARCH_AIROHA` was never added to this file.
- Precedent: `b3b76fc86f0fb` “PCI: mediatek: Allow building for
ARCH_AIROHA” — identical rationale and pattern.
- Standalone one-commit fix; not part of a series.
### Step 3.4: Author's Other Commits
**Record:** Christian Marangi is an active Airoha/Mediatek platform
contributor (net/airoha fixes visible in tree). This patch is consistent
with ongoing Airoha platform enablement work.
### Step 3.5: Prerequisites
**Record:**
- **Requires:** `ARCH_AIROHA` Kconfig symbol — **present** in this tree
(`arch/arm64/Kconfig.platforms`, `arch/arm/Kconfig.platforms`).
- **Requires:** `USB_XHCI_MTK` driver — **present**
(`drivers/usb/host/xhci-mtk.c`).
- **Standalone:** Yes; no other commits required.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original Patch Discussion
**Record:** `b4 dig -c <commit>` could not be run (commit not in local
tree). Lore fetch blocked (403/Anubis bot protection). Link tag points
to linux-usb list submission from 2026-05-19. **UNVERIFIED:** Full
review thread content.
### Step 4.2: Reviewers
**Record:** Greg Kroah-Hartman Signed-off-by confirms USB maintainer
acceptance. **UNVERIFIED:** Full recipient list via `b4 dig -w`.
### Step 4.3: Bug Report
**Record:** No external bug report referenced. Issue inferred from
platform/Kconfig mismatch.
### Step 4.4: Related Patches/Series
**Record:** Part of broader Airoha platform enablement; similar Kconfig
updates already landed for PCIe, pinctrl, clk, gpio, ethernet, etc. No
multi-patch series dependency.
### Step 4.5: Stable Mailing List
**Record:** **UNVERIFIED** — could not search lore stable list due to
access restrictions.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key Functions Modified
**Record:** None — Kconfig symbol `USB_XHCI_MTK` dependency only.
### Step 5.2: Callers
**Record:** Kconfig evaluated at build configuration time. `xhci-mtk`
driver probe is triggered by device tree `compatible = "mediatek,mtk-
xhci"` (and variants) via `xhci-mtk.c` platform driver table. No Airoha
USB DT nodes in mainline DTS yet, but en7581 reset/clock bindings
include USB host reset lines (`EN7581_USB_HOST_P0_RST`, etc.).
### Step 5.3: Callees
**Record:** N/A for Kconfig change.
### Step 5.4: Call Chain / Reachability
**Record:** Affects developers/distro builders configuring kernels with
`CONFIG_ARCH_AIROHA=y`. Not a userspace-triggerable runtime bug, but
blocks building USB host support for Airoha hardware using the existing
xhci-mtk driver.
### Step 5.5: Similar Patterns
**Record:** Multiple drivers in this tree already use `ARCH_AIROHA` in
Kconfig:
- `drivers/pci/controller/Kconfig` — `PCIE_MEDIATEK`,
`PCIE_MEDIATEK_GEN3`
- `drivers/pinctrl/mediatek/Kconfig`
- `drivers/clk/Kconfig`
- `drivers/gpio/Kconfig`
- `drivers/net/ethernet/mediatek/Kconfig`
- `drivers/net/ethernet/airoha/Kconfig`
USB xhci-mtk is the outlier missing this dependency.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Does the Buggy Code Exist?
**Record:** **YES.** Local tree is **v6.18.44** (`VERSION=6`,
`PATCHLEVEL=18`, `SUBLEVEL=44`). Current `drivers/usb/host/Kconfig` line
74:
```74:74:drivers/usb/host/Kconfig
depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST
```
`ARCH_AIROHA` is enabled in `arch/arm64/configs/defconfig` (line 37).
The commit under review is **not yet applied** to this tree.
### Step 6.2: Backport Complications
**Record:** `git apply --check` confirms the patch applies **cleanly**
to the local tree. No conflicts expected.
### Step 6.3: Related Fixes Already Present?
**Record:** `PCIE_MEDIATEK` ARCH_AIROHA dependency fix (`b3b76fc86f0fb`)
is already in tree. No duplicate xhci-mtk ARCH_AIROHA fix found.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem Criticality
**Record:** **drivers/usb/host** — IMPORTANT (USB host support), but fix
is config-only for a platform-specific (Airoha) subset.
### Step 7.2: Subsystem Activity
**Record:** xhci-mtk actively maintained (recent fixes in 2024–2025 for
isoc/split scheduling). Airoha platform actively developed since 2024.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who Is Affected
**Record:** **Platform-specific** — kernel builders and users of Airoha
EN7581/EN7523 SoCs (routers/embedded). `CONFIG_ARCH_AIROHA=y` is in
arm64 defconfig.
### Step 8.2: Trigger Conditions
**Record:** Building a kernel with `CONFIG_ARCH_AIROHA=y` and attempting
to enable `CONFIG_USB_XHCI_MTK`. Common for platform bring-up; not
triggered by unprivileged users at runtime.
### Step 8.3: Failure Mode Severity
**Record:** **Build/configuration failure** — cannot select/build xhci-
mtk for Airoha. Severity: **LOW** for general users, **MEDIUM** for
Airoha platform developers. Not a crash, security issue, or data
corruption.
### Step 8.4: Risk-Benefit Ratio
**Record:**
- **Benefit:** Unblocks USB host driver compilation for Airoha;
completes Kconfig parity with other Mediatek-IP drivers; zero-cost for
non-Airoha users.
- **Risk:** Minimal — one Kconfig token, no code change, no behavior
change unless user explicitly enables the option.
- **Ratio:** Favorable for Airoha platform support in a tree that
already ships `ARCH_AIROHA`.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence Summary
**FOR backport:**
- Real Kconfig bug in v6.18.44 — `ARCH_AIROHA` present but xhci-mtk
dependency missing
- Build-fix exception explicitly covers Kconfig dependency fixes
- 1-line, obviously correct, applies cleanly
- Identical precedent already in tree (`PCIE_MEDIATEK` + `ARCH_AIROHA`)
- USB maintainer (Greg K-H) sign-off
- Airoha hardware has USB-related reset/clock infrastructure in tree
- Many sibling Mediatek drivers already include `ARCH_AIROHA`
**AGAINST backport:**
- No runtime crash or security impact
- No USB device-tree nodes for Airoha in mainline yet — limited
immediate user impact
- Niche embedded platform
- No explicit bug report or stable nomination found
**UNRESOLVED:**
- Full mailing list review thread (lore access blocked)
- Whether stable maintainers already discussed this
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — trivial Kconfig alignment;
Greg K-H SOB
2. Fixes a real bug affecting users? **PASS** — real Kconfig/build
blocker for Airoha builders
3. Important issue? **PASS (borderline)** — build fix for platform
already in tree; not crash-level but blocks hardware enablement
4. Small and contained? **PASS** — 1 line, 1 file
5. No new features or APIs? **PASS** — exposes existing driver to
existing arch; no new code
6. Can apply to local tree? **PASS** — applies cleanly; all
prerequisites present
### Step 9.3: Exception Category
**Record:** **BUILD FIX** — Kconfig dependency correction to permit
compilation on `ARCH_AIROHA`.
### Step 9.4: Decision Rationale
This tree (v6.18.44) already supports `ARCH_AIROHA` in defconfig and has
extensive Airoha platform infrastructure, including Mediatek-derived
PCIe, clock, pinctrl, and ethernet drivers with `ARCH_AIROHA`
dependencies. The xhci-mtk Kconfig omission is a clear oversight that
prevents building USB host support on this platform using the existing
driver — the same class of fix that was backported for `PCIE_MEDIATEK`
years ago. The change is minimal, zero-risk at runtime, and directly
relevant to this tree.
---
## Verification
- **[Phase 1]** Parsed commit message and tags from user-provided diff
- **[Phase 1]** Confirmed no `Fixes:`, `Reported-by:`, syzbot, or stable
tags
- **[Phase 2]** Verified diff is 1-line Kconfig change in `USB_XHCI_MTK
depends on`
- **[Phase 3]** `git describe HEAD` → v6.18.44; `make kernelversion`
equivalent via Makefile → 6.18.44
- **[Phase 3]** `git blame -L 71,78 drivers/usb/host/Kconfig` → depends
line from 2016; never updated for Airoha
- **[Phase 3]** `git log --oneline -1 428ae88ef519f` → ARCH_AIROHA added
March 2024, merged May 2024
- **[Phase 3]** `git show b3b76fc86f0fb` → PCI mediatek ARCH_AIROHA
precedent confirmed
- **[Phase 3]** `git log -S'ARCH_AIROHA' -- drivers/usb/host/Kconfig` →
empty (fix not present)
- **[Phase 4]** `b4 dig` requires commit in tree — not usable;
**UNVERIFIED** lore thread
- **[Phase 4]** WebFetch/curl to lore → blocked (403/Anubis)
- **[Phase 5]** `grep ARCH_AIROHA drivers/*/Kconfig` → 15+ drivers
already include ARCH_AIROHA; USB_XHCI_MTK does not
- **[Phase 5]** Read `drivers/usb/host/xhci-mtk.c` compatible table —
uses `mediatek,mtk-xhci` variants
- **[Phase 5]** Read `en7581.dtsi` — no USB nodes yet; reset headers
include USB host resets
- **[Phase 6]** Read current `drivers/usb/host/Kconfig` line 74 —
missing ARCH_AIROHA
- **[Phase 6]** `grep ARCH_AIROHA arch/arm64/configs/defconfig` →
CONFIG_ARCH_AIROHA=y
- **[Phase 6]** `git apply --check` with provided diff → applies cleanly
(exit 0)
- **[Phase 6]** `grep PCIE_MEDIATEK arch/arm64/configs/defconfig` →
CONFIG_PCIE_MEDIATEK_GEN3=m (Airoha PCIe already enabled)
- **[Phase 8]** Failure mode: Kconfig unselectable driver on ARCH_AIROHA
builds; severity LOW-MEDIUM
**YES**The background git search finished: the commit isn’t in this tree
yet — no matches for the subject, “XHCI MTK dependency,” or Christian
Marangi changes under `drivers/usb/host/Kconfig`.
That matches what we already saw: `drivers/usb/host/Kconfig` still lacks
`ARCH_AIROHA` in the `USB_XHCI_MTK` dependency, and the patch applies
cleanly to v6.18.44.
**Verdict for this tree: YES** — one-line Kconfig build fix so Airoha
builds can enable the existing xhci-mtk driver, same pattern as the PCI
Mediatek `ARCH_AIROHA` dependency fix already in tree.
drivers/usb/host/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index c4f17ce5c77b1..87103b868032d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -71,7 +71,7 @@ config USB_XHCI_HISTB
config USB_XHCI_MTK
tristate "xHCI support for MediaTek SoCs"
select MFD_SYSCON
- depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST
+ depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || ARCH_AIROHA || COMPILE_TEST
help
Say 'Y' to enable the support for the xHCI host controller
found in MediaTek SoCs.
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.1] USB: cdc-acm: start bulk-IN polling when ALWAYS_POLL_CTRL is set
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (17 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] usb: host: add ARCH_AIROHA in XHCI MTK dependency Sasha Levin
@ 2026-08-31 13:30 ` Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add MeiG SRM813Q Sasha Levin
` (3 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:30 UTC (permalink / raw)
To: patches, stable
Cc: Dave Carey, Greg Kroah-Hartman, Sasha Levin, oneukum, linux-usb,
linux-kernel
From: Dave Carey <carvsdriver@gmail.com>
[ Upstream commit e5ab27ddd74e2d67a94c51c6f2ad87b1ff13912b ]
The INGENIC 17EF:6161 touchscreen composite device has a ~55-second
watchdog that resets the USB device if the bulk-IN endpoint on the CDC
data interface goes unread. The existing ALWAYS_POLL_CTRL quirk keeps
the notification endpoint (ctrlurb / EP 0x82) polling continuously, but
that alone is insufficient: the firmware monitors bulk-IN activity, not
just notification-endpoint activity.
Add acm_submit_read_urbs() calls to the two ALWAYS_POLL_CTRL paths that
already restart the ctrlurb:
1. acm_probe(): start bulk reads at probe time alongside the ctrlurb,
so the watchdog is satisfied from first bind without requiring a
userspace process to open /dev/ttyACMn.
2. acm_port_shutdown(): restart bulk reads after port close alongside
the ctrlurb restart, so the watchdog keeps running when the last
TTY user closes the port.
acm_read_bulk_callback() already resubmits each URB unconditionally on
normal completion, so once submitted the reads remain active until an
explicit kill (disconnect, suspend). acm_submit_read_urb() is a no-op
for URBs that are already in flight (read_urbs_free bit clear), so the
existing acm_port_activate() call remains correct and races are avoided.
Tested on Lenovo Yoga Book 9 14IAH10 (83KJ): without this patch the
device resets every ~55 s when no TTY is open; with it the device
remains stable indefinitely.
Signed-off-by: Dave Carey <carvsdriver@gmail.com>
Link: https://patch.msgid.link/20260515141940.751397-1-carvsdriver@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background searches finished and match the earlier analysis:
- **`git log --grep="start bulk-IN polling"` /
`--grep="ALWAYS_POLL_CTRL"`** only turned up the prerequisite Yoga
Book quirk commits (`5d29d7ff8679e`, `625153b917bc4`), not the bulk-IN
polling fix.
- **`git log --grep="bulk-IN polling"` / `--grep="start bulk"`** found
no matching fix commit in this tree.
So the patch under review is **not present in 6.18.44**; the incomplete
`ALWAYS_POLL_CTRL` behavior is still there. The backport recommendation
remains **YES** — it completes the quirk already in this tree.
drivers/usb/class/cdc-acm.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 12f9fe62199ba..d6a2f1591460a 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -797,6 +797,9 @@ static void acm_port_shutdown(struct tty_port *port)
"ctrl polling restart failed after port close\n");
/* port_shutdown() cleared DTR/RTS; restore them */
acm_set_control(acm, USB_CDC_CTRL_DTR | USB_CDC_CTRL_RTS);
+ if (acm_submit_read_urbs(acm, GFP_KERNEL))
+ dev_dbg(&acm->control->dev,
+ "read urb restart failed after port close\n");
}
}
@@ -1564,6 +1567,9 @@ static int acm_probe(struct usb_interface *intf,
if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL))
dev_warn(&intf->dev,
"failed to start persistent ctrl polling\n");
+ if (acm_submit_read_urbs(acm, GFP_KERNEL))
+ dev_warn(&intf->dev,
+ "failed to start persistent bulk read polling\n");
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add MeiG SRM813Q
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (18 preceding siblings ...)
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] USB: cdc-acm: start bulk-IN polling when ALWAYS_POLL_CTRL is set Sasha Levin
@ 2026-08-31 13:30 ` Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep the domain reference while processing hotplug Sasha Levin
` (2 subsequent siblings)
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:30 UTC (permalink / raw)
To: patches, stable
Cc: Jan Volckaert, Jakub Kicinski, Sasha Levin, bjorn, andrew+netdev,
davem, edumazet, pabeni, netdev, linux-usb, linux-kernel
From: Jan Volckaert <janvolck@gmail.com>
[ Upstream commit 9758c11fc6c138a79a28a5659feeaa3abde7aa6a ]
Add support for the Qualcomm Technology Snapdragon X35-based MeiG SRM813Q
module.
The module can be put in different modes via AT commands
to enable/disable GPS functionality:
MODEM - PPP mode(2dee:4d63): AT+SER=1,1
If#= 0: RMNET
If#= 1: DIAG/ADB
If#= 2: MODEM
If#= 3: AT
P: Vendor=2dee ProdID=4d63 Rev=05.15
S: Manufacturer=MEIG
S: Product=LTE-A Module
S: SerialNumber=1bd51f0e
C: #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
NMEA mode(2dee:4d64): AT+SER=51,1
If#= 0: RMNET
If#= 1: DIAG/ADB
If#= 2: NMEA
If#= 3: AT
P: Vendor=2dee ProdID=4d64 Rev=05.15
S: Manufacturer=MEIG
S: Product=LTE-A Module
S: SerialNumber=1bd51f0e
C: #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
Signed-off-by: Jan Volckaert <janvolck@gmail.com>
Link: https://patch.msgid.link/20260517153237.55995-2-janvolck@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:
## Phase 1: Commit Message Forensics
### Step 1.1: Subject Line
**Record:** `[net: usb: qmi_wwan]` `[add]` — Add USB device ID table
entries for the MeiG SRM813Q LTE modem (Snapdragon X35-based) to the
existing `qmi_wwan` driver.
### Step 1.2: Commit Message Tags
**Record:**
- **Fixes:** — not present (expected for manual review)
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by:** — none
- **Acked-by:** — none
- **Link:**
`https://patch.msgid.link/20260517153237.55995-2-janvolck@gmail.com`
(patch 2/2 in series)
- **Cc: stable@vger.kernel.org** — not present on this commit (the
companion `option.c` patch in this tree does have it)
- **Signed-off-by:** Jan Volckaert `<janvolck@gmail.com>` (author),
Jakub Kicinski `<kuba@kernel.org>` (netdev maintainer)
- **Notable:** Maintainer sign-off from Jakub Kicinski; detailed
`lsusb`-style descriptors for two USB product IDs (`2dee:4d63`,
`2dee:4d64`); patch 2 of 2 (companion is `USB: serial: option: add
MeiG SRM813Q`)
### Step 1.3: Commit Body Analysis
**Record:**
- **Bug description:** Not a kernel crash/corruption bug. The MeiG
SRM813Q modem exposes its RMNET/QMI data interface on USB interface #0
(`Prot=50`, driver `qmi_wwan`), but without table entries the kernel
will not bind `qmi_wwan` to this device.
- **Symptom:** Users with this modem get no `wwan0`/RMNET network
interface; cellular data does not work. Serial/DIAG/AT ports are
handled separately by the `option` driver.
- **Root cause:** Missing `usb_device_id` entries in `qmi_wwan.c` for
vendor `0x2dee`, products `0x4d63` (Modem/PPP mode) and `0x4d64` (NMEA
mode).
- **Version info:** None stated; hardware is new (Snapdragon X35, USB
3.20).
### Step 1.4: Hidden Bug Fix Detection
**Record:** Not a hidden bug fix. This is explicit **hardware
enablement** — a new device ID addition to an existing driver. No error-
path, locking, refcount, or memory-safety changes.
---
## Phase 2: Diff Analysis
### Step 2.1: Change Inventory
**Record:**
- **Files:** `drivers/net/usb/qmi_wwan.c` — +2 lines
- **Functions modified:** `products[]` USB device ID table only (static
data, no function body changes)
- **Scope:** Single-file, surgical device ID addition
### Step 2.2: Code Flow Change
**Record:**
- **Hunk (products[] table):** Before → device not matched by
`qmi_wwan`; QMI interface #0 left unbound. After → `qmi_wwan` binds to
interface #0 for `2dee:4d63` and `2dee:4d64`, using
`QMI_QUIRK_SET_DTR` (same pattern as Quectel, SIMCom, u-blox entries
on interface 0).
- **Execution path:** USB device enumeration / driver probe at plug-in
time.
### Step 2.3: Bug Mechanism
**Record:** Category **h) Hardware workarounds / device ID addition**.
Without entries, `qmi_wwan` never probes the RMNET interface. The
`QMI_QUIRK_SET_DTR` flag ensures proper DTR/power management during bind
(consistent with other Qualcomm-based modems lacking auto-DTR).
### Step 2.4: Fix Quality
**Record:** Obviously correct — interface #0 confirmed by commit message
`lsusb` output (`Driver=qmi_wwan` on `If#= 0`). Minimal change.
Regression risk very low: only affects devices with these specific
VID/PID pairs that currently have no `qmi_wwan` binding at all.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame
**Record:** Insertion point is immediately after
`{QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}` (MeiG SRM825L), introduced by
commit `1ca645a2f74a4` (Aug 2024). The SRM813Q entries are new; no pre-
existing buggy code to blame.
### Step 3.2: Fixes: Tag
**Record:** Not applicable — no `Fixes:` tag.
### Step 3.3: Related File History
**Record:** Recent `qmi_wwan.c` changes in this tree are predominantly
similar device-ID additions (Telit, Quectel, Fibocom, MeiG SRM825L). The
companion `option.c` patch (`38ba1a464c0d1`, upstream `7d2b37d3e42d`) is
**already present** in this tree. The `qmi_wwan` half is **not yet** in
this tree — creating a half-enabled state for SRM813Q users.
### Step 3.4: Author Context
**Record:** Jan Volckaert submitted the companion `option.c` patch
(already merged here with `Cc: stable@vger.kernel.org`). Jakub Kicinski
(netdev maintainer) signed off on the `qmi_wwan` patch per commit
message.
### Step 3.5: Dependencies
**Record:** Part of a 2-patch series with `USB: serial: option: add MeiG
SRM813Q`. The `option` half is already in v6.18.44. This `qmi_wwan`
patch is standalone (applies independently) but functionally completes
modem support. No structural/API prerequisites beyond existing
`QMI_QUIRK_SET_DTR` macro and `qmi_wwan` driver.
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Discussion
**Record:** Link points to `20260517153237.55995-2-janvolck@gmail.com`
(patch 2/2). `b4 dig -c` could not match this commit (not yet in local
git). `WebFetch` and `curl` to lore.kernel.org returned 403/bot
protection — discussion content **unverified**. Patch series structure
(2/2) confirmed from message ID.
### Step 4.2: Reviewers
**Record:** UNVERIFIED via b4 (commit not in tree). Jakub Kicinski
Signed-off-by confirms netdev maintainer acceptance.
### Step 4.3: Bug Report
**Record:** No external bug report, syzbot, or user crash report.
Hardware enablement driven by author testing with physical device
(`lsusb` descriptors provided).
### Step 4.4: Related Patches
**Record:** Patch 1/2 (`option.c`, commit `38ba1a464c0d1`) already in
v6.18.44 with `Cc: stable@vger.kernel.org`. This patch 2/2 completes
RMNET data path support.
### Step 4.5: Stable List History
**Record:** UNVERIFIED (lore access blocked). Companion `option.c` patch
explicitly nominated for stable in this tree.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** Only `products[]` static table modified. Probe/bind handled
by existing `qmi_wwan_probe()` → `qmi_wwan_bind()`.
### Step 5.2: Callers
**Record:** USB core calls `qmi_wwan` probe during device enumeration
when VID/PID/interface match `products[]`. Standard hot-plug path for
USB modems.
### Step 5.3: Callees
**Record:** On bind with `QMI_QUIRK_SET_DTR`, existing code calls
`qmi_wwan_manage_power()` and `qmi_wwan_change_dtr()` — well-established
path for Qualcomm modems.
### Step 5.4: Reachability
**Record:** Triggered by plugging in MeiG SRM813Q USB modem. Common user
operation for cellular connectivity. Not syscall-triggered, but standard
device hotplug.
### Step 5.5: Similar Patterns
**Record:** Dozens of identical-pattern entries in `products[]` (e.g.,
`QMI_QUIRK_SET_DTR(0x2c7c, ...)`, `QMI_FIXED_INTF(0x2dee, 0x4d22, 5)`
for sibling MeiG SRM825L). Telit/Quectel additions in this tree
routinely carry `Cc: stable@vger.kernel.org`.
---
## Phase 6: Cross-Reference Against Local Tree (v6.18.44)
### Step 6.1: Buggy Code Exists?
**Record:** Yes — the **absence** of entries is the issue.
`drivers/net/usb/qmi_wwan.c` line 1454 has SRM825L (`0x2dee:0x4d22`) but
**not** SRM813Q (`0x4d63`, `0x4d64`). Meanwhile
`drivers/usb/serial/option.c` already has all six SRM813Q entries (lines
2472–2476). Half-enabled state confirmed.
### Step 6.2: Backport Complications
**Record:** Clean apply — `git apply --check` succeeded with zero
conflicts against current `qmi_wwan.c`.
### Step 6.3: Related Fixes Already Present?
**Record:** `option.c` SRM813Q support present (`38ba1a464c0d1`). No
`qmi_wwan` SRM813Q fix present. No duplicate.
---
## Phase 7: Subsystem and Maintainer Context
### Step 7.1: Subsystem Criticality
**Record:** `drivers/net/usb/` — IMPORTANT. USB WWAN/cellular modems
used in laptops, routers, IoT, embedded. Not core-kernel, but critical
for affected hardware users.
### Step 7.2: Subsystem Activity
**Record:** Actively maintained — frequent device ID additions and bug
fixes in `drivers/net/usb/` on this branch.
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users of MeiG SRM813Q (Snapdragon X35) USB LTE modules.
Config-dependent: `CONFIG_USB_NET_QMI_WWAN`. Currently broken for
cellular data on v6.18.44 despite partial `option` driver support.
### Step 8.2: Trigger Conditions
**Record:** Plug in MeiG SRM813Q modem. Deterministic, every time. No
privilege required beyond normal USB device access.
### Step 8.3: Failure Mode Severity
**Record:** No kernel crash/oops. **Functional failure** — no
RMNET/`wwan` network interface, no cellular data connectivity. Severity:
**MEDIUM** for affected users (device unusable for its primary purpose),
**LOW** globally (single modem model).
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** Enables cellular data on SRM813Q; completes support
started by already-merged `option.c` patch. Standard stable device-ID
backport.
- **Risk:** Very low — 2 lines, only matches specific VID/PID, no
behavior change for any other device.
- **Ratio:** High benefit for affected users, negligible risk.
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Summary
**FOR backport:**
- Explicit stable exception: new USB device IDs to existing driver
- 2-line, surgical, applies cleanly to v6.18.44
- Companion `option.c` patch already in tree with `Cc: stable`
- Without this, SRM813Q users lack `qmi_wwan`/RMNET — modem data path
non-functional
- Maintainer (Jakub Kicinski) signed off
- Identical pattern to other stable-nominated `qmi_wwan` device
additions in this tree
**AGAINST backport:**
- Not a crash/security/corruption fix
- Affects only one modem model (limited user population)
- No explicit `Cc: stable` on this specific commit message
- Mailing list discussion unverified
**UNRESOLVED:**
- Full lore review thread content
- Whether author tested RMNET connectivity end-to-end (descriptors
strongly support correctness)
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — descriptors match table
entries; maintainer SOB; established macro pattern
2. Fixes real bug affecting users? **PASS** — hardware non-functional
for data without it; completes half-merged series
3. Important issue? **PASS (MEDIUM)** — no crash, but primary device
function broken for affected users
4. Small and contained? **PASS** — 2 lines, one file
5. No new features/APIs? **PASS** — device ID table only (stable
exception category)
6. Can apply to local tree? **PASS** — verified clean apply
### Step 9.3: Exception Category
**Record:** **NEW DEVICE IDs** — adding USB VID/PID entries to the
existing `qmi_wwan` driver. Textbook stable backport material.
### Step 9.4: Decision Rationale
For **v6.18.44**, this commit should be backported. It is a minimal
device ID addition that enables RMNET/cellular data on the MeiG SRM813Q
modem. The `qmi_wwan` driver and all required infrastructure already
exist in this tree. The companion `option.c` patch is already merged
here (with stable nomination), leaving users in a broken partial-support
state until this `qmi_wwan` half is also applied. This matches the
stable exception for new device IDs and follows the same pattern as
other `qmi_wwan` modem additions routinely backported to stable.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body from user-provided commit
message
- **[Phase 1]** Confirmed patch 2/2 series structure from message ID
`55995-2`
- **[Phase 2]** Diff analysis: +2 lines in `products[]`,
`QMI_QUIRK_SET_DTR(0x2dee, 0x4d63/0x4d64, 0)`
- **[Phase 3]** `git describe HEAD` → `v6.18.44` (VERSION 6, PATCHLEVEL
18, SUBLEVEL 44)
- **[Phase 3]** `git blame -L 1454,1454` → SRM825L added by
`1ca645a2f74a4` (Aug 2024)
- **[Phase 3]** `git log --oneline -20 -- drivers/net/usb/qmi_wwan.c` →
recent device-ID additions confirmed
- **[Phase 3]** `git show 38ba1a464c0d1` → companion `option.c` patch
present with `Cc: stable@vger.kernel.org`
- **[Phase 3]** `git cat-file -t 7d2b37d3e42d` → upstream option commit
exists in tree
- **[Phase 3]** `grep 0x4d63/0x4d64` in `qmi_wwan.c` → no matches (not
yet present)
- **[Phase 4]** `b4 dig -c 1ca645a2f74a4` → found SRM825L lore link
(wrong commit, expected)
- **[Phase 4]** `WebFetch`/`curl` lore.kernel.org → 403/bot blocked;
thread content UNVERIFIED
- **[Phase 5]** Read `QMI_QUIRK_SET_DTR` macro and DTR quirk logic at
lines 821–825, 938–958
- **[Phase 5]** `grep QMI_QUIRK_SET_DTR` → many similar entries confirm
pattern
- **[Phase 6]** `grep SRM813Q/0x4d63` in `option.c` → 6 entries present
(lines 2472–2476)
- **[Phase 6]** `grep SRM813Q/0x4d63` in `qmi_wwan.c` → only SRM825L
(`0x4d22`), not SRM813Q
- **[Phase 6]** `git apply --check` on provided diff → applies cleanly
- **[Phase 7]** `git log --oneline -20 -- drivers/net/usb/` → active
subsystem
- **[Phase 8]** Confirmed failure mode: no `qmi_wwan` bind → no cellular
data (not a crash)
- **[Phase 9]** `git show e81a7f65288c7` → similar Telit addition has
`Cc: stable@vger.kernel.org`
**YES**
drivers/net/usb/qmi_wwan.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 05acac10cd2ba..94cdb61dca83d 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1452,6 +1452,8 @@ static const struct usb_device_id products[] = {
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
{QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
{QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L */
+ {QMI_QUIRK_SET_DTR(0x2dee, 0x4d63, 0)}, /* MeiG SRM813Q w/ Modem(PPP) */
+ {QMI_QUIRK_SET_DTR(0x2dee, 0x4d64, 0)}, /* MeiG SRM813Q w/ NMEA */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep the domain reference while processing hotplug
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (19 preceding siblings ...)
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add MeiG SRM813Q Sasha Levin
@ 2026-08-31 13:31 ` Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Increase timeout for Configuration Ready bit Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Release request if tb_cfg_request() fails in __tb_xdomain_response() Sasha Levin
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:31 UTC (permalink / raw)
To: patches, stable
Cc: Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit 138ec65b2c761f065b19d115aed2b8246fc272f5 ]
We process hotplug events in a workqueue that may run after the domain
has been removed by tb_domain_remove(). For example if user unloads the
driver while at the same time plugging a device router we may have
scheduled tb_handle_hotplug() to run. Avoid possible UAF in this case by
taking the domain reference before scheduling the hotplug handler in
tb_queue_hotplug().
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.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 line**
Record: `[thunderbolt] [keep] Keep the domain reference while processing
hotplug` — holds a domain reference during deferred hotplug handling.
**Step 1.2 — Tags**
Record:
- `Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>`
(author)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, `Link:`, or `Cc: stable@vger.kernel.org`
Notable: author is the Thunderbolt subsystem maintainer. No syzbot or
user reports in the message.
**Step 1.3 — Body**
Record:
- **Bug:** Hotplug runs on `tb->wq` via `tb_handle_hotplug()`; that work
can still run after `tb_domain_remove()` if the driver is unloaded
while a device is plugged.
- **Symptom:** Possible use-after-free on the `struct tb` domain object.
- **Root cause:** `tb_queue_hotplug()` stores a raw `tb` pointer with no
refcount; removal can free the domain before the work item finishes.
- **Fix:** Take `tb_domain_get()` when queueing; release with
`tb_domain_put()` when the handler completes.
**Step 1.4 — Hidden bug fix?**
Record: **Yes** — explicit UAF fix, not cosmetic cleanup.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `drivers/thunderbolt/tb.c` only
- **Scope:** ~4 net lines (1 changed, 3 added)
- **Functions:** `tb_queue_hotplug()`, `tb_handle_hotplug()`
- **Classification:** Single-file, surgical fix
**Step 2.2 — Code flow**
Record:
- **Hunk 1 (`tb_queue_hotplug`):** `ev->tb = tb` → `ev->tb =
tb_domain_get(tb)` — bumps device refcount before scheduling work.
- **Hunk 2 (`tb_handle_hotplug`):** Adds `tb_domain_put(tb)` on all exit
paths through `out:` before `kfree(ev)` — balances the refcount from
queue time.
**Step 2.3 — Bug mechanism**
Record:
- **Category:** Use-after-free / reference-counting bug
- **Mechanism:** Async hotplug work can outlive domain teardown.
`tb_domain_remove()` calls `flush_workqueue()`, but a race remains:
`tb_queue_hotplug()` can run after `flush_workqueue()` returns (e.g.
concurrent unload + plug event). Without a refcount,
`device_unregister()` → `tb_domain_release()` can `kfree(tb)` while
`tb_handle_hotplug()` still dereferences `ev->tb`.
**Step 2.4 — Fix quality**
Record:
- Matches the existing pattern in `xdomain.c`
(`tb_xdp_schedule_request()` uses `tb_domain_get()` /
`tb_domain_put()`).
- Minimal, obviously correct refcount pairing.
- **Regression risk:** Very low — only extends domain lifetime for in-
flight hotplug work.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: In this tree, `tb_queue_hotplug()` and `tb_handle_hotplug()`
blame to `19eef1d98eeda` (squashed import). The hotplug workqueue design
is long-standing Thunderbolt infrastructure.
**Step 3.2 — Fixes: tag**
Record: N/A — no `Fixes:` tag.
**Step 3.3 — Related file history**
Record: Recent stable thunderbolt fixes on `stable/linux-6.18.y` include
XDomain validation and debugfs leaks; no duplicate fix for this UAF
found.
**Step 3.4 — Author context**
Record: Mika Westerberg is the Thunderbolt maintainer. No other commits
from this author found in this checkout’s history (squashed tree).
**Step 3.5 — Dependencies**
Record:
- Requires `tb_domain_get()` / `tb_domain_put()` — **present** in
`drivers/thunderbolt/tb.h` (lines 796–806).
- Standalone; no series dependency.
- Backport note: mainline diff uses `kmalloc_obj(*ev)`; this tree uses
`kmalloc(sizeof(*ev), GFP_KERNEL)` — trivial context adjustment only.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: `b4 dig -c <commit>` not run — commit hash not present in this
checkout. Lore search blocked (Anubis bot protection). Web search did
not locate this specific patch thread.
**Step 4.2 — Reviewers**
Record: UNVERIFIED — could not retrieve thread via b4 or lore.
**Step 4.3 — Bug report**
Record: N/A — no `Reported-by:` or `Link:` tags.
**Step 4.4 — Series context**
Record: Standalone one-commit fix; no multi-patch series indicated.
**Step 4.5 — Stable list**
Record: UNVERIFIED — stable@ discussion not searched (lore blocked).
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `tb_queue_hotplug()`, `tb_handle_hotplug()`, plus callers
`tb_handle_event()`, `tb_scan_port()`.
**Step 5.2 — Callers**
Record:
- `tb_handle_event()` — control-channel plug events (`handle_event`
callback at line 3291)
- `tb_scan_port()` — DP HPD path (line 1302)
Both are reachable during normal Thunderbolt operation and driver
unload.
**Step 5.3 — Callees**
Record: `tb_handle_hotplug()` uses `pm_runtime_get_sync()`,
`mutex_lock(&tb->lock)`, switch/port lookups, `tb_scan_port()`,
tunnel/DP handling, `kfree(ev)`.
**Step 5.4 — Reachability**
Record: Triggerable by hardware hotplug and by `rmmod`/PCI remove during
concurrent plug — realistic on laptops/workstations with Thunderbolt.
**Step 5.5 — Similar patterns**
Record: `xdomain.c` already uses `tb_domain_get()` for deferred work.
`tb_queue_dp_bandwidth_request()` still uses a raw `ev->tb = tb` (line
2869) — same class of bug, but out of scope for this commit.
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is **6.18.43** (`git describe HEAD` →
`v6.18.43-1-gc7f0dac02d232`). Current code:
```101:106:drivers/thunderbolt/tb.c
ev->tb = tb;
ev->route = route;
ev->port = port;
ev->unplug = unplug;
INIT_DELAYED_WORK(&ev->work, tb_handle_hotplug);
queue_delayed_work(tb->wq, &ev->work, 0);
```
`tb_handle_hotplug()` ends with `kfree(ev)` and no `tb_domain_put()`.
**Step 6.2 — Backport difficulty**
Record: **Clean apply** with at most `kmalloc` vs `kmalloc_obj` context
difference.
**Step 6.3 — Fix already present?**
Record: **No** — fix not in this checkout.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: `drivers/thunderbolt/` — **IMPORTANT** (PCI driver; common on
Intel/Apple laptops, docks, displays).
**Step 7.2 — Activity**
Record: Active maintenance on 6.18.y (recent thunderbolt
security/validation fixes in stable history).
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Systems with `CONFIG_THUNDERBOLT` and the in-tree NHI driver —
Thunderbolt laptop/workstation users.
**Step 8.2 — Trigger conditions**
Record: Driver unload (`nhi_remove()` → `tb_domain_remove()`) concurrent
with device plug/hotplug event. Unprivileged users can unload modules if
permitted; root can always trigger via `rmmod`.
**Step 8.3 — Failure mode**
Record: **UAF on `struct tb`** → kernel oops/panic or memory corruption.
**Severity: CRITICAL/HIGH.**
**Step 8.4 — Risk vs benefit**
Record:
- **Benefit:** High — prevents crash/corruption on a realistic
unload+hotplug race.
- **Risk:** Very low — 3-line refcount fix following an established in-
driver pattern.
- **Ratio:** Strongly favors backport.
---
## Phase 9: Final Synthesis
**Step 9.1 — Evidence**
**FOR:**
- Real, well-described UAF race
- Subsystem maintainer fix
- Small, surgical, matches existing `xdomain.c` pattern
- Buggy code confirmed in 6.18.43
- `tb_domain_get/put` infrastructure already in tree
- Crash/corruption severity
**AGAINST:**
- No external reproducer (syzbot/user) in commit message
- Mailing-list review not verified
- Mainline merge not verified (torvalds/linux `tb.c` on GitHub still
shows buggy `ev->tb = tb`)
- Related `tb_queue_dp_bandwidth_request()` has the same pattern
(separate issue)
**UNRESOLVED:**
- Commit hash and lore review thread
- Whether fix is already in upstream mainline
**Step 9.2 — Stable rules checklist**
| Criterion | Result |
|-----------|--------|
| 1. Obviously correct and tested? | **PASS** — refcount pairing is
standard; no `Tested-by` in message |
| 2. Fixes a real user-affecting bug? | **PASS** — UAF on driver unload
+ hotplug |
| 3. Important issue? | **PASS** — crash/corruption (CRITICAL/HIGH) |
| 4. Small and contained? | **PASS** — ~4 lines, one file |
| 5. No new features/APIs? | **PASS** — refcount only |
| 6. Can apply to local tree? | **PASS** — infrastructure present, clean
apply |
**Step 9.3 — Exception category**
Record: N/A — not a quirk/DT/build/docs fix; standard bug fix.
**Step 9.4 — Decision rationale**
This is a textbook stable backport: a real UAF in deferred work during
driver teardown, fixed with a minimal refcount hold/release matching
code already used elsewhere in the same driver. The bug exists in the
local 6.18.43 tree, prerequisites are present, and the change is low
risk with high stability benefit.
---
## Verification
- [Phase 1] Parsed subject, body, tags from user-provided commit message
- [Phase 2] Analyzed provided diff: `tb_domain_get()` in
`tb_queue_hotplug()`, `tb_domain_put()` in `tb_handle_hotplug()`
- [Phase 3] `git describe HEAD` → v6.18.43; `git blame` on
`tb_queue_hotplug`/`tb_handle_hotplug`
- [Phase 3] `git log stable/linux-6.18.y --grep=thunderbolt` — no
duplicate fix found
- [Phase 4] `b4 dig` — not run (no commit hash in tree)
- [Phase 4] Lore fetch — blocked by Anubis
- [Phase 4] Web search — no matching patch thread found
- [Phase 5] `grep tb_queue_hotplug` — callers at lines 1302, 2930
- [Phase 5] Read `tb_handle_event()`, `tb_domain_remove()`,
`tb_domain_release()`
- [Phase 5] Verified `xdomain.c` refcount pattern (lines 879, 859)
- [Phase 6] Read current `tb.c` — buggy code present, fix absent
- [Phase 6] Verified `tb_domain_get/put` in `tb.h` lines 796–806
- [Phase 7] Confirmed thunderbolt driver path and recent stable activity
- [Phase 8] Traced `nhi_remove()` → `tb_domain_remove()` →
`device_unregister()` → `tb_domain_release()` → `kfree(tb)`
- [UNVERIFIED] Mainline merge status
- [UNVERIFIED] Mailing-list review / stable@ nomination
- [UNVERIFIED] User or syzbot reproduction
**YES**The two background git searches (`build/master` and `fixes-next`)
didn’t finish — they hung and were killed, so they didn’t turn up a
commit hash or confirm mainline merge status.
That doesn’t change the earlier conclusion: the UAF is present in your
6.18.43 tree, the fix is small and correct, and it should be backported.
**YES**
drivers/thunderbolt/tb.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 4a94cb406bdfb..041a4c8e10fb9 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -98,7 +98,7 @@ static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug)
if (!ev)
return;
- ev->tb = tb;
+ ev->tb = tb_domain_get(tb);
ev->route = route;
ev->port = port;
ev->unplug = unplug;
@@ -2527,6 +2527,9 @@ static void tb_handle_hotplug(struct work_struct *work)
pm_runtime_mark_last_busy(&tb->dev);
pm_runtime_put_autosuspend(&tb->dev);
+ /* Undo the refcount increased in tb_queue_hotplug() */
+ tb_domain_put(tb);
+
kfree(ev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-6.6] thunderbolt: Increase timeout for Configuration Ready bit
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (20 preceding siblings ...)
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep the domain reference while processing hotplug Sasha Levin
@ 2026-08-31 13:31 ` Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Release request if tb_cfg_request() fails in __tb_xdomain_response() Sasha Levin
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:31 UTC (permalink / raw)
To: patches, stable
Cc: Gil Fine, Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Gil Fine <gil.fine@linux.intel.com>
[ Upstream commit ba2cc385110129d03cd0f18a1b5969a430b67a18 ]
After setting the Configuration Valid bit (ROUTER_CS_5.CV), the USB4
Connection Manager guide specifies a 500 ms timeout for the router to
set the Configuration Ready bit (ROUTER_CS_6.CR). The current timeout
is shorter than specified. While there, fix the kernel-doc typo.
Increase the timeout to match the CM guide recommendation.
Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.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 line**
Record: `[thunderbolt]` `[Increase]` — Increase timeout for
Configuration Ready bit after setting Configuration Valid on USB4
routers.
**Step 1.2 — Tags**
Record:
- **Fixes:** none
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none (in commit)
- **Acked-by:** none
- **Link:** none
- **Cc: stable:** none (expected for manual review)
- **Signed-off-by:** Gil Fine, Mika Westerberg (subsystem maintainer)
No syzbot, no user bug report tags.
**Step 1.3 — Body analysis**
Record:
- **Bug:** After setting `ROUTER_CS_5.CV`, the USB4 Connection Manager
guide requires up to **500 ms** for the router to set `ROUTER_CS_6.CR`
(Configuration Ready). The kernel waits only **50 ms**.
- **Symptom:** Premature timeout waiting for Configuration Ready;
enumeration/tunnel setup may proceed before the router is actually
ready.
- **Root cause:** Timeout value does not match the CM guide
specification (present since initial USB4 support).
- **Also:** kernel-doc typo — “does nothing for the latter” should be
“former” (host router, where `tb_route(sw)` is zero).
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Although the subject says “Increase timeout,” this is a
real correctness/timing bug, not cosmetic cleanup. The doc fix is
incidental.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `drivers/thunderbolt/usb4.c` (+2 / −2 lines)
- **Functions:** `usb4_switch_configuration_valid()` (timeout change);
kernel-doc for same function (typo)
- **Scope:** Single-file, surgical fix
**Step 2.2 — Code flow change**
Record:
- **Hunk 1 (doc):** “latter” → “former” — documents that the function is
a no-op on the **host** router (`!tb_route(sw)` early return).
- **Hunk 2 (timeout):** `tb_switch_wait_for_bit(..., ROUTER_CS_6_CR,
..., 50)` → `..., 500)`.
- **Before:** Wait at most 50 ms for CR after writing CV.
- **After:** Wait up to 500 ms per USB4 CM guide.
- **Path:** USB4 device-router hotplug enumeration and resume restore
(via `tb_switch_configuration_valid()`).
**Step 2.3 — Bug mechanism**
Record: **Logic / timing correctness fix.** The wait can expire at 50 ms
while hardware is still within spec (up to 500 ms).
`tb_switch_wait_for_bit()` then returns `-ETIMEDOUT`. Callers currently
ignore that return value, but the function still returns to callers only
after the (too-short) wait completes, so tunnel/retimer work may start
before CR is set.
**Step 2.4 — Fix quality**
Record:
- **Obviously correct:** Aligns with spec; other waits in the same file
already use 500 ms (e.g. `ROUTER_CS_26` at line 79).
- **Minimal:** Two-line functional change.
- **Regression risk:** Very low — only lengthens a poll loop; worst case
adds ~450 ms on genuine timeout paths.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: 50 ms timeout introduced in `1639664fb74f30` (Dec 2021, “Move
usb4_switch_wait_for_bit() to switch.c”); originally in `b04079837b209`
(Dec 2019, “Add initial support for USB4”). Bug has existed since USB4
support landed.
**Step 3.2 — Fixes: tag**
Record: N/A — no Fixes: tag.
**Step 3.3 — Related file history**
Record:
- Part of upstream 5-patch series “CM fixes to follow CM guide more
closely” (Jan 2026).
- Related upstream-only commits on same files: `062023c4364ff` (Router
Ready wait in `usb4_switch_setup()`), `69a7b98770b7e` (PCIe adapter
detect check).
- **This patch is standalone** — only changes CR timeout and doc; does
not depend on RR verification or other series patches.
**Step 3.4 — Author context**
Record: Gil Fine (Intel thunderbolt contributor); committed by Mika
Westerberg (subsystem maintainer).
**Step 3.5 — Dependencies**
Record: **None required.** `ROUTER_CS_6_CR` and
`tb_switch_wait_for_bit()` exist in this tree. Patch applies cleanly
(`git apply --check` passed). `ROUTER_CS_6_RR` from patch 3/5 is **not**
in 6.18.y and is **not** needed for this change.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record:
- **b4 dig:** https://patch.msgid.link/20260126220606.3476657-5-
gil.fine@linux.intel.com
- **Series:** v1 only (5 patches, Jan 27 2026)
- **Stable nomination:** None found in thread
- **NAKs:** None
**Step 4.2 — Reviewers**
Record: **b4 dig -w:** Mika Westerberg, Andreas Noever, Yehezkel
Shapira, linux-usb@vger.kernel.org, Lukas Wunner. Mika reviewed patches
2/5 and 3/5; **no reply specifically on patch 4/5**.
**Step 4.3 — Bug reports**
Record: No Reported-by, syzbot, or bugzilla links. Spec-compliance fix
without a public user report.
**Step 4.4 — Series context**
Record: Patch 4/5 of 5; independently valuable. Other patches address
separate CM-guide gaps.
**Step 4.5 — Stable list**
Record: Not searched separately; no stable@vger discussion found in mbox
thread.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `usb4_switch_configuration_valid()`,
`tb_switch_configuration_valid()`, `tb_switch_wait_for_bit()`.
**Step 5.2 — Callers**
Record:
- `tb_switch_configuration_valid()` →
`usb4_switch_configuration_valid()` for USB4 switches
(`switch.c:2673-2677`)
- Called from `tb.c:1407` (hotplug/discovery path after TMU enable)
- Called from `tb.c:3095` (`tb_restore_children()` on resume)
- **Return value not checked** at either call site.
**Step 5.3 — Callees**
Record: `tb_sw_read()`, `tb_sw_write()`, `tb_switch_wait_for_bit()`
(poll loop with `usleep_range(50,100)`).
**Step 5.4 — Reachability**
Record: Triggered on USB4/Thunderbolt device-router hotplug and system
resume — common paths for dock/peripheral users with
`CONFIG_USB4`/`CONFIG_THUNDERBOLT`.
**Step 5.5 — Similar patterns**
Record: Other thunderbolt timeout increases in this tree use 500 ms
(`usb4.c:79`). Stable tree already contains `b6d572aeb58a5` (“Increase
DisplayPort Connection Manager handshake timeout”) — precedent for
backporting thunderbolt timing fixes.
---
## Phase 6: Cross-Reference Against Local Tree (6.18.y)
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is **v6.18.44** (`stable/linux-6.18.y`).
`usb4_switch_configuration_valid()` still uses **50 ms** at
`usb4.c:329-330`. Upstream fix `ba2cc38511012` is **not** an ancestor of
HEAD.
**Step 6.2 — Backport complications**
Record: **Clean apply** — `git format-patch -1 ba2cc38511012 | git apply
--check` succeeded with no conflicts.
**Step 6.3 — Related fixes already present?**
Record: No equivalent timeout change in 6.18.y. Router Ready
verification (`062023c4364ff`) is also absent — separate issue.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: **drivers/thunderbolt** — IMPORTANT (USB4/Thunderbolt docks,
peripherals, resume).
**Step 7.2 — Activity**
Record: Actively maintained; recent stable-relevant fixes include dock
connection issues (`bd646c768a934`) and retimer enumeration timing
(`75749d2c1d8ce`).
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: USB4/Thunderbolt users with downstream device routers that need
>50 ms to assert Configuration Ready after Configuration Valid — docks,
hubs, chained routers.
**Step 8.2 — Trigger conditions**
Record: Device connect or resume restore on USB4 topology. Not every
router (only those slower than 50 ms). Not a security issue;
unprivileged users cannot directly trigger this register sequence.
**Step 8.3 — Failure mode severity**
Record: **MEDIUM–HIGH** — intermittent enumeration failures, tunnels not
established, peripherals/docks failing to work until replug/reboot. Not
a kernel oops, but a real functional failure on affected hardware.
**Step 8.4 — Risk vs benefit**
Record:
- **Benefit:** Prevents premature proceed-before-ready on slow-but-spec-
compliant routers; aligns with CM guide.
- **Risk:** Very low (2-line change, longer wait only on this specific
bit poll).
- **Ratio:** Favorable for stable.
---
## Phase 9: Final Synthesis
**Evidence FOR backport:**
- Real spec mismatch bug since USB4 support (2019/2021)
- Buggy code confirmed in v6.18.44
- Small, obviously correct, applies cleanly
- Standalone (no series dependencies)
- Maintainer-authored/committed
- Precedent: other thunderbolt timeout increases are in 6.18.y
- Can cause user-visible dock/peripheral failures
**Evidence AGAINST:**
- No explicit user bug report or syzbot report
- Callers ignore return value (mitigates crash risk but not functional
impact)
- Part of broader CM-guide compliance series (though this hunk is
independent)
**Stable rules checklist:**
1. Obviously correct and tested? **PASS** — spec-aligned; maintainer
SOB; no Tested-by but change is trivial
2. Fixes a real bug? **PASS** — timeout too short vs USB4 CM guide
3. Important issue? **PASS** — functional failures on USB4 hardware
(MEDIUM–HIGH)
4. Small and contained? **PASS** — 2 lines functional change, 1 file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — verified clean apply
**Exception category:** Hardware timing workaround / spec-compliance fix
for existing USB4 driver (similar to prior thunderbolt timeout
backports).
---
## Problem Summary for Stable Users
On v6.18.44, after marking a USB4 device router’s configuration valid,
the kernel waits only 50 ms for the Configuration Ready bit. The USB4
Connection Manager guide allows up to 500 ms. Routers that need between
50–500 ms can hit a premature timeout; enumeration then continues before
the router is ready, which can manifest as flaky or failed
Thunderbolt/USB4 dock and peripheral bring-up. The fix is a minimal
timeout increase plus a documentation typo correction.
---
## Verification
- [Phase 1] Parsed commit `ba2cc38511012`: subject, body, tags (only
SOBs)
- [Phase 2] Read diff: 50→500 ms in `usb4_switch_configuration_valid()`,
doc typo fix
- [Phase 2] Read `tb_switch_wait_for_bit()` at `switch.c:1720-1739`
- [Phase 3] `git blame` lines 329-330: introduced 2021, 50 ms since USB4
bring-up
- [Phase 3] `git log -S "ROUTER_CS_6_CR, 50"`: original in
`b04079837b209`
- [Phase 3] `git merge-base --is-ancestor b04079837b209 HEAD`: USB4 code
in tree
- [Phase 3] `ba2cc38511012` not ancestor of HEAD: fix not yet in 6.18.44
- [Phase 4] `b4 dig -c ba2cc38511012`: lore URL found
- [Phase 4] `b4 dig -a`: v1 series, patch 4/5
- [Phase 4] `b4 dig -w`: maintainers CC’d
- [Phase 4] `b4 dig -m /tmp/tb_timeout.mbx`: no stable Cc, no NAKs, Mika
replied on patches 2–3 only
- [Phase 5] `grep usb4_switch_configuration_valid`: callers in
`switch.c`, `tb.c`
- [Phase 5] Read `tb.c:1407`, `tb.c:3095`: return value not checked
- [Phase 5] Read `usb4.c:311-330`: early return for host
(`!tb_route(sw)`)
- [Phase 5] `usb4.c:79`: other 500 ms timeout precedent in same file
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] `git format-patch -1 ba2cc38511012 | git apply --check`:
clean apply
- [Phase 6] `grep ROUTER_CS_6_RR tb_regs.h`: not in 6.18.y (unrelated to
this patch)
- [Phase 7] `git log --grep="DisplayPort Connection Manager handshake
timeout" stable/linux-6.18.y`: precedent commit present
- [Phase 8] Assessed severity: functional USB4 enumeration failures, not
kernel crash
**YES****Verdict: YES** — backport to this tree (v6.18.44 /
`stable/linux-6.18.y`).
The commit fixes a real USB4 timing bug: after setting Configuration
Valid, the kernel waits only **50 ms** for Configuration Ready, but the
USB4 CM guide allows **500 ms**. On slower routers, enumeration can
proceed too early and cause flaky dock/peripheral bring-up. The change
is two lines in `drivers/thunderbolt/usb4.c`, applies cleanly, is
standalone (doesn't need the other patches in the series), and matches
precedent for thunderbolt timeout fixes already in 6.18.y.
drivers/thunderbolt/usb4.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index 276c25c7d37e6..9430bed07c468 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -304,7 +304,7 @@ int usb4_switch_setup(struct tb_switch *sw)
* Sets configuration valid bit for the router. Must be called before
* any tunnels can be set through the router and after
* usb4_switch_setup() has been called. Can be called to host and device
- * routers (does nothing for the latter).
+ * routers (does nothing for the former).
*
* Return: %0 on success, negative errno otherwise.
*/
@@ -327,7 +327,7 @@ int usb4_switch_configuration_valid(struct tb_switch *sw)
return ret;
return tb_switch_wait_for_bit(sw, ROUTER_CS_6, ROUTER_CS_6_CR,
- ROUTER_CS_6_CR, 50);
+ ROUTER_CS_6_CR, 500);
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] thunderbolt: Release request if tb_cfg_request() fails in __tb_xdomain_response()
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (21 preceding siblings ...)
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Increase timeout for Configuration Ready bit Sasha Levin
@ 2026-08-31 13:31 ` Sasha Levin
22 siblings, 0 replies; 23+ messages in thread
From: Sasha Levin @ 2026-08-31 13:31 UTC (permalink / raw)
To: patches, stable
Cc: Mika Westerberg, Sasha Levin, andreas.noever, westeri,
YehezkelShB, linux-usb, linux-kernel
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit 4c63f29872cb444b33665348bbd2f45cab06afcd ]
If tb_cfg_request() fails setting up the request (for example the
control channel is shut down already) it returns an error without
calling the callback. To avoid leaking that memory, call
tb_cfg_request_put() if tb_cfg_request() fails.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `thunderbolt: Release request if
tb_cfg_request() fails in __tb_xdomain_response()`
**Local tree:** `v6.18.43-1-gc7f0dac02d232` (kernel version **6.18.43**)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Parse the subject line
**Record:** `[thunderbolt]` `[Release/fix]` — Release the allocated
`tb_cfg_request` when `tb_cfg_request()` fails in
`__tb_xdomain_response()`.
### Step 1.2: Parse all commit message tags
**Record:**
- **Fixes:** — none
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by:** — none
- **Acked-by:** — none
- **Link:** — none
- **Cc: stable:** — none (expected for manual review)
- **Signed-off-by:** Mika Westerberg `<mika.westerberg@linux.intel.com>`
(author; ignore pipeline SOB)
No syzbot, no user reports. Author is the Thunderbolt subsystem
maintainer.
### Step 1.3: Analyze commit body
**Record:**
- **Bug:** `tb_cfg_request()` can fail during setup (e.g., control
channel already shut down with `ctl->running == false`). On failure it
returns an error without invoking the `response_ready` callback.
- **Symptom:** Each failed `__tb_xdomain_response()` leaks one `struct
tb_cfg_request` (~200 bytes via `kzalloc`).
- **Root cause:** Caller allocates with `tb_cfg_request_alloc()`
(refcount 1). `tb_cfg_request()` bumps refcount and on error only
drops its own reference, leaving the alloc reference unreleased. The
success path relies on `response_ready` + workqueue to drop both
references; the error path has no callback.
### Step 1.4: Detect hidden bug fixes
**Record:** Not disguised — explicitly a memory-leak fix on an error
path.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory the changes
**Record:**
- **File:** `drivers/thunderbolt/xdomain.c` (+5 / -1 lines)
- **Function:** `__tb_xdomain_response()`
- **Scope:** Single-file, surgical fix
### Step 2.2: Code flow change
**Record:**
- **Before:** `return tb_cfg_request(ctl, req, response_ready, req);` —
on error, `req` leaked.
- **After:** Capture return value; if non-zero, call
`tb_cfg_request_put(req)`; return `ret`.
- **Path affected:** Error path only (enqueue failure `-ENOTCONN`, TX
failure, etc.).
### Step 2.3: Bug mechanism
**Record:** **Category:** Memory/resource leak (reference counting
imbalance).
Verified refcount flow in `tb_cfg_request()`:
```547:578:drivers/thunderbolt/ctl.c
int tb_cfg_request(struct tb_ctl *ctl, struct tb_cfg_request *req,
void (*callback)(void *), void *callback_data)
{
// ...
tb_cfg_request_get(req);
ret = tb_cfg_request_enqueue(ctl, req);
if (ret)
goto err_put;
// ...
err_put:
tb_cfg_request_put(req);
return ret;
}
```
- Alloc: ref = 1
- `tb_cfg_request_get()`: ref = 2
- Error `tb_cfg_request_put()`: ref = 1 (callback never runs)
- Without caller `put`: **leak**
Success path (no `req->response`): workqueue runs `response_ready` (put)
then `tb_cfg_request_put` in work — balanced.
### Step 2.4: Fix quality
**Record:** Obviously correct. Matches the pattern in
`__tb_xdomain_request()` (always calls `tb_cfg_request_put` after sync)
and `icm.c` (always puts after `tb_cfg_request`). Minimal regression
risk — only runs on already-failing paths.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame the changed lines
**Record:** `__tb_xdomain_response()` leaky pattern is present at HEAD
in this tree. Upstream fix: `4c63f29872cb` (May 5, 2026). Prepared
stable backport object `5430d7b1b6346` exists in repo but is **NOT** an
ancestor of HEAD.
### Step 3.2: Follow Fixes: tag
**Record:** N/A — no `Fixes:` tag. Bug is a longstanding omission in the
async ownership model of `__tb_xdomain_response`, not a regression from
a specific commit.
### Step 3.3: Related file history
**Record:** Recent thunderbolt fixes in this tree include other leak
fixes (`da405838` debugfs margining buffer leak). XDomain hardening
commits (`fcbd0cd`, `46da5c3`, `b5daa920`) are separate security/size
fixes.
### Step 3.4: Author context
**Record:** Mika Westerberg is Thunderbolt maintainer. Fix is in a 7.2
pull series but is standalone (patch 5/12, no structural dependencies).
### Step 3.5: Prerequisites
**Record:** No dependencies. `tb_cfg_request_put`, `response_ready`, and
`__tb_xdomain_response` all exist in this tree. Applies cleanly.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original patch discussion
**Record:** `b4 dig -c 4c63f29872cb` and `b4 dig -c 5430d7b1b6346` — no
lore match. `b4 am` subject lookup — not found. lore.kernel.org blocked
by Anubis bot protection. Web search found patch in **[GIT PULL] USB /
Thunderbolt driver changes for 7.2-1** as patch 5/12.
### Step 4.2: Reviewers
**Record:** UNVERIFIED — could not retrieve recipient list from lore/b4.
### Step 4.3: Bug report
**Record:** No external bug report. Issue identified by maintainer via
code inspection.
### Step 4.4: Series context
**Record:** Part of 12-patch Thunderbolt series for 7.2. This patch is
self-contained; other series patches are unrelated features/refactors.
### Step 4.5: Stable list history
**Record:** UNVERIFIED — lore stable archive inaccessible. Similar
thunderbolt leak fix (`da405838`) already backported to this 6.18.y
tree.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `__tb_xdomain_response()`, `response_ready()`,
`tb_cfg_request()`, `tb_cfg_request_alloc()`, `tb_cfg_request_put()`.
### Step 5.2: Callers of `__tb_xdomain_response()`
**Record:** Six internal call sites in `xdomain.c`:
- `tb_xdp_uuid_response()`
- `tb_xdp_error_response()`
- `tb_xdp_properties_response()`
- `tb_xdp_properties_changed_response()`
- `tb_xdp_link_state_status_response()`
- (one more via grep at line 609)
Also exported wrapper `tb_xdomain_response()` for module drivers.
### Step 5.3: Callees
**Record:** `tb_cfg_request_alloc()`, `tb_cfg_request()`,
`tb_cfg_request_put()` (after fix). `tb_cfg_request_enqueue()` returns
`-ENOTCONN` when `!ctl->running`.
### Step 5.4: Reachability
**Record:** Triggered during XDomain protocol handling — device hotplug,
property exchange, link state changes. Error path fires when control
channel is stopped (`tb_ctl_stop()` during `tb_domain_remove()` / probe
error paths). Realistic during Thunderbolt cable unplug or driver
unload.
### Step 5.5: Similar patterns
**Record:** `__tb_xdomain_request()` always calls
`tb_cfg_request_put(req)` after `tb_cfg_request_sync()`. `icm.c:2282`
always puts after async `tb_cfg_request()`. `__tb_xdomain_response()`
was the outlier missing error-path cleanup.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Does buggy code exist?
**Record:** **YES.** At HEAD, `drivers/thunderbolt/xdomain.c:153` still
has `return tb_cfg_request(ctl, req, response_ready, req);` without
error-path `put`. Fix commit `5430d7b1b6346` is **NOT_IN_HEAD**.
### Step 6.2: Backport complications
**Record:** Clean apply expected — upstream diff is 5 lines, no context
conflicts with recent XDomain security patches in this tree.
### Step 6.3: Related fixes already present?
**Record:** No equivalent fix present. Other thunderbolt leak fixes
exist (debugfs) but not this one.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/thunderbolt/` — **IMPORTANT** (USB4/Thunderbolt
driver, `CONFIG_USB4`). Affects systems with TB/USB4 hardware.
### Step 7.2: Subsystem activity
**Record:** Actively maintained — multiple recent fixes in this 6.18.y
tree (XDomain validation, debugfs leak, property parsing bounds).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users with USB4/Thunderbolt (`CONFIG_USB4`) during XDomain
communication, especially teardown/unplug scenarios.
### Step 8.2: Trigger conditions
**Record:** `tb_cfg_request()` fails because control channel is not
running (`-ENOTCONN` from `tb_cfg_request_enqueue`) or TX fails. Most
likely during domain stop/removal while XDomain responses are still
attempted. Not userspace-triggerable directly, but common on hot-unplug.
### Step 8.3: Failure mode severity
**Record:** Memory leak — one `struct tb_cfg_request` per failed
response. Not a crash or security issue, but accumulates on repeated
teardown races. **Severity: MEDIUM** (resource leak on realistic error
path).
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** MEDIUM — prevents kernel memory leak during TB
disconnect/teardown
- **Risk:** VERY LOW — 5-line error-path fix, maintainer-authored,
mirrors existing patterns
- **Ratio:** Favorable for stable
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Verified memory leak on `tb_cfg_request()` error path
- Buggy code confirmed present in 6.18.43 tree; fix not yet applied
- Small, surgical, obviously correct fix
- Thunderbolt maintainer authorship
- Realistic trigger during control channel shutdown
- Precedent: other thunderbolt leak fixes backported to this tree
- No dependencies or API changes
**AGAINST backport:**
- Leak is small per occurrence (not crash/corruption)
- Only affects `CONFIG_USB4` systems
- No fuzzer or user reports
**UNRESOLVED:**
- Full lore review thread unavailable (b4/lore blocked)
- Exact frequency of leak in production unquantified
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — refcount logic verified; no
Tested-by but pattern matches sibling code
2. Fixes a real bug? **PASS** — confirmed memory leak
3. Important issue? **PASS (MEDIUM)** — resource leak on driver teardown
path
4. Small and contained? **PASS** — 5 lines, one function
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — code exists, clean apply expected
### Step 9.3: Exception categories
**Record:** N/A — standard bug fix, not device ID/quirk/DT/build/doc
exception.
### Step 9.4: Decision rationale
This commit fixes a real, verifiable memory leak in the Thunderbolt
XDomain response path. When the control channel is already stopped
(typical during domain teardown or hot-unplug), `tb_cfg_request()`
returns an error without invoking the `response_ready` callback, leaving
the allocation from `tb_cfg_request_alloc()` unreleased. The fix adds
the missing `tb_cfg_request_put()` on the error path only, matching
established patterns elsewhere in the same driver.
For the **6.18.43** tree checked out locally, the buggy code is present
and the fix is absent. The patch is minimal, maintainer-authored, and
carries very low regression risk. While not a crash-level issue, stable
trees routinely accept driver memory-leak fixes on realistic error paths
— and this tree already backports a similar thunderbolt debugfs leak
fix.
---
## Verification
- [Phase 1] Parsed subject, tags (only SOB from Mika Westerberg), body —
memory leak on `tb_cfg_request()` failure
- [Phase 2] Diff: +5/-1 in `__tb_xdomain_response()`, error-path
`tb_cfg_request_put()`
- [Phase 2] Read `tb_cfg_request()` at `ctl.c:547-578` — confirmed error
path drops only internal ref, callback not called
- [Phase 2] Read `response_ready()` at `xdomain.c:133-136` — success-
path cleanup via callback
- [Phase 3] `git describe HEAD` → v6.18.43; `make kernelversion` →
6.18.43
- [Phase 3] `git show 4c63f29872cb` — upstream fix commit exists (May 5,
2026)
- [Phase 3] `git merge-base --is-ancestor 5430d7b1b6346 HEAD` →
NOT_IN_HEAD; buggy code at `xdomain.c:153`
- [Phase 3] Compared `__tb_xdomain_request()` at `xdomain.c:198` —
always puts after request
- [Phase 3] Compared `icm.c:2278-2282` — always puts after async
`tb_cfg_request()`
- [Phase 4] `b4 dig -c 4c63f29872cb` — no lore match
- [Phase 4] Web search — found in 7.2 GIT PULL series (patch 5/12)
- [Phase 4] lore.kernel.org — blocked by Anubis (UNVERIFIED for thread
review)
- [Phase 5] Grep: 6 call sites for `__tb_xdomain_response()` in
`xdomain.c`
- [Phase 5] Read `tb_cfg_request_enqueue()` at `ctl.c:140-142` — returns
`-ENOTCONN` when `!ctl->running`
- [Phase 5] Read `tb_ctl_stop()` at `ctl.c:751-754` — sets `ctl->running
= false`
- [Phase 5] Read `tb_domain_remove()` at `domain.c:506` — calls
`tb_ctl_stop()`
- [Phase 6] Confirmed buggy code at HEAD `xdomain.c:138-154`
- [Phase 6] Confirmed fix not in HEAD; upstream diff applies to same
function structure
- [Phase 7] Driver built under `CONFIG_USB4` per
`drivers/thunderbolt/Makefile`
- [Phase 8] Prior thunderbolt leak fix `da405838` present in this tree
- [Phase 8] Leak size: one `kzalloc(sizeof(struct tb_cfg_request))` per
failure
**YES**The background `git branch -a --contains` check hung (likely
because scanning all branches is slow in this repo), so I didn’t wait on
it.
The same question was already answered with a direct check: `git merge-
base --is-ancestor 5430d7b1b6346 HEAD` → **NOT_IN_HEAD**. The leak fix
is not in your current **6.18.43** tree; the buggy code is still at
`drivers/thunderbolt/xdomain.c:153`.
**Verdict from the analysis: YES** — this is a small, correct memory-
leak fix on the `tb_cfg_request()` error path and is appropriate for
stable backport to this tree.
drivers/thunderbolt/xdomain.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index b27ef872edeac..5fbdd412a712f 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -139,6 +139,7 @@ static int __tb_xdomain_response(struct tb_ctl *ctl, const void *response,
size_t size, enum tb_cfg_pkg_type type)
{
struct tb_cfg_request *req;
+ int ret;
req = tb_cfg_request_alloc();
if (!req)
@@ -150,7 +151,11 @@ static int __tb_xdomain_response(struct tb_ctl *ctl, const void *response,
req->request_size = size;
req->request_type = type;
- return tb_cfg_request(ctl, req, response_ready, req);
+ ret = tb_cfg_request(ctl, req, response_ready, req);
+ if (ret)
+ tb_cfg_request_put(req);
+
+ return ret;
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-08-31 13:52 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18] usb: xhci: remove legacy 'num_trbs_free' tracking Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] xhci: Prevent queuing new commands if xhci is inaccessible Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Don't access path config space on Lane 1 adapters in tb_switch_reset_host() Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep XDomain reference during the lifetime of a service Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: aspeed_udc: avoid past-the-end iterator in dequeue Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: udc: skip pullup() if already connected Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.10] usb: core: hcd: fix possible deadlock in rh control transfers Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] usb: xhci: Improve Soft Retries after short transfers Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Verify Router Ready bit is set after router enumeration Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Avoid reserved fields in path config space for USB4 routers Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Improve multi-display DisplayPort tunnel allocation Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-6.1] thunderbolt: Don't create multiple DMA tunnels on firmware connection manager Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] usb: gadget: goku_udc: avoid NULL deref of dev->driver in INT_USBRESET log Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] thunderbolt: Verify PCIe adapter in detect state before tunnel setup Sasha Levin
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18-5.10] usbip: vhci_hcd: fix NULL deref in status_show_vhci Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Set tb->root_switch to NULL when domain is stopped Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-6.12] thunderbolt: Don't disable lane adapter if XDomain lane bonding isn't possible Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] usb: host: add ARCH_AIROHA in XHCI MTK dependency Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] USB: cdc-acm: start bulk-IN polling when ALWAYS_POLL_CTRL is set Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add MeiG SRM813Q Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Keep the domain reference while processing hotplug Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-6.6] thunderbolt: Increase timeout for Configuration Ready bit Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.10] thunderbolt: Release request if tb_cfg_request() fails in __tb_xdomain_response() Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox