diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 5cf941774347fb02c2dbb34d148abbe96fca313e..c2d24991bb2bd708f8d5485638906d95c343de50 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 4905e0e3a6446fd00c1fc83918920dca157903da..4cca5b939e0e7a0c0260c95fa615f350f4d6296c 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