Commit e820482c authored by Keshavamurthy, Anil S's avatar Keshavamurthy, Anil S Committed by Linus Torvalds

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: default avatarAnil 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: default avatarJan Engelhardt <jengelh@gmx.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3460a6d9
......@@ -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).
......
......@@ -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;
}
......@@ -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"
......
......@@ -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;
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment