intel-iommu: Add option to exclude integrated GPU only
authorBen Hutchings <ben@decadent.org.uk>
Tue, 20 Aug 2019 23:05:30 +0000 (00:05 +0100)
committerSalvatore Bonaccorso <carnil@debian.org>
Mon, 6 Jun 2022 18:45:23 +0000 (19:45 +0100)
Bug-Debian: https://bugs.debian.org/935270
Bug-Kali: https://bugs.kali.org/view.php?id=5644

There is still laptop firmware that touches the integrated GPU behind
the operating system's back, and doesn't say so in the RMRR table.
Enabling the IOMMU for all devices causes breakage, but turning it off
for all graphics devices seems like a major weakness.

Add an option, intel_iommu=intgpu_off, to exclude only integrated GPUs
from remapping.  This is a narrower exclusion than igfx_off: it only
affects Intel devices on the root bus.  Devices attached through an
external port (Thunderbolt or ExpressCard) won't be on the root bus.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Gbp-Pq: Topic features/x86
Gbp-Pq: Name intel-iommu-add-option-to-exclude-integrated-gpu-only.patch

Documentation/admin-guide/kernel-parameters.txt
drivers/iommu/intel/iommu.c

index 3f1cc5e317ed4a5ad001082c9c589b6008f68db9..82641a7f58fcb1f5d6b5223165e149fdd70712f2 100644 (file)
                        bypassed by not enabling DMAR with this option. In
                        this case, gfx device will use physical address for
                        DMA.
+               intgpu_off [Default Off]
+                       Bypass the DMAR unit for an integrated GPU only.
                strict [Default Off]
                        Deprecated, equivalent to iommu.strict=1.
                sp_off [Default Off]
index 0ea47e17b379e5edd0a90d7e292289e6a5eefa84..7f67fe7c6de7d8a324ca5b2889c8ec39ecf54be5 100644 (file)
@@ -35,6 +35,9 @@
 #define CONTEXT_SIZE           VTD_PAGE_SIZE
 
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+#define IS_INTGPU_DEVICE(pdev) (IS_GFX_DEVICE(pdev) &&         \
+                               (pdev)->vendor == 0x8086 &&     \
+                               pci_is_root_bus((pdev)->bus))
 #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
 #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@ -307,12 +310,14 @@ int intel_iommu_enabled = 0;
 EXPORT_SYMBOL_GPL(intel_iommu_enabled);
 
 static int dmar_map_gfx = 1;
+static int dmar_map_intgpu = 1;
 static int intel_iommu_superpage = 1;
 static int iommu_identity_mapping;
 static int iommu_skip_te_disable;
 
 #define IDENTMAP_GFX           2
 #define IDENTMAP_AZALIA                4
+#define IDENTMAP_INTGPU                8
 
 int intel_iommu_gfx_mapped;
 EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
@@ -381,6 +386,9 @@ static int __init intel_iommu_setup(char *str)
                } else if (!strncmp(str, "igfx_off", 8)) {
                        dmar_map_gfx = 0;
                        pr_info("Disable GFX device mapping\n");
+               } else if (!strncmp(str, "intgpu_off", 10)) {
+                       dmar_map_intgpu = 0;
+                       pr_info("Disable integrated GPU device mapping\n");
                } else if (!strncmp(str, "forcedac", 8)) {
                        pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n");
                        iommu_dma_forcedac = true;
@@ -2724,6 +2732,9 @@ static int device_def_domain_type(struct device *dev)
 
                if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
                        return IOMMU_DOMAIN_IDENTITY;
+
+               if ((iommu_identity_mapping & IDENTMAP_INTGPU) && IS_INTGPU_DEVICE(pdev))
+                       return IOMMU_DOMAIN_IDENTITY;
        }
 
        return 0;
@@ -3160,6 +3171,9 @@ static int __init init_dmars(void)
        if (!dmar_map_gfx)
                iommu_identity_mapping |= IDENTMAP_GFX;
 
+       if (!dmar_map_intgpu)
+               iommu_identity_mapping |= IDENTMAP_INTGPU;
+
        check_tylersburg_isoch();
 
        ret = si_domain_init(hw_pass_through);