From 03ec922f00250817a11b6b829601932d5f777998 Mon Sep 17 00:00:00 2001 From: Gerd Bayer Date: Mon, 30 Mar 2026 15:09:44 +0200 Subject: [PATCH 1/3] PCI: Do not enable AtomicOps by RCiEPs Since Root Complex Integrated Endpoints (RCiEPs) attach to a bus that has no bridge device describing the Root Port, the capability to complete AtomicOps requests cannot be determined with PCIe methods. Change default of pci_enable_atomic_ops_to_root() to not enable AtomicOps requests on RCiEPs. As far as we know, there are no RCiEPs that need AtomicOps (see Link below). Signed-off-by: Gerd Bayer Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260330-fix_pciatops-v7-1-f601818417e8@linux.ibm.com --- drivers/pci/pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8479c2e1f74f..135e5b591df4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3692,15 +3692,14 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) /* * Per PCIe r4.0, sec 6.15, endpoints and root ports may be - * AtomicOp requesters. For now, we only support endpoints as - * requesters and root ports as completers. No endpoints as + * AtomicOp requesters. For now, we only support (legacy) endpoints + * as requesters and root ports as completers. No endpoints as * completers, and no peer-to-peer. */ switch (pci_pcie_type(dev)) { case PCI_EXP_TYPE_ENDPOINT: case PCI_EXP_TYPE_LEG_END: - case PCI_EXP_TYPE_RC_END: break; default: return -EINVAL; From 1ae8c4ce157037e266184064a182af9ef9af278b Mon Sep 17 00:00:00 2001 From: Gerd Bayer Date: Mon, 30 Mar 2026 15:09:45 +0200 Subject: [PATCH 2/3] PCI: Enable AtomicOps only if Root Port supports them When inspecting the config space of a Connect-X physical function in an s390 system after it was initialized by the mlx5_core device driver, we found the function to be enabled to request AtomicOps despite the Root Port lacking support for completing them: 00:00.1 Ethernet controller: Mellanox Technologies MT2894 Family [ConnectX-6 Lx] Subsystem: Mellanox Technologies Device 0002 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- AtomicOpsCtl: ReqEn+ On s390 and many virtualized guests, the Endpoint is visible but the Root Port is not. In this case, pci_enable_atomic_ops_to_root() previously enabled AtomicOps in the Endpoint even though it can't tell whether the Root Port supports them as a completer. Change pci_enable_atomic_ops_to_root() to fail if there's no Root Port or the Root Port doesn't support AtomicOps. Fixes: 430a23689dea ("PCI: Add pci_enable_atomic_ops_to_root()") Reported-by: Alexander Schmidt Signed-off-by: Gerd Bayer [bhelgaas: commit log, check RP first to simplify flow] Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260330-fix_pciatops-v7-2-f601818417e8@linux.ibm.com --- drivers/pci/pci.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 135e5b591df4..3a4ba587042b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3675,8 +3675,7 @@ void pci_acs_init(struct pci_dev *dev) */ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) { - struct pci_bus *bus = dev->bus; - struct pci_dev *bridge; + struct pci_dev *root, *bridge; u32 cap, ctl2; /* @@ -3705,35 +3704,35 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) return -EINVAL; } - while (bus->parent) { - bridge = bus->self; + root = pcie_find_root_port(dev); + if (!root) + return -EINVAL; - pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap); + pcie_capability_read_dword(root, PCI_EXP_DEVCAP2, &cap); + if ((cap & cap_mask) != cap_mask) + return -EINVAL; + bridge = pci_upstream_bridge(dev); + while (bridge != root) { switch (pci_pcie_type(bridge)) { - /* Ensure switch ports support AtomicOp routing */ case PCI_EXP_TYPE_UPSTREAM: - case PCI_EXP_TYPE_DOWNSTREAM: - if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE)) - return -EINVAL; - break; - - /* Ensure root port supports all the sizes we care about */ - case PCI_EXP_TYPE_ROOT_PORT: - if ((cap & cap_mask) != cap_mask) - return -EINVAL; - break; - } - - /* Ensure upstream ports don't block AtomicOps on egress */ - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) { + /* Upstream ports must not block AtomicOps on egress */ pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl2); if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) return -EINVAL; + fallthrough; + + /* All switch ports need to route AtomicOps */ + case PCI_EXP_TYPE_DOWNSTREAM: + pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, + &cap); + if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE)) + return -EINVAL; + break; } - bus = bus->parent; + bridge = pci_upstream_bridge(bridge); } pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, From 8e69214402397fcbb17f25ac5acb178195aca4bc Mon Sep 17 00:00:00 2001 From: Gerd Bayer Date: Mon, 30 Mar 2026 15:09:46 +0200 Subject: [PATCH 3/3] PCI: Update PCIe spec references for AtomicOps Point to the relevant sections in the most recent release 7.0 of the PCIe spec. Text has mostly just moved around without any semantic change. Signed-off-by: Gerd Bayer Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260330-fix_pciatops-v7-3-f601818417e8@linux.ibm.com --- drivers/pci/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 3a4ba587042b..fde970c78413 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3679,7 +3679,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) u32 cap, ctl2; /* - * Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit + * Per PCIe r7.0, sec 7.5.3.16, the AtomicOp Requester Enable bit * in Device Control 2 is reserved in VFs and the PF value applies * to all associated VFs. */ @@ -3690,7 +3690,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) return -EINVAL; /* - * Per PCIe r4.0, sec 6.15, endpoints and root ports may be + * Per PCIe r7.0, sec 6.15, endpoints and root ports may be * AtomicOp requesters. For now, we only support (legacy) endpoints * as requesters and root ports as completers. No endpoints as * completers, and no peer-to-peer.