From: Joerg Roedel <jroedel@suse.de>
Date: Mon, 4 Jan 2016 16:41:51 +0100
Subject: iommu/vt-d: Don't change dma domain on dma-mask change
Patch-mainline: No, upstream code changed too much and fixed the bug differently
References: bsc#955925

When iommu=pt is used the Intel VT-d driver might switch a
device between the SI domain and an IOVA managed domain when
the dma_mask changes.
This invalidates all allocated DMA buffers and causes DMA
page faults. So don't re-assign a device back to the
si-domain when it is already in an IOVA domain.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/pci/intel-iommu.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 4ff24b2..78f1595 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -425,6 +425,19 @@ static LIST_HEAD(device_domain_list);
 
 static struct iommu_ops intel_iommu_ops;
 
+static bool device_has_dma_domain(struct pci_dev *pdev)
+{
+	struct device_domain_info *info;
+
+	info = pdev->dev.archdata.iommu;
+
+	if (!info || info == DUMMY_DEVICE_DOMAIN_INFO || !info->domain)
+		return false;
+
+	return !(info->domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
+	       !(info->domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
+}
+
 static int __init intel_iommu_setup(char *str)
 {
 	if (!str)
@@ -2885,7 +2898,8 @@ static int iommu_no_mapping(struct device *dev)
 		 * In case of a detached 64 bit DMA device from vm, the device
 		 * is put into si_domain for identity mapping.
 		 */
-		if (iommu_should_identity_map(pdev, 0)) {
+		if (iommu_should_identity_map(pdev, 0) &&
+		    !device_has_dma_domain(pdev)) {
 			int ret;
 			ret = domain_add_dev_info(si_domain, pdev,
 						  hw_pass_through ?

