Public bug reported:

[Impact]

The CXL HDM decoder cache added by commit 017d76d5ca2b ("NVIDIA: VR:
SAUCE: cxl: Cache endpoint decoder settings during PCI enumeration") is
initialised from pci_init_capabilities(), that is from pci_device_add()
during pci_scan_child_bus(). That runs before PCI resource assignment,
so a CXL-capable endpoint whose BARs firmware left unprogrammed is
probed while pci_resource_start() still returns 0.

__pci_read_base() does not set IORESOURCE_UNSET for a BAR that simply
reads as zero — it only sets that flag for the over-4GB cases and the
inverted-region check — so the resource looks valid to
cxl_decode_regblock(), which only tests offset > pci_resource_len(). The
register block is therefore computed at physical address 0 + offset.
__pci_cxl_hdm_init() then enables PCI_COMMAND_MEMORY, ioremap()s that
address and reads it. On arm64 this is unclaimed physical address space,
so the read takes a synchronous external abort inside an initcall,
killing PID 1:

pci 0002:81:00.0: BAR 0 [mem 0x00000000-0x0fffffff 64bit pref]
Internal error: synchronous external abort: 0000000096000410 [#1] SMP
pc : cxl_probe_component_regs+0x4c/0x388
Call trace:
 cxl_probe_component_regs+0x4c/0x388 (P)
 cxl_probe_regs+0xc0/0x2b8
 cxl_setup_regs+0x74/0x1a0
 __pci_cxl_hdm_init+0x1ec/0xb60
 pci_cxl_hdm_init+0x24/0xe8
 pci_device_add+0x1b8/0x2f0
 pci_scan_single_device+0xe8/0x110
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b


[Fix]

Two changes, both following the rework in Srirangan Madhavan's v12-v14
upstream postings (https://lore.kernel.org/linux-
cxl/[email protected]/):

Move the HDM cache init from pci_init_capabilities() to
pci_bus_add_device(), after resource assignment and before driver
binding. This is the correct insertion point — pci_bus_add_device()
carries the comment "Can not put in pci_device_add yet because resources
are not assigned yet for some devices." All enumeration paths (boot via
pci_acpi_scan_root(), pci_rescan_bus(), pciehp, acpiphp, SR-IOV) assign
resources before calling it.

Add a cxl_pci_bar_usable() gate that rejects a BAR which is zero-length,
IORESOURCE_UNSET, IORESOURCE_DISABLED, not IORESOURCE_MEM, or has a zero
start, and apply it to the register block before PCI_COMMAND_MEMORY is
touched or anything is mapped. Note the zero-start test is the load-
bearing one for this bug; IORESOURCE_UNSET only becomes meaningful once
the hook runs after assignment, where it catches a BAR whose assignment
was attempted and failed. The same predicate is applied to
cxl_pci_hdm_find_bar() and to cxl_pci_hdm_ioremap_current() on the post-
reset path, and cxl_pci_hdm_capable() additionally rejects a DVSEC
advertising no 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/2170528

Title:
  cxl: Kernel panic in cxl_probe_component_regs() when the CXL HDM cache
  probes an unassigned BAR

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-bos/+bug/2170528/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to