summaryrefslogtreecommitdiff
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorRajat Jain <rajatja@google.com>2020-07-07 15:46:04 -0700
committerBjorn Helgaas <bhelgaas@google.com>2020-09-16 16:42:22 -0500
commit76fc8e854e3b0b4641acf596d4a59f36d9939083 (patch)
tree8d7a2c6761c426cab67e039d0cec47d0341083bc /drivers/pci/quirks.c
parent9123e3a74ec7b934a4a099e98af6a61c2f80bbf5 (diff)
PCI/ACS: Enable Translation Blocking for external devices
Translation Blocking is a required feature for Downstream Ports (Root Ports or Switch Downstream Ports) that implement ACS. When enabled, the Port checks the Address Type (AT) of each upstream Memory Request it receives. The default AT (00b) means "untranslated" and the IOMMU can decide whether to treat the address as I/O virtual or physical. If AT is not the default, i.e., if the Memory Request contains an already-translated (physical) address, the Port blocks the request and reports an ACS error. When enabling ACS, enable Translation Blocking for external-facing ports and untrusted (external) devices. This is to help prevent attacks from external devices that initiate DMA with physical addresses that bypass the IOMMU. [bhelgaas: commit log, simplify setting bit and drop warning; TB is required for Downstream Ports with ACS, so we should never see the warning] Link: https://lore.kernel.org/r/20200707224604.3737893-4-rajatja@google.com Signed-off-by: Rajat Jain <rajatja@google.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index bdf9b52567e0..8f409d442bc0 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4949,6 +4949,13 @@ static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev)
}
}
+/*
+ * Currently this quirk does the equivalent of
+ * PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF
+ *
+ * TODO: This quirk also needs to do equivalent of PCI_ACS_TB,
+ * if dev->external_facing || dev->untrusted
+ */
static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
{
if (!pci_quirk_intel_pch_acs_match(dev))
@@ -4988,6 +4995,9 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
ctrl |= (cap & PCI_ACS_CR);
ctrl |= (cap & PCI_ACS_UF);
+ if (dev->external_facing || dev->untrusted)
+ ctrl |= (cap & PCI_ACS_TB);
+
pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
pci_info(dev, "Intel SPT PCH root port ACS workaround enabled\n");