Public bug reported:
## Summary
Single-commit fix for a silent regression on `26.04_linux-nvidia-bos` that makes
a CXL Type 3 device's memory disappear entirely when firmware commits an unused
HDM decoder slot with size 0. Six lines in `drivers/cxl/core/reset.c`.
before the fix after the fix
-------------------- -------------------- -----------------------------------
cxl list -M [] mem0, 128 GiB
cxl list -R -i [] region0 @ 0x400000000000, committed
lsmem total online 715.5 G 843.5 G
numactl -H node 2 0 MB 131072 MB
## Motivation
This is a regression of a feature already merged on this branch, caused by two
of our own commits duplicating the same check in different places, with no
textual conflict to flag it.
`591881a5890e` ("NVIDIA: VR: SAUCE: cxl: Allow zero sized HDM decoders",
October 2025) made `init_hdm_decoder()` return `-ENOSPC` for a committed
size-0 decoder, which `devm_cxl_enumerate_decoders()` treats as "skip this slot
and keep enumerating".
`463d2a08ee53` ("NVIDIA: VR: SAUCE: cxl: Share HDM decoder decode logic", the
CXL reset series, July 2026) then moved register decoding into the shared
`cxl_hdm_decode_decoder()` helper and added a second, stricter rejection there:
```c
if (enabled && !size)
return -ENXIO;
```
`init_hdm_decoder()` calls that helper first and returns its error immediately,
so it never reaches its own `size == 0` skip. `devm_cxl_enumerate_decoders()`
sees `-ENXIO` instead of `-ENOSPC` and fails the entire port, taking the
endpoint and the memdev with it. `cxl_pci_hdm_read_decoder()` shares the same
helper and fails identically during early PCI enumeration, independently
emptying the HDM cache that CXL reset and vfio-cxl depend on.
Committing a decoder with size 0 is spec-legal (CXL r3.2 8.2.4.20.12) and
firmware uses it to burn unused slots. On the reporting DUT, decoder 1 is
committed and locked at size 0 (`ctrl 0x1700`):
```
pci 0005:01:00.0: CXL HDM decoder 1 has invalid configuration: -6
cxl_port endpoint9: decoder9.1: Invalid decoder configuration (ctrl: 0x1700): -6
cxl_port endpoint9: Failed to initialize decoder9.1
cxl_mem mem0: endpoint9 failed probe
```
## What's in this PR
One commit, `drivers/cxl/core/reset.c` only:
1. **Drop the duplicate rejection from the shared decode helper.**
`cxl_hdm_decode_decoder()` no longer returns `-ENXIO` for `enabled && !size`.
A committed size-0 decoder decodes as an empty HPA range and
`init_hdm_decoder()`'s existing `-ENOSPC` rejection does the skipping again.
Rejecting a spec-legal configuration is caller policy and does not belong in
a decode helper shared by two callers with different needs.
2. **Skip empty ranges when collecting CXL reset windows**, in
`cxl_hdm_ranges_collect()`:
```c
/* A committed zero-size decoder maps no HPA. */
if (!range_len(&settings->hpa_range))
continue;
```
The two hunks are a matched pair and neither is correct alone. Hunk 1 alone
changes nothing for enumeration, since `init_hdm_decoder()` still rejects
`size == 0`; its only effect is that `cxl_pci_hdm_read_decoder()` now admits the
slot to the HDM cache, which is exactly why hunk 2 is required. Without hunk 2
that cached empty range reaches the reset path and is rejected —
`cxl_hdm_range_add()` returns `-EINVAL` on `end < start`, and when `base == 0`
the end wraps to `U64_MAX` and `cxl_hdm_range_len()` returns `-EOVERFLOW`.
`range_len()` is 0 in both the ordinary and the wrapped case, so the new guard
covers both. The hardware run confirms this empirically: both failure sites
clear together.
## Provenance
Reported by Fenghua Yu in August 2026 against this branch carrying the reset
series v9, with a local fix patch. Rather than carry that patch, both hunks were
requested for the upstream series so the two overlapping changes could not
defeat each other again; Srirangan folded them into v11 patches 3/12 and 7/12,
and they are carried forward in v14 and v15.
Backported from v15, the current posting. v15 restructures this code into new
`hdm_regs.c` / `hdm_state.c` / `drivers/pci/cxl.c` files that do not exist on
this branch, so the hunks were taken in their v11 form, which maps directly onto
this tree's `reset.c`. v15 carries the same two changes semantically, differing
only in merging the enable and zero-size conditions into one `if`.
- Upstream v15:
https://lore.kernel.org/linux-cxl/[email protected]/
- `Fixes: 463d2a08ee53` ("NVIDIA: VR: SAUCE: cxl: Share HDM decoder decode
logic")
- Regressed feature: `591881a5890e` ("NVIDIA: VR: SAUCE: cxl: Allow zero sized
HDM decoders")
** Affects: linux-nvidia-bos (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2171032
Title:
CXL: Restore Type 3 memory by accepting firmware-committed zero-size
HDM decoders
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-bos/+bug/2171032/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs