[PATCH v5 02/18] PCI/CXL: Probe the underlying bus reset in cxl_reset_bus_function()
Nicolin Chen
nicolinc at nvidia.com
Thu Jul 2 21:06:27 PDT 2026
cxl_reset_bus_function() reports "supported" to a probe after checking only
that the upstream bridge carries a CXL port DVSEC. The underlying bus reset
can still be unavailable, e.g. on a bus shared with other devices, so both
the reset_methods[] array and the reset_method sysfs node end up listing a
"cxl_bus" that is guaranteed to fail with -ENOTTY when it is attempted.
Probe the underlying pci_dev_reset_slot_function() and then, if it is not
applicable, pci_parent_bus_reset(). These are the same two checks that the
actual reset runs, so a shared-bus CXL device no longer advertises a method
that can never succeed.
Probing via pci_reset_bus_function() would not work: its cxl_sbr_masked()
check rejects every CXL port with a masked SBR, while the do-reset path in
this function unmasks the SBR before resetting. Such a port would wrongly
probe as unsupported.
Also pass an explicit PCI_RESET_DO_RESET at the do-reset call site, since
probe is always false at that point.
Fixes: 53c49b6e6dd2e ("PCI/CXL: Add 'cxl_bus' reset method for devices below CXL Ports")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
drivers/pci/pci.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 01cf310540561..8102989673333 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4979,8 +4979,16 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
if (!dvsec)
return -ENOTTY;
- if (probe)
- return 0;
+ /*
+ * Do not probe via pci_reset_bus_function(), which would reject a
+ * masked SBR that the do-reset path below unmasks before resetting.
+ */
+ if (probe) {
+ rc = pci_dev_reset_slot_function(dev, PCI_RESET_PROBE);
+ if (rc != -ENOTTY)
+ return rc;
+ return pci_parent_bus_reset(dev, PCI_RESET_PROBE);
+ }
rc = pci_read_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL, ®);
if (rc)
@@ -5000,7 +5008,7 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
val);
}
- rc = pci_reset_bus_function(dev, probe);
+ rc = pci_reset_bus_function(dev, PCI_RESET_DO_RESET);
if (reg != val)
pci_write_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
--
2.43.0
More information about the linux-arm-kernel
mailing list