diff options
-rw-r--r-- | arch/x86_64/Kconfig | 10 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 27 |
2 files changed, 37 insertions, 0 deletions
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 5cf94177434..c2d24991bb2 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -772,6 +772,16 @@ config DMAR_GFX_WA all the OS-visible memory. Hence the driver can continue to use physical addresses for DMA. +config DMAR_FLOPPY_WA + bool + depends on DMAR + default y + help + Floppy disk drivers are know to bypass DMA API calls + thereby failing to work when IOMMU is enabled. This + workaround will setup a 1:1 mapping for the first + 16M to make floppy (an ISA device) work. + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 4905e0e3a64..4cca5b939e0 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1632,6 +1632,31 @@ error: } #endif +#ifdef CONFIG_DMAR_FLOPPY_WA +static inline void iommu_prepare_isa(void) +{ + struct pci_dev *pdev; + int ret; + + pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); + if (!pdev) + return; + + printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n"); + ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); + + if (ret) + printk("IOMMU: Failed to create 0-64M identity map, " + "floppy might not work\n"); + +} +#else +static inline void iommu_prepare_isa(void) +{ + return; +} +#endif /* !CONFIG_DMAR_FLPY_WA */ + int __init init_dmars(void) { struct dmar_drhd_unit *drhd; @@ -1697,6 +1722,8 @@ int __init init_dmars(void) iommu_prepare_gfx_mapping(); + iommu_prepare_isa(); + /* * for each drhd * enable fault log |