Skip to content

Commit 9e852ca

Browse files
nicolincnvidia-bfigg
authored andcommitted
NVIDIA: VR: SAUCE: PCI: Allow ATS to be always on for pre-CXL devices
BugLink: https://bugs.launchpad.net/bugs/2150727 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_always_on() quirk function to scan a list of IDs for these devices. Then, include it in pci_ats_always_on(). 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> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> (backported from https://lore.kernel.org/r/1a8cf5e88051ab5c10417edb94df598ecbc810cf.1777269009.git.nicolinc@nvidia.com) [Nirmoy: Apply after reverting older ATS always-on PCI quirk support.] Signed-off-by: Nirmoy Das <nirmoyd@nvidia.com> Acked-by: Jamie Nguyen <jamien@nvidia.com> Acked-by: Carol L Soto <csoto@nvidia.com> Acked-by: Matthew R. Ochs <mochs@nvidia.com> Signed-off-by: Brad Figg <bfigg@nvidia.com>
1 parent 049df40 commit 9e852ca

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

drivers/pci/ats.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ bool pci_ats_always_on(struct pci_dev *pdev)
244244
if (pdev->is_virtfn)
245245
pdev = pci_physfn(pdev);
246246

247-
return pci_cxl_ats_always_on(pdev);
247+
return pci_cxl_ats_always_on(pdev) ||
248+
pci_dev_specific_ats_always_on(pdev);
248249
}
249250
EXPORT_SYMBOL_GPL(pci_ats_always_on);
250251

drivers/pci/pci.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,15 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
11501150
}
11511151
#endif
11521152

1153+
#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_PCI_ATS)
1154+
bool pci_dev_specific_ats_always_on(struct pci_dev *dev);
1155+
#else
1156+
static inline bool pci_dev_specific_ats_always_on(struct pci_dev *dev)
1157+
{
1158+
return false;
1159+
}
1160+
#endif
1161+
11531162
#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
11541163
int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
11551164
struct resource *res);

drivers/pci/quirks.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5729,6 +5729,44 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
57295729
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
57305730
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
57315731
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
5732+
5733+
static bool quirk_nvidia_gpu_ats_always_on(struct pci_dev *pdev)
5734+
{
5735+
switch (pdev->device) {
5736+
case 0x2e00 ... 0x2e3f: /* GB20B */
5737+
return true;
5738+
}
5739+
return false;
5740+
}
5741+
5742+
static const struct pci_dev_ats_always_on {
5743+
u16 vendor;
5744+
u16 device;
5745+
bool (*ats_always_on)(struct pci_dev *dev);
5746+
} pci_dev_ats_always_on[] = {
5747+
/* NVIDIA GPUs */
5748+
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, quirk_nvidia_gpu_ats_always_on },
5749+
/* NVIDIA CX10 Family NVlink-C2C */
5750+
{ PCI_VENDOR_ID_MELLANOX, 0x2101, NULL },
5751+
{ 0 }
5752+
};
5753+
5754+
/* Some pre-CXL devices require ATS when it is IOMMU-bypassed */
5755+
bool pci_dev_specific_ats_always_on(struct pci_dev *pdev)
5756+
{
5757+
const struct pci_dev_ats_always_on *i;
5758+
5759+
for (i = pci_dev_ats_always_on; i->vendor; i++) {
5760+
if (i->vendor != pdev->vendor)
5761+
continue;
5762+
if (i->ats_always_on && i->ats_always_on(pdev))
5763+
return true;
5764+
if (!i->ats_always_on && i->device == pdev->device)
5765+
return true;
5766+
}
5767+
5768+
return false;
5769+
}
57325770
#endif /* CONFIG_PCI_ATS */
57335771

57345772
/* Freescale PCIe doesn't support MSI in RC mode */

0 commit comments

Comments
 (0)