Skip to content

Commit

Permalink
iommu/vt-d: Don't apply gfx quirks to untrusted devices
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Rajat Jain authored and Joerg Roedel committed Jun 23, 2020
1 parent 16ecf10 commit 67e8a5b
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions drivers/iommu/intel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6020,6 +6020,23 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain,
return ret;
}

/*
* 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,
Expand Down Expand Up @@ -6059,6 +6076,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;
}
Expand Down Expand Up @@ -6100,6 +6120,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.
Expand Down Expand Up @@ -6130,6 +6153,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;

Expand Down Expand Up @@ -6163,6 +6189,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
Expand All @@ -6172,6 +6204,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;
Expand Down

0 comments on commit 67e8a5b

Please sign in to comment.