From 18c35163cc5762d3b3dcdb4d24d9979b283b2d4a Mon Sep 17 00:00:00 2001 From: Vidya Sagar Date: Wed, 25 Feb 2026 19:08:01 +0530 Subject: [PATCH] PCI/CXL: Hide SBR from reset_methods if masked by CXL Per CXL r3.1, sec 8.1.5.2, the Secondary Bus Reset (SBR) bit in the Bridge Control register of a CXL port has no effect unless the "Unmask SBR" bit in the Port Control Extensions Register is set. After b1956e2d0713 ("PCI/CXL: Fail bus reset if upstream CXL Port has SBR masked"), Linux checks the "Unmask SBR" bit in pci_reset_bus_function(). But when probe==true, it previously returned 0, incorrectly indicating that SBR is a viable reset method for the device. As a result, "bus" is listed in the device's "reset_method" attribute even though the hardware is incapable of performing it. If a user writes "bus" to "reset_method" or triggers a reset that falls back to SBR, the operation fails with "write error: Inappropriate ioctl for device". If the link is operating in CXL mode (pcie_is_cxl()), return -ENOTTY immediately unless "Unmask SBR" is set, regardless of the probe argument. This ensures that "bus" is not advertised in "reset_methods" when the hardware prevents it, improving clarity for users and aligning the sysfs capability report with actual hardware behavior. Signed-off-by: Vidya Sagar [bhelgaas: commit log, use pcie_is_cxl()] Signed-off-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Link: https://patch.msgid.link/20260225133801.30231-1-vidyas@nvidia.com (cherry picked from commit 702c1d56c7177a0481abd2814bab9495f1150967) Signed-off-by: Lee Trager --- drivers/pci/pci.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0b6a23405f167..7ca158267cc61 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5022,12 +5022,8 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe) * If "dev" is below a CXL port that has SBR control masked, SBR * won't do anything, so return error. */ - if (bridge && cxl_sbr_masked(bridge)) { - if (probe) - return 0; - + if (bridge && pcie_is_cxl(bridge) && cxl_sbr_masked(bridge)) return -ENOTTY; - } rc = pci_dev_reset_slot_function(dev, probe); if (rc != -ENOTTY)