From: Jason Gunthorpe <jgg@nvidia.com>
To: Bjorn Helgaas <bhelgaas@google.com>,
iommu@lists.linux.dev, Joerg Roedel <joro@8bytes.org>,
linux-pci@vger.kernel.org, Robin Murphy <robin.murphy@arm.com>,
Will Deacon <will@kernel.org>
Cc: Alex Williamson <alex.williamson@redhat.com>,
Lu Baolu <baolu.lu@linux.intel.com>,
Donald Dutile <ddutile@redhat.com>,
galshalom@nvidia.com, Joerg Roedel <jroedel@suse.de>,
Kevin Tian <kevin.tian@intel.com>,
kvm@vger.kernel.org, maorg@nvidia.com, patches@lists.linux.dev,
tdave@nvidia.com, Tony Zhu <tony.zhu@intel.com>
Subject: [PATCH v3 10/11] PCI: Check ACS DSP/USP redirect bits in pci_enable_pasid()
Date: Fri, 5 Sep 2025 15:06:25 -0300 [thread overview]
Message-ID: <10-v3-8827cc7fc4e0+23f-pcie_switch_groups_jgg@nvidia.com> (raw)
In-Reply-To: <0-v3-8827cc7fc4e0+23f-pcie_switch_groups_jgg@nvidia.com>
Switches ignore the PASID when routing TLPs. This means the path from the
PASID issuing end point to the IOMMU must be direct with no possibility
for another device to claim the addresses.
This is done using ACS flags and pci_enable_pasid() checks for this.
The new ACS Enhanced bits clarify some undefined behaviors in the spec
around what P2P Request Redirect means.
Linux has long assumed that PCI_ACS_RR implies PCI_ACS_DSP_MT_RR |
PCI_ACS_USP_MT_RR | PCI_ACS_UNCLAIMED_RR.
If the device supports ACS Enhanced then use the information it reports to
determine if PASID SVA is supported or not.
PCI_ACS_DSP_MT_RR: Prevents Downstream Port BAR's from claiming upstream
flowing transactions
PCI_ACS_USP_MT_RR: Prevents Upstream Port BAR's from claiming upstream
flowing transactions
PCI_ACS_UNCLAIMED_RR: Prevents a hole in the USP bridge window compared
to all the DSP bridge windows from generating a
error.
Each of these cases would poke a hole in the PASID address space which is
not permitted.
Enhance the comments around pci_acs_flags_enabled() to better explain the
reasoning for its logic. Continue to take the approach of assuming the
device is doing the "right ACS" if it does not explicitly declare
otherwise.
Fixes: 201007ef707a ("PCI: Enable PASID only when ACS RR & UF enabled on upstream path")
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/pci/ats.c | 4 +++-
drivers/pci/pci.c | 54 +++++++++++++++++++++++++++++++++++++++++------
2 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index ec6c8dbdc5e9c9..00603c2c4ff0ea 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -416,7 +416,9 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (!pasid)
return -EINVAL;
- if (!pci_acs_path_enabled(pdev, NULL, PCI_ACS_RR | PCI_ACS_UF))
+ if (!pci_acs_path_enabled(pdev, NULL,
+ PCI_ACS_RR | PCI_ACS_UF | PCI_ACS_USP_MT_RR |
+ PCI_ACS_DSP_MT_RR | PCI_ACS_UNCLAIMED_RR))
return -EINVAL;
pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 983f71211f0055..620b7f79093854 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3606,6 +3606,52 @@ void pci_configure_ari(struct pci_dev *dev)
}
}
+
+/*
+ * The spec is not clear what it means if the capability bit is 0. One view is
+ * that the device acts as though the ctrl bit is zero, another view is the
+ * device behavior is undefined.
+ *
+ * Historically Linux has taken the position that the capability bit as 0 means
+ * the device supports the most favorable interpretation of the spec - ie that
+ * things like P2P RR are always on. As this is security sensitive we expect
+ * devices that do not follow this rule to be quirked.
+ *
+ * ACS Enhanced eliminated undefined areas of the spec around MMIO in root ports
+ * and switch ports. If those ports have no MMIO then it is not relavent.
+ * PCI_ACS_UNCLAIMED_RR eliminates the undefined area around an upstream switch
+ * window that is not fully decoded by the downstream windows.
+ *
+ * This takes the same approach with ACS Enhanced, if the device does not
+ * support it then we assume the ACS P2P RR has all the enhanced behaviors too.
+ *
+ * Due to ACS Enhanced bits being force set to 0 by older Linux kernels, and
+ * those values would break old kernels on the edge cases they cover, the only
+ * compatible thing for a new device to implement is ACS Enhanced supported with
+ * the control bits (except PCI_ACS_IORB) wired to follow ACS_RR.
+ */
+static u16 pci_acs_ctrl_mask(struct pci_dev *pdev, u16 hw_cap)
+{
+ /*
+ * Egress Control enables use of the Egress Control Vector which is not
+ * present without the cap.
+ */
+ u16 mask = PCI_ACS_EC;
+
+ mask = hw_cap & (PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
+ PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
+
+ /*
+ * If ACS Enhanced is supported the device reports what it is doing
+ * through these bits which may not be settable.
+ */
+ if (hw_cap & PCI_ACS_ENHANCED)
+ mask |= PCI_ACS_IORB | PCI_ACS_DSP_MT_RB | PCI_ACS_DSP_MT_RR |
+ PCI_ACS_USP_MT_RB | PCI_ACS_USP_MT_RR |
+ PCI_ACS_UNCLAIMED_RR;
+ return mask;
+}
+
static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
{
int pos;
@@ -3615,15 +3661,9 @@ static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
if (!pos)
return false;
- /*
- * Except for egress control, capabilities are either required
- * or only required if controllable. Features missing from the
- * capability field can therefore be assumed as hard-wired enabled.
- */
pci_read_config_word(pdev, pos + PCI_ACS_CAP, &cap);
- acs_flags &= (cap | PCI_ACS_EC);
-
pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
+ acs_flags &= pci_acs_ctrl_mask(pdev, cap);
return (ctrl & acs_flags) == acs_flags;
}
--
2.43.0
next prev parent reply other threads:[~2025-09-05 18:06 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-05 18:06 [PATCH v3 00/11] Fix incorrect iommu_groups with PCIe ACS Jason Gunthorpe
2025-09-05 18:06 ` [PATCH v3 01/11] PCI: Move REQ_ACS_FLAGS into pci_regs.h as PCI_ACS_ISOLATED Jason Gunthorpe
2025-09-09 4:08 ` Donald Dutile
2025-09-05 18:06 ` [PATCH v3 02/11] PCI: Add pci_bus_isolated() Jason Gunthorpe
2025-09-09 4:09 ` Donald Dutile
2025-09-09 19:54 ` Bjorn Helgaas
2025-09-09 21:21 ` Jason Gunthorpe
2025-09-05 18:06 ` [PATCH v3 03/11] iommu: Compute iommu_groups properly for PCIe switches Jason Gunthorpe
2025-09-09 4:14 ` Donald Dutile
2025-09-09 12:18 ` Jason Gunthorpe
2025-09-09 19:33 ` Donald Dutile
2025-09-09 20:27 ` Bjorn Helgaas
2025-09-09 21:21 ` Jason Gunthorpe
2025-09-05 18:06 ` [PATCH v3 04/11] iommu: Organize iommu_group by member size Jason Gunthorpe
2025-09-09 4:16 ` Donald Dutile
2025-09-05 18:06 ` [PATCH v3 05/11] PCI: Add pci_reachable_set() Jason Gunthorpe
2025-09-09 21:03 ` Bjorn Helgaas
2025-09-10 16:13 ` Jason Gunthorpe
2025-09-11 19:56 ` Donald Dutile
2025-09-15 13:38 ` Jason Gunthorpe
2025-09-15 14:32 ` Donald Dutile
2025-09-05 18:06 ` [PATCH v3 06/11] iommu: Compute iommu_groups properly for PCIe MFDs Jason Gunthorpe
2025-09-09 4:57 ` Donald Dutile
2025-09-09 13:31 ` Jason Gunthorpe
2025-09-09 19:55 ` Donald Dutile
2025-09-09 21:24 ` Bjorn Helgaas
2025-09-09 23:20 ` Jason Gunthorpe
2025-09-10 1:59 ` Donald Dutile
2025-09-10 17:43 ` Jason Gunthorpe
2025-09-05 18:06 ` [PATCH v3 07/11] iommu: Validate that pci_for_each_dma_alias() matches the groups Jason Gunthorpe
2025-09-09 5:00 ` Donald Dutile
2025-09-09 15:35 ` Jason Gunthorpe
2025-09-09 19:58 ` Donald Dutile
2025-09-05 18:06 ` [PATCH v3 08/11] PCI: Add the ACS Enhanced Capability definitions Jason Gunthorpe
2025-09-09 5:01 ` Donald Dutile
2025-09-05 18:06 ` [PATCH v3 09/11] PCI: Enable ACS Enhanced bits for enable_acs and config_acs Jason Gunthorpe
2025-09-09 5:01 ` Donald Dutile
2025-09-05 18:06 ` Jason Gunthorpe [this message]
2025-09-09 5:02 ` [PATCH v3 10/11] PCI: Check ACS DSP/USP redirect bits in pci_enable_pasid() Donald Dutile
2025-09-09 21:43 ` Bjorn Helgaas
2025-09-10 17:34 ` Jason Gunthorpe
2025-09-11 19:50 ` Donald Dutile
2026-01-20 18:08 ` Keith Busch
2025-09-05 18:06 ` [PATCH v3 11/11] PCI: Check ACS Extended flags for pci_bus_isolated() Jason Gunthorpe
2025-09-09 5:04 ` Donald Dutile
2025-09-15 9:41 ` [PATCH v3 00/11] Fix incorrect iommu_groups with PCIe ACS Cédric Le Goater
2025-09-22 22:39 ` Alex Williamson
2025-09-23 1:44 ` Donald Dutile
2025-09-23 2:06 ` Alex Williamson
2025-09-23 2:42 ` Donald Dutile
2025-09-23 22:23 ` Alex Williamson
2025-09-30 15:23 ` Donald Dutile
2025-09-30 16:21 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=10-v3-8827cc7fc4e0+23f-pcie_switch_groups_jgg@nvidia.com \
--to=jgg@nvidia.com \
--cc=alex.williamson@redhat.com \
--cc=baolu.lu@linux.intel.com \
--cc=bhelgaas@google.com \
--cc=ddutile@redhat.com \
--cc=galshalom@nvidia.com \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=jroedel@suse.de \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=maorg@nvidia.com \
--cc=patches@lists.linux.dev \
--cc=robin.murphy@arm.com \
--cc=tdave@nvidia.com \
--cc=tony.zhu@intel.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox