| From 39837998dbbc678517c1fee796bc1fad0c62c47e Mon Sep 17 00:00:00 2001 | |
| From: Sasha Levin <sashal@kernel.org> | |
| Date: Mon, 21 Sep 2026 13:19:03 +0200 | |
| Subject: PCI: Accept AtomicOps already enabled by the hypervisor | |
| MIME-Version: 1.0 | |
| Content-Type: text/plain; charset=UTF-8 | |
| Content-Transfer-Encoding: 8bit | |
| From: Nikola Prica <nikola.prica@amd.com> | |
| [ Upstream commit 40cce45b921f7930886bcba43069edc579725457 ] | |
| pci_enable_atomic_ops_to_root() currently fails when no Root Port is | |
| visible. That is common in passthrough guests (ESXi, Hyper-V): the Endpoint | |
| is assigned to the VM, but the Root Port above it is not visible in the | |
| guest topology. | |
| In those setups the hypervisor may already have enabled AtomicOp Requester | |
| Enable on the device. If PCI_EXP_DEVCTL2_ATOMIC_REQ is set, treat AtomicOps | |
| as already enabled and return success instead of failing the Root Port | |
| walk. | |
| After 1ae8c4ce1570 ("PCI: Enable AtomicOps only if Root Port supports | |
| them"), pci_enable_atomic_ops_to_root() always returns failure if the Root | |
| Port is not visible, so drivers don't use atomics when they could. On | |
| systems where the Root Port is not visible but *does* support AtomicOps, | |
| this is a regression: prior to 1ae8c4ce1570, it enabled AtomicOps in the | |
| endpoint and returned success. | |
| Fixes: 1ae8c4ce1570 ("PCI: Enable AtomicOps only if Root Port supports them") | |
| Signed-off-by: Nikola Prica <nikola.prica@amd.com> | |
| [bhelgaas: commit log, code comment] | |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> | |
| Tested-by: Gerd Bayer <gbayer@linux.ibm.com> | |
| Reviewed-by: Christian König <christian.koenig@amd.com> | |
| Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com> | |
| Link: https://patch.msgid.link/20260921111903.978687-1-nikprica@amd.com | |
| Signed-off-by: Sasha Levin <sashal@kernel.org> | |
| --- | |
| drivers/pci/pci.c | 15 ++++++++++++++- | |
| 1 file changed, 14 insertions(+), 1 deletion(-) | |
| diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c | |
| index b0d4c3bc205bf..6e861dd4020cb 100644 | |
| --- a/drivers/pci/pci.c | |
| +++ b/drivers/pci/pci.c | |
| @@ -3822,8 +3822,21 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) | |
| } | |
| root = pcie_find_root_port(dev); | |
| - if (!root) | |
| + if (!root) { | |
| + | |
| + /* | |
| + * A hypervisor may expose a topology with the root port | |
| + * not visible to the guest. If the hypervisor has already | |
| + * set AtomicOp Requester Enable in the endpoint, we assume | |
| + * it has verified support in the root port, so it is safe | |
| + * for the driver to use AtomicOps. | |
| + */ | |
| + pcie_capability_read_dword(dev, PCI_EXP_DEVCTL2, &ctl2); | |
| + if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ) | |
| + return 0; | |
| + | |
| return -EINVAL; | |
| + } | |
| pcie_capability_read_dword(root, PCI_EXP_DEVCAP2, &cap); | |
| if ((cap & cap_mask) != cap_mask) | |
| -- | |
| 2.53.0 | |