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

Reply via email to