diff options
author | Keshavamurthy, Anil S | 2007-10-21 16:41:55 -0700 |
---|---|---|
committer | Linus Torvalds | 2007-10-22 08:13:19 -0700 |
commit | e820482cd2621dba60e403af1c54502daa54b220 (patch) | |
tree | 3498401c7154e14008ab80b2f0cbca539ce7ffbc | |
parent | 3460a6d9cef9ac2aa997da7eff7ff1c8291b361c (diff) |
Intel IOMMU: Iommu Gfx workaround
When we fix all the opensource gfx drivers to use the DMA api's, at that time
we can yank this config options out.
[jengelh@computergmbh.de: Kconfig fixes]
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Muli Ben-Yehuda <muli@il.ibm.com>
Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/Intel-IOMMU.txt | 5 | ||||
-rw-r--r-- | arch/x86/kernel/e820_64.c | 19 | ||||
-rw-r--r-- | arch/x86_64/Kconfig | 19 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 33 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.h | 7 |
5 files changed, 79 insertions, 4 deletions
diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt index aba7722c2935..c2321903aa09 100644 --- a/Documentation/Intel-IOMMU.txt +++ b/Documentation/Intel-IOMMU.txt @@ -57,6 +57,11 @@ Graphics Problems? 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). diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c index 57616865d8a0..1ca228b06a20 100644 --- a/arch/x86/kernel/e820_64.c +++ b/arch/x86/kernel/e820_64.c @@ -729,3 +729,22 @@ __init void e820_setup_gap(void) 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; +} diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 5c9aaed589a5..5cf941774347 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -755,11 +755,22 @@ config DMAR depends on PCI_MSI && ACPI && EXPERIMENTAL default y help - DMA remapping(DMAR) devices support enables independent address - translations for Direct Memory Access(DMA) from Devices. + DMA remapping (DMAR) devices support enables independent address + translations for Direct Memory Access (DMA) from devices. These DMA remapping devices are reported via ACPI tables - and includes pci device scope covered by these DMA - remapping device. + and include PCI device scope covered by these DMA + remapping devices. + +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 APIs. 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" diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 358dd406fe21..4905e0e3a644 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1602,6 +1602,36 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, 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 = arch_get_ram_range(0, &base, &size); + while (slot >= 0) { + ret = iommu_prepare_identity_map(pdev, + base, base + size); + if (ret) + goto error; + slot = arch_get_ram_range(slot, &base, &size); + } + continue; +error: + printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); + } +} +#endif + int __init init_dmars(void) { struct dmar_drhd_unit *drhd; @@ -1665,6 +1695,8 @@ int __init init_dmars(void) } } + iommu_prepare_gfx_mapping(); + /* * for each drhd * enable fault log @@ -2176,3 +2208,4 @@ int __init intel_iommu_init(void) dma_ops = &intel_dma_ops; return 0; } + diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h index 71dda6b56ffa..ee88dd2400cb 100644 --- a/drivers/pci/intel-iommu.h +++ b/drivers/pci/intel-iommu.h @@ -315,4 +315,11 @@ struct intel_iommu { struct sys_device sysdev; }; +#ifndef CONFIG_DMAR_GFX_WA +static inline void iommu_prepare_gfx_mapping(void) +{ + return; +} +#endif /* !CONFIG_DMAR_GFX_WA */ + #endif |