]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: Allow ATS to be always on for pre-CXL devices
authorNicolin Chen <nicolinc@nvidia.com>
Thu, 21 May 2026 20:34:21 +0000 (13:34 -0700)
committerJoerg Roedel <joerg.roedel@amd.com>
Thu, 28 May 2026 07:34:42 +0000 (09:34 +0200)
Some NVIDIA GPU/NIC devices, though they don't implement CXL config space,
have many CXL-like properties. Call this kind "pre-CXL".

Similar to CXL.cache capability, these pre-CXL devices also require the ATS
function even when their RIDs are IOMMU bypassed, i.e. keep ATS "always on"
v.s. "on demand" when a non-zero PASID line gets enabled in SVA use cases.

Introduce pci_dev_specific_ats_required() quirk function to scan a list of
IDs for these devices. Then, include it in pci_ats_required().

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nirmoy Das <nirmoyd@nvidia.com>
Tested-by: Nirmoy Das <nirmoyd@nvidia.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
drivers/pci/ats.c
drivers/pci/pci.h
drivers/pci/quirks.c

index 84cd06d74fc9c7e57ee603eefddb4f2dee123a98..96efa00d974334dca6afcce2234c8fc1fe143aea 100644 (file)
@@ -247,7 +247,8 @@ bool pci_ats_required(struct pci_dev *pdev)
        if (pdev->is_virtfn)
                pdev = pci_physfn(pdev);
 
-       return pci_cxl_ats_required(pdev);
+       return pci_cxl_ats_required(pdev) ||
+              pci_dev_specific_ats_required(pdev);
 }
 EXPORT_SYMBOL_GPL(pci_ats_required);
 
index 4a14f88e543a26d0896cf5a0ed71f66455fc5593..e8ad27abb1cfe41de9aac8e3f176fe1319394387 100644 (file)
@@ -1155,6 +1155,15 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
 }
 #endif
 
+#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_PCI_ATS)
+bool pci_dev_specific_ats_required(struct pci_dev *dev);
+#else
+static inline bool pci_dev_specific_ats_required(struct pci_dev *dev)
+{
+       return false;
+}
+#endif
+
 #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
 int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
                          struct resource *res);
index caaed1a01dc026b9eb82810c95eebe839c24758f..c0242f3e9f063988824034d6ae8effa90d27accc 100644 (file)
@@ -5715,6 +5715,48 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
+
+static bool quirk_nvidia_gpu_ats_required(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       case 0x2e00 ... 0x2e3f: /* GB20B */
+               return true;
+       }
+       return false;
+}
+
+static const struct pci_dev_ats_required {
+       u16 vendor;
+       u16 device;
+       bool (*ats_required)(struct pci_dev *dev);
+} pci_dev_ats_required[] = {
+       /* NVIDIA GPUs */
+       { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, quirk_nvidia_gpu_ats_required },
+       /* NVIDIA CX10 Family NVlink-C2C */
+       { PCI_VENDOR_ID_MELLANOX, 0x2101, NULL },
+       { 0 }
+};
+
+/*
+ * Some NVIDIA devices do not implement CXL config space, but present as PCIe
+ * devices that can issue CXL-like cache operations like CXL.cache. Thus, they
+ * require ATS to obtain host physical addresses, like pci_cxl_ats_required().
+ */
+bool pci_dev_specific_ats_required(struct pci_dev *pdev)
+{
+       const struct pci_dev_ats_required *i;
+
+       for (i = pci_dev_ats_required; i->vendor; i++) {
+               if (i->vendor != pdev->vendor)
+                       continue;
+               if (i->ats_required && i->ats_required(pdev))
+                       return true;
+               if (!i->ats_required && i->device == pdev->device)
+                       return true;
+       }
+
+       return false;
+}
 #endif /* CONFIG_PCI_ATS */
 
 /* Freescale PCIe doesn't support MSI in RC mode */