From: David Woodhouse <dwmw2@infradead.org>
Date: Tue, 11 Mar 2014 17:10:29 -0700
Subject: iommu/vt-d: Be less pessimistic about domain coherency where possible
Git-commit: d05019608746240d86a406fbf8d8c1fc71a87101
Patch-mainline: v3.15-rc2
References: fate#317111

In commit 2e12bc29 ("intel-iommu: Default to non-coherent for domains
unattached to iommus") we decided to err on the side of caution and
always assume that it's possible that a device will be attached which is
behind a non-coherent IOMMU.

In some cases, however, that just *cannot* happen. If there *are* no
IOMMUs in the system which are non-coherent, then we don't need to do
it. And flushing the dcache is a *significant* performance hit.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/pci/intel-iommu.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

--- linux-3.0-SLE11-SP4.orig/drivers/pci/intel-iommu.c
+++ linux-3.0-SLE11-SP4/drivers/pci/intel-iommu.c
@@ -564,15 +564,29 @@
 
 static void domain_update_iommu_coherency(struct dmar_domain *domain)
 {
-	int i;
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu;
+	int i, found = 0;
 
 	domain->iommu_coherency = 1;
 
 	for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
+		found = 1;
 		if (!ecap_coherent(g_iommus[i]->ecap)) {
 			domain->iommu_coherency = 0;
 			break;
 		}
+	}
+
+	if (found)
+		return;
+
+	/* No hardware attached; use lowest common denominator */
+	for_each_active_iommu(iommu, drhd) {
+		if (!ecap_coherent(iommu->ecap)) {
+			domain->iommu_coherency = 0;
+			break;
+		}
 	}
 }
 
