| From b8eb364bcecb219da8ac2f7ffbd4d06ad1eeaca1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 23 Jun 2020 07:13:42 +0800 |
| Subject: iommu/vt-d: Don't apply gfx quirks to untrusted devices |
| |
| From: Rajat Jain <rajatja@google.com> |
| |
| [ Upstream commit 67e8a5b18d41af9298db5c17193f671f235cce01 ] |
| |
| Currently, an external malicious PCI device can masquerade the VID:PID |
| of faulty gfx devices, and thus apply iommu quirks to effectively |
| disable the IOMMU restrictions for itself. |
| |
| Thus we need to ensure that the device we are applying quirks to, is |
| indeed an internal trusted device. |
| |
| Signed-off-by: Rajat Jain <rajatja@google.com> |
| Reviewed-by: Ashok Raj <ashok.raj@intel.com> |
| Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Acked-by: Lu Baolu <baolu.lu@linux.intel.com> |
| Link: https://lore.kernel.org/r/20200622231345.29722-4-baolu.lu@linux.intel.com |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/iommu/intel-iommu.c | 37 +++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 37 insertions(+) |
| |
| diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c |
| index 6366b5fbb3a46..cdc1f4736a116 100644 |
| --- a/drivers/iommu/intel-iommu.c |
| +++ b/drivers/iommu/intel-iommu.c |
| @@ -5962,6 +5962,23 @@ static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain, |
| return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO; |
| } |
| |
| +/* |
| + * Check that the device does not live on an external facing PCI port that is |
| + * marked as untrusted. Such devices should not be able to apply quirks and |
| + * thus not be able to bypass the IOMMU restrictions. |
| + */ |
| +static bool risky_device(struct pci_dev *pdev) |
| +{ |
| + if (pdev->untrusted) { |
| + pci_info(pdev, |
| + "Skipping IOMMU quirk for dev [%04X:%04X] on untrusted PCI link\n", |
| + pdev->vendor, pdev->device); |
| + pci_info(pdev, "Please check with your BIOS/Platform vendor about this\n"); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| const struct iommu_ops intel_iommu_ops = { |
| .capable = intel_iommu_capable, |
| .domain_alloc = intel_iommu_domain_alloc, |
| @@ -5990,6 +6007,9 @@ const struct iommu_ops intel_iommu_ops = { |
| |
| static void quirk_iommu_igfx(struct pci_dev *dev) |
| { |
| + if (risky_device(dev)) |
| + return; |
| + |
| pci_info(dev, "Disabling IOMMU for graphics on this chipset\n"); |
| dmar_map_gfx = 0; |
| } |
| @@ -6031,6 +6051,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); |
| |
| static void quirk_iommu_rwbf(struct pci_dev *dev) |
| { |
| + if (risky_device(dev)) |
| + return; |
| + |
| /* |
| * Mobile 4 Series Chipset neglects to set RWBF capability, |
| * but needs it. Same seems to hold for the desktop versions. |
| @@ -6061,6 +6084,9 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) |
| { |
| unsigned short ggc; |
| |
| + if (risky_device(dev)) |
| + return; |
| + |
| if (pci_read_config_word(dev, GGC, &ggc)) |
| return; |
| |
| @@ -6094,6 +6120,12 @@ static void __init check_tylersburg_isoch(void) |
| pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL); |
| if (!pdev) |
| return; |
| + |
| + if (risky_device(pdev)) { |
| + pci_dev_put(pdev); |
| + return; |
| + } |
| + |
| pci_dev_put(pdev); |
| |
| /* System Management Registers. Might be hidden, in which case |
| @@ -6103,6 +6135,11 @@ static void __init check_tylersburg_isoch(void) |
| if (!pdev) |
| return; |
| |
| + if (risky_device(pdev)) { |
| + pci_dev_put(pdev); |
| + return; |
| + } |
| + |
| if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) { |
| pci_dev_put(pdev); |
| return; |
| -- |
| 2.25.1 |
| |