--- /dev/null
+From c2a2876e863356b092967ea62bebdb4dd663af80 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <joro@8bytes.org>
+Date: Tue, 26 Mar 2013 22:48:23 +0100
+Subject: iommu/amd: Make sure dma_ops are set for hotplug devices
+
+From: Joerg Roedel <joro@8bytes.org>
+
+commit c2a2876e863356b092967ea62bebdb4dd663af80 upstream.
+
+There is a bug introduced with commit 27c2127 that causes
+devices which are hot unplugged and then hot-replugged to
+not have per-device dma_ops set. This causes these devices
+to not function correctly. Fixed with this patch.
+
+Reported-by: Andreas Degert <andreas.degert@googlemail.com>
+Signed-off-by: Joerg Roedel <joro@8bytes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/amd_iommu.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+--- a/arch/x86/kernel/amd_iommu.c
++++ b/arch/x86/kernel/amd_iommu.c
+@@ -53,6 +53,8 @@ static struct protection_domain *pt_doma
+
+ static struct iommu_ops amd_iommu_ops;
+
++static struct dma_map_ops amd_iommu_dma_ops;
++
+ /*
+ * general struct to manage commands send to an IOMMU
+ */
+@@ -1778,18 +1780,20 @@ static int device_change_notifier(struct
+
+ domain = domain_for_device(dev);
+
+- /* allocate a protection domain if a device is added */
+ dma_domain = find_protection_domain(devid);
+- if (dma_domain)
+- goto out;
+- dma_domain = dma_ops_domain_alloc();
+- if (!dma_domain)
+- goto out;
+- dma_domain->target_dev = devid;
++ if (!dma_domain) {
++ /* allocate a protection domain if a device is added */
++ dma_domain = dma_ops_domain_alloc();
++ if (!dma_domain)
++ goto out;
++ dma_domain->target_dev = devid;
++
++ spin_lock_irqsave(&iommu_pd_list_lock, flags);
++ list_add_tail(&dma_domain->list, &iommu_pd_list);
++ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
++ }
+
+- spin_lock_irqsave(&iommu_pd_list_lock, flags);
+- list_add_tail(&dma_domain->list, &iommu_pd_list);
+- spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
++ dev->archdata.dma_ops = &amd_iommu_dma_ops;
+
+ break;
+ case BUS_NOTIFY_DEL_DEVICE: