Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/vt-d: Don't apply gfx quirks to untrusted devices

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>

authored by

Rajat Jain and committed by
Joerg Roedel
67e8a5b1 16ecf10e

+37
+37
drivers/iommu/intel/iommu.c
··· 6020 6020 return ret; 6021 6021 } 6022 6022 6023 + /* 6024 + * Check that the device does not live on an external facing PCI port that is 6025 + * marked as untrusted. Such devices should not be able to apply quirks and 6026 + * thus not be able to bypass the IOMMU restrictions. 6027 + */ 6028 + static bool risky_device(struct pci_dev *pdev) 6029 + { 6030 + if (pdev->untrusted) { 6031 + pci_info(pdev, 6032 + "Skipping IOMMU quirk for dev [%04X:%04X] on untrusted PCI link\n", 6033 + pdev->vendor, pdev->device); 6034 + pci_info(pdev, "Please check with your BIOS/Platform vendor about this\n"); 6035 + return true; 6036 + } 6037 + return false; 6038 + } 6039 + 6023 6040 const struct iommu_ops intel_iommu_ops = { 6024 6041 .capable = intel_iommu_capable, 6025 6042 .domain_alloc = intel_iommu_domain_alloc, ··· 6076 6059 6077 6060 static void quirk_iommu_igfx(struct pci_dev *dev) 6078 6061 { 6062 + if (risky_device(dev)) 6063 + return; 6064 + 6079 6065 pci_info(dev, "Disabling IOMMU for graphics on this chipset\n"); 6080 6066 dmar_map_gfx = 0; 6081 6067 } ··· 6120 6100 6121 6101 static void quirk_iommu_rwbf(struct pci_dev *dev) 6122 6102 { 6103 + if (risky_device(dev)) 6104 + return; 6105 + 6123 6106 /* 6124 6107 * Mobile 4 Series Chipset neglects to set RWBF capability, 6125 6108 * but needs it. Same seems to hold for the desktop versions. ··· 6152 6129 static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) 6153 6130 { 6154 6131 unsigned short ggc; 6132 + 6133 + if (risky_device(dev)) 6134 + return; 6155 6135 6156 6136 if (pci_read_config_word(dev, GGC, &ggc)) 6157 6137 return; ··· 6189 6163 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL); 6190 6164 if (!pdev) 6191 6165 return; 6166 + 6167 + if (risky_device(pdev)) { 6168 + pci_dev_put(pdev); 6169 + return; 6170 + } 6171 + 6192 6172 pci_dev_put(pdev); 6193 6173 6194 6174 /* System Management Registers. Might be hidden, in which case ··· 6203 6171 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL); 6204 6172 if (!pdev) 6205 6173 return; 6174 + 6175 + if (risky_device(pdev)) { 6176 + pci_dev_put(pdev); 6177 + return; 6178 + } 6206 6179 6207 6180 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) { 6208 6181 pci_dev_put(pdev);