aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/Intel-IOMMU.txt5
-rw-r--r--arch/x86/kernel/e820_64.c19
-rw-r--r--arch/x86_64/Kconfig19
-rw-r--r--drivers/pci/intel-iommu.c33
-rw-r--r--drivers/pci/intel-iommu.h7
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?
57If you encounter issues with graphics devices, you can try adding 57If you encounter issues with graphics devices, you can try adding
58option intel_iommu=igfx_off to turn off the integrated graphics engine. 58option intel_iommu=igfx_off to turn off the integrated graphics engine.
59 59
60If it happens to be a PCI device included in the INCLUDE_ALL Engine,
61then try enabling CONFIG_DMAR_GFX_WA to setup a 1-1 map. We hear
62graphics drivers may be in process of using DMA api's in the near
63future and at that time this option can be yanked out.
64
60Some exceptions to IOVA 65Some exceptions to IOVA
61----------------------- 66-----------------------
62Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff). 67Interrupt 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)
729 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", 729 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
730 pci_mem_start, gapstart, gapsize); 730 pci_mem_start, gapstart, gapsize);
731} 731}
732
733int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
734{
735 int i;
736
737 if (slot < 0 || slot >= e820.nr_map)
738 return -1;
739 for (i = slot; i < e820.nr_map; i++) {
740 if (e820.map[i].type != E820_RAM)
741 continue;
742 break;
743 }
744 if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
745 return -1;
746 *addr = e820.map[i].addr;
747 *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
748 max_pfn << PAGE_SHIFT) - *addr;
749 return i + 1;
750}
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
755 depends on PCI_MSI && ACPI && EXPERIMENTAL 755 depends on PCI_MSI && ACPI && EXPERIMENTAL
756 default y 756 default y
757 help 757 help
758 DMA remapping(DMAR) devices support enables independent address 758 DMA remapping (DMAR) devices support enables independent address
759 translations for Direct Memory Access(DMA) from Devices. 759 translations for Direct Memory Access (DMA) from devices.
760 These DMA remapping devices are reported via ACPI tables 760 These DMA remapping devices are reported via ACPI tables
761 and includes pci device scope covered by these DMA 761 and include PCI device scope covered by these DMA
762 remapping device. 762 remapping devices.
763
764config DMAR_GFX_WA
765 bool "Support for Graphics workaround"
766 depends on DMAR
767 default y
768 help
769 Current Graphics drivers tend to use physical address
770 for DMA and avoid using DMA APIs. Setting this config
771 option permits the IOMMU driver to set a unity map for
772 all the OS-visible memory. Hence the driver can continue
773 to use physical addresses for DMA.
763 774
764source "drivers/pci/pcie/Kconfig" 775source "drivers/pci/pcie/Kconfig"
765 776
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,
1602 rmrr->end_address + 1); 1602 rmrr->end_address + 1);
1603} 1603}
1604 1604
1605#ifdef CONFIG_DMAR_GFX_WA
1606extern int arch_get_ram_range(int slot, u64 *addr, u64 *size);
1607static void __init iommu_prepare_gfx_mapping(void)
1608{
1609 struct pci_dev *pdev = NULL;
1610 u64 base, size;
1611 int slot;
1612 int ret;
1613
1614 for_each_pci_dev(pdev) {
1615 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO ||
1616 !IS_GFX_DEVICE(pdev))
1617 continue;
1618 printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
1619 pci_name(pdev));
1620 slot = arch_get_ram_range(0, &base, &size);
1621 while (slot >= 0) {
1622 ret = iommu_prepare_identity_map(pdev,
1623 base, base + size);
1624 if (ret)
1625 goto error;
1626 slot = arch_get_ram_range(slot, &base, &size);
1627 }
1628 continue;
1629error:
1630 printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
1631 }
1632}
1633#endif
1634
1605int __init init_dmars(void) 1635int __init init_dmars(void)
1606{ 1636{
1607 struct dmar_drhd_unit *drhd; 1637 struct dmar_drhd_unit *drhd;
@@ -1665,6 +1695,8 @@ int __init init_dmars(void)
1665 } 1695 }
1666 } 1696 }
1667 1697
1698 iommu_prepare_gfx_mapping();
1699
1668 /* 1700 /*
1669 * for each drhd 1701 * for each drhd
1670 * enable fault log 1702 * enable fault log
@@ -2176,3 +2208,4 @@ int __init intel_iommu_init(void)
2176 dma_ops = &intel_dma_ops; 2208 dma_ops = &intel_dma_ops;
2177 return 0; 2209 return 0;
2178} 2210}
2211
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 {
315 struct sys_device sysdev; 315 struct sys_device sysdev;
316}; 316};
317 317
318#ifndef CONFIG_DMAR_GFX_WA
319static inline void iommu_prepare_gfx_mapping(void)
320{
321 return;
322}
323#endif /* !CONFIG_DMAR_GFX_WA */
324
318#endif 325#endif