[Intel-IOMMU 09/10] Iommu Gfx workaround

From: anil . s . keshavamurthy
Date: Wed Jun 06 2007 - 15:20:07 EST


When we fix all the opensource gfx drivers to use the DMA api's,
at that time we can yank this config options out.

Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@xxxxxxxxx>
---
Documentation/Intel-IOMMU.txt | 5 +++++
arch/x86_64/Kconfig | 11 +++++++++++
arch/x86_64/kernel/e820.c | 19 +++++++++++++++++++
drivers/pci/intel-iommu.c | 32 ++++++++++++++++++++++++++++++++
4 files changed, 67 insertions(+)

Index: linux-2.6.22-rc3/Documentation/Intel-IOMMU.txt
===================================================================
--- linux-2.6.22-rc3.orig/Documentation/Intel-IOMMU.txt 2007-06-04 12:40:58.000000000 -0700
+++ linux-2.6.22-rc3/Documentation/Intel-IOMMU.txt 2007-06-04 12:41:11.000000000 -0700
@@ -57,6 +57,11 @@
If you encounter issues with graphics devices, you can try adding
option intel_iommu=igfx_off to turn off the integrated graphics engine.

+If it happens to be a PCI device included in the INCLUDE_ALL Engine,
+then try enabling CONFIG_DMAR_GFX_WA to setup a 1-1 map. We hear
+graphics drivers may be in process of using DMA api's in the near
+future and at that time this option can be yanked out.
+
Some exceptions to IOVA
-----------------------
Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
Index: linux-2.6.22-rc3/arch/x86_64/Kconfig
===================================================================
--- linux-2.6.22-rc3.orig/arch/x86_64/Kconfig 2007-06-04 12:35:19.000000000 -0700
+++ linux-2.6.22-rc3/arch/x86_64/Kconfig 2007-06-04 12:41:11.000000000 -0700
@@ -727,6 +727,17 @@
and includes pci device scope covered by these DMA
remapping device.

+config DMAR_GFX_WA
+ bool "Support for Graphics workaround"
+ depends on DMAR
+ default y
+ help
+ Current Graphics drivers tend to use physical address
+ for DMA and avoid using DMA api's. Setting this config
+ option permits the IOMMU driver to set a unity map for
+ all the OS visible memory. Hence the driver can continue
+ to use physical addresses for DMA.
+
source "drivers/pci/pcie/Kconfig"

source "drivers/pci/Kconfig"
Index: linux-2.6.22-rc3/arch/x86_64/kernel/e820.c
===================================================================
--- linux-2.6.22-rc3.orig/arch/x86_64/kernel/e820.c 2007-06-04 12:19:13.000000000 -0700
+++ linux-2.6.22-rc3/arch/x86_64/kernel/e820.c 2007-06-04 12:41:11.000000000 -0700
@@ -717,3 +717,22 @@
printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
}
+
+int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
+{
+ int i;
+
+ if (slot < 0 || slot >= e820.nr_map)
+ return -1;
+ for (i = slot; i < e820.nr_map; i++) {
+ if(e820.map[i].type != E820_RAM)
+ continue;
+ break;
+ }
+ if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
+ return -1;
+ *addr = e820.map[i].addr;
+ *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
+ max_pfn << PAGE_SHIFT) - *addr;
+ return i + 1;
+}
Index: linux-2.6.22-rc3/drivers/pci/intel-iommu.c
===================================================================
--- linux-2.6.22-rc3.orig/drivers/pci/intel-iommu.c 2007-06-04 12:40:58.000000000 -0700
+++ linux-2.6.22-rc3/drivers/pci/intel-iommu.c 2007-06-04 12:41:11.000000000 -0700
@@ -1556,6 +1556,34 @@
rmrr->end_address + 1);
}

+#ifdef CONFIG_DMAR_GFX_WA
+extern int arch_get_ram_range(int slot, u64 *addr, u64 *size);
+static void __init iommu_prepare_gfx_mapping(void)
+{
+ struct pci_dev *pdev = NULL;
+ u64 base, size;
+ int slot;
+ int ret;
+
+ for_each_pci_dev(pdev) {
+ if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO ||
+ !IS_GFX_DEVICE(pdev))
+ continue;
+ printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
+ pci_name(pdev));
+ slot = 0;
+ while ((slot = arch_get_ram_range(slot, &base, &size)) >= 0) {
+ ret = iommu_prepare_identity_map(pdev, base, base + size);
+ if (ret)
+ goto error;
+ }
+ continue;
+error:
+ printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
+ }
+}
+#endif
+
int __init init_dmars(void)
{
struct dmar_drhd_unit *drhd;
@@ -1611,6 +1639,10 @@
printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
end_for_each_rmrr_device(rmrr, pdev)

+#ifdef CONFIG_DMAR_GFX_WA
+ iommu_prepare_gfx_mapping();
+#endif
+
/*
* for each drhd
* enable fault log

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/