linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable()
@ 2014-09-05 10:52 Joerg Roedel
  2014-09-05 10:52 ` [PATCH 01/12] iommu: Introduce iommu_capable API function Joerg Roedel
                   ` (11 more replies)
  0 siblings, 12 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

Hi,

this patch-set removes the iommu_domain_has_cap() function
from the IOMMU-API and replaces it with the new
iommu_capable() function.

The capabilities that can be queried with the
iommu_domain_has_cap() function are not domain specific, but
specific to the IOMMUs in the system, so they are not a
function of the domain. This should be reflected in the
IOMMU-API. Please review.

Thanks,

	Joerg

Joerg Roedel (12):
  iommu: Introduce iommu_capable API function
  iommu: Convert iommu-caps from define to enum
  iommu/amd: Convert to iommu_capable() API function
  iommu/arm-smmu: Convert to iommu_capable() API function
  iommu/fsl: Convert to iommu_capable() API function
  iommu/vt-d: Convert to iommu_capable() API function
  iommu/msm: Convert to iommu_capable() API function
  iommu/tegra: Convert to iommu_capable() API function
  kvm: iommu: Convert to use new iommu_capable() API function
  vfio: Convert to use new iommu_capable() API function
  IB/usnic: Convert to use new iommu_capable() API function
  iommu: Remove iommu_domain_has_cap() API function

 drivers/infiniband/hw/usnic/usnic_uiom.c |  2 +-
 drivers/iommu/amd_iommu.c                | 11 +++++-----
 drivers/iommu/arm-smmu.c                 | 35 ++++++++++++++++++++++++--------
 drivers/iommu/fsl_pamu_domain.c          |  5 ++---
 drivers/iommu/intel-iommu.c              | 13 +++++-------
 drivers/iommu/iommu.c                    | 19 ++++++++---------
 drivers/iommu/msm_iommu.c                |  7 +++----
 drivers/iommu/tegra-gart.c               |  7 +++----
 drivers/iommu/tegra-smmu.c               |  7 +++----
 drivers/vfio/vfio_iommu_type1.c          |  4 ++--
 include/linux/iommu.h                    | 25 +++++++++++------------
 virt/kvm/iommu.c                         |  6 ++----
 12 files changed, 73 insertions(+), 68 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/12] iommu: Introduce iommu_capable API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-05 10:52 ` [PATCH 02/12] iommu: Convert iommu-caps from define to enum Joerg Roedel
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

From: Joerg Roedel <jroedel@suse.de>

This function will replace the current iommu_domain_has_cap
function and clean up the interface while at it.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/iommu.c | 18 +++++++++++++++---
 include/linux/iommu.h |  7 +++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ac4adb3..1bc882e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -815,6 +815,15 @@ bool iommu_present(struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(iommu_present);
 
+bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
+{
+	if (!bus->iommu_ops || !bus->iommu_ops->capable)
+		return false;
+
+	return bus->iommu_ops->capable(cap);
+}
+EXPORT_SYMBOL_GPL(iommu_capable);
+
 /**
  * iommu_set_fault_handler() - set a fault handler for an iommu domain
  * @domain: iommu domain
@@ -948,10 +957,13 @@ EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 int iommu_domain_has_cap(struct iommu_domain *domain,
 			 unsigned long cap)
 {
-	if (unlikely(domain->ops->domain_has_cap == NULL))
-		return 0;
+	if (domain->ops->domain_has_cap != NULL)
+		return domain->ops->domain_has_cap(domain, cap);
+
+	if (domain->ops->capable != NULL)
+		return domain->ops->capable(cap);
 
-	return domain->ops->domain_has_cap(domain, cap);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 20f9a52..d43146a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -102,6 +102,7 @@ enum iommu_attr {
  * @pgsize_bitmap: bitmap of supported page sizes
  */
 struct iommu_ops {
+	bool (*capable)(enum iommu_cap);
 	int (*domain_init)(struct iommu_domain *domain);
 	void (*domain_destroy)(struct iommu_domain *domain);
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
@@ -142,6 +143,7 @@ struct iommu_ops {
 
 extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
 extern bool iommu_present(struct bus_type *bus);
+extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap);
 extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
 extern struct iommu_group *iommu_group_get_by_id(int id);
 extern void iommu_domain_free(struct iommu_domain *domain);
@@ -250,6 +252,11 @@ static inline bool iommu_present(struct bus_type *bus)
 	return false;
 }
 
+static inline bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
+{
+	return false;
+}
+
 static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
 	return NULL;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 02/12] iommu: Convert iommu-caps from define to enum
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
  2014-09-05 10:52 ` [PATCH 01/12] iommu: Introduce iommu_capable API function Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-05 10:52 ` [PATCH 03/12] iommu/amd: Convert to iommu_capable() API function Joerg Roedel
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

From: Joerg Roedel <jroedel@suse.de>

Allow compile-time type-checking.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/iommu.c |  2 +-
 include/linux/iommu.h | 11 +++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1bc882e..319d40e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -955,7 +955,7 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 
 int iommu_domain_has_cap(struct iommu_domain *domain,
-			 unsigned long cap)
+			 enum iommu_cap cap)
 {
 	if (domain->ops->domain_has_cap != NULL)
 		return domain->ops->domain_has_cap(domain, cap);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d43146a..d5534d5 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -57,8 +57,11 @@ struct iommu_domain {
 	struct iommu_domain_geometry geometry;
 };
 
-#define IOMMU_CAP_CACHE_COHERENCY	0x1
-#define IOMMU_CAP_INTR_REMAP		0x2	/* isolates device intrs */
+enum iommu_cap {
+	IOMMU_CAP_CACHE_COHERENCY,	/* IOMMU can enforce cache coherent DMA
+					   transactions */
+	IOMMU_CAP_INTR_REMAP,		/* IOMMU supports interrupt isolation */
+};
 
 /*
  * Following constraints are specifc to FSL_PAMUV1:
@@ -157,7 +160,7 @@ extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
 		       size_t size);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
 extern int iommu_domain_has_cap(struct iommu_domain *domain,
-				unsigned long cap);
+				enum iommu_cap cap);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
 			iommu_fault_handler_t handler, void *token);
 
@@ -312,7 +315,7 @@ static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_ad
 }
 
 static inline int iommu_domain_has_cap(struct iommu_domain *domain,
-				       unsigned long cap)
+				       enum iommu_cap cap)
 {
 	return 0;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 03/12] iommu/amd: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
  2014-09-05 10:52 ` [PATCH 01/12] iommu: Introduce iommu_capable API function Joerg Roedel
  2014-09-05 10:52 ` [PATCH 02/12] iommu: Convert iommu-caps from define to enum Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-05 10:52 ` [PATCH 04/12] iommu/arm-smmu: " Joerg Roedel
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

From: Joerg Roedel <jroedel@suse.de>

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/amd_iommu.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index ecb0109..7de9276 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3384,20 +3384,20 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
 	return paddr;
 }
 
-static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
-				    unsigned long cap)
+static bool amd_iommu_capable(enum iommu_cap cap)
 {
 	switch (cap) {
 	case IOMMU_CAP_CACHE_COHERENCY:
-		return 1;
+		return true;
 	case IOMMU_CAP_INTR_REMAP:
-		return irq_remapping_enabled;
+		return (irq_remapping_enabled == 1);
 	}
 
-	return 0;
+	return false;
 }
 
 static const struct iommu_ops amd_iommu_ops = {
+	.capable = amd_iommu_capable,
 	.domain_init = amd_iommu_domain_init,
 	.domain_destroy = amd_iommu_domain_destroy,
 	.attach_dev = amd_iommu_attach_device,
@@ -3405,7 +3405,6 @@ static const struct iommu_ops amd_iommu_ops = {
 	.map = amd_iommu_map,
 	.unmap = amd_iommu_unmap,
 	.iova_to_phys = amd_iommu_iova_to_phys,
-	.domain_has_cap = amd_iommu_domain_has_cap,
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 04/12] iommu/arm-smmu: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (2 preceding siblings ...)
  2014-09-05 10:52 ` [PATCH 03/12] iommu/amd: Convert to iommu_capable() API function Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-08 16:51   ` Will Deacon
  2014-09-05 10:52 ` [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function Joerg Roedel
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Will Deacon

From: Joerg Roedel <jroedel@suse.de>

Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/arm-smmu.c | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index ca18d6d..47c2cb6 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1515,20 +1515,37 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
 	return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
 }
 
-static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
-				   unsigned long cap)
+static bool arm_smmu_capable(enum iommu_cap cap)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
-	u32 features = smmu ? smmu->features : 0;
+	struct arm_smmu_device *smmu;
+	bool ret = false;
 
 	switch (cap) {
 	case IOMMU_CAP_CACHE_COHERENCY:
-		return features & ARM_SMMU_FEAT_COHERENT_WALK;
+		/*
+		 * Use ARM_SMMU_FEAT_COHERENT_WALK as an indicator on whether
+		 * the SMMU can force coherency on the DMA transaction. If it
+		 * supports COHERENT_WALK it must be behind a coherent
+		 * interconnect.
+		 * A domain can be attached to any SMMU, so to reliably support
+		 * IOMMU_CAP_CACHE_COHERENCY all SMMUs in the system need to be
+		 * behind a coherent interconnect.
+		 */
+		spin_lock(&arm_smmu_devices_lock);
+		list_for_each_entry(smmu, &arm_smmu_devices, list) {
+			if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) {
+				ret = true;
+			} else {
+				ret = false;
+				break;
+			}
+		}
+		spin_unlock(&arm_smmu_devices_lock);
+		return ret;
 	case IOMMU_CAP_INTR_REMAP:
-		return 1; /* MSIs are just memory writes */
+		return true; /* MSIs are just memory writes */
 	default:
-		return 0;
+		return false;
 	}
 }
 
@@ -1598,6 +1615,7 @@ static void arm_smmu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops arm_smmu_ops = {
+	.capable	= arm_smmu_capable,
 	.domain_init	= arm_smmu_domain_init,
 	.domain_destroy	= arm_smmu_domain_destroy,
 	.attach_dev	= arm_smmu_attach_dev,
@@ -1605,7 +1623,6 @@ static const struct iommu_ops arm_smmu_ops = {
 	.map		= arm_smmu_map,
 	.unmap		= arm_smmu_unmap,
 	.iova_to_phys	= arm_smmu_iova_to_phys,
-	.domain_has_cap	= arm_smmu_domain_has_cap,
 	.add_device	= arm_smmu_add_device,
 	.remove_device	= arm_smmu_remove_device,
 	.pgsize_bitmap	= (SECTION_SIZE |
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (3 preceding siblings ...)
  2014-09-05 10:52 ` [PATCH 04/12] iommu/arm-smmu: " Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-09 18:38   ` Varun Sethi
  2014-09-05 10:52 ` [PATCH 06/12] iommu/vt-d: " Joerg Roedel
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Varun Sethi

From: Joerg Roedel <jroedel@suse.de>

Cc: Varun Sethi <Varun.Sethi@freescale.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/fsl_pamu_domain.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 61d1daf..f43a80d 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -411,8 +411,7 @@ static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
 	return get_phys_addr(dma_domain, iova);
 }
 
-static int fsl_pamu_domain_has_cap(struct iommu_domain *domain,
-				      unsigned long cap)
+static bool fsl_pamu_capable(enum iommu_cap cap)
 {
 	return cap == IOMMU_CAP_CACHE_COHERENCY;
 }
@@ -1074,6 +1073,7 @@ static u32 fsl_pamu_get_windows(struct iommu_domain *domain)
 }
 
 static const struct iommu_ops fsl_pamu_ops = {
+	.capable	= fsl_pamu_capable,
 	.domain_init	= fsl_pamu_domain_init,
 	.domain_destroy = fsl_pamu_domain_destroy,
 	.attach_dev	= fsl_pamu_attach_device,
@@ -1083,7 +1083,6 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.domain_get_windows = fsl_pamu_get_windows,
 	.domain_set_windows = fsl_pamu_set_windows,
 	.iova_to_phys	= fsl_pamu_iova_to_phys,
-	.domain_has_cap = fsl_pamu_domain_has_cap,
 	.domain_set_attr = fsl_pamu_set_domain_attr,
 	.domain_get_attr = fsl_pamu_get_domain_attr,
 	.add_device	= fsl_pamu_add_device,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 06/12] iommu/vt-d: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (4 preceding siblings ...)
  2014-09-05 10:52 ` [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-05 10:52 ` [PATCH 07/12] iommu/msm: " Joerg Roedel
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Jiang Liu, David Woodhouse

From: Joerg Roedel <jroedel@suse.de>

Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/intel-iommu.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 5619f26..bc1a203 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4415,17 +4415,14 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
 	return phys;
 }
 
-static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
-				      unsigned long cap)
+static bool intel_iommu_capable(enum iommu_cap cap)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
-
 	if (cap == IOMMU_CAP_CACHE_COHERENCY)
-		return dmar_domain->iommu_snooping;
+		return domain_update_iommu_snooping(NULL) == 1;
 	if (cap == IOMMU_CAP_INTR_REMAP)
-		return irq_remapping_enabled;
+		return irq_remapping_enabled == 1;
 
-	return 0;
+	return false;
 }
 
 static int intel_iommu_add_device(struct device *dev)
@@ -4464,6 +4461,7 @@ static void intel_iommu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops intel_iommu_ops = {
+	.capable	= intel_iommu_capable,
 	.domain_init	= intel_iommu_domain_init,
 	.domain_destroy = intel_iommu_domain_destroy,
 	.attach_dev	= intel_iommu_attach_device,
@@ -4471,7 +4469,6 @@ static const struct iommu_ops intel_iommu_ops = {
 	.map		= intel_iommu_map,
 	.unmap		= intel_iommu_unmap,
 	.iova_to_phys	= intel_iommu_iova_to_phys,
-	.domain_has_cap = intel_iommu_domain_has_cap,
 	.add_device	= intel_iommu_add_device,
 	.remove_device	= intel_iommu_remove_device,
 	.pgsize_bitmap	= INTEL_IOMMU_PGSIZES,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 07/12] iommu/msm: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (5 preceding siblings ...)
  2014-09-05 10:52 ` [PATCH 06/12] iommu/vt-d: " Joerg Roedel
@ 2014-09-05 10:52 ` Joerg Roedel
  2014-09-05 10:53 ` [PATCH 08/12] iommu/tegra: " Joerg Roedel
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:52 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

From: Joerg Roedel <jroedel@suse.de>

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/msm_iommu.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 49f41d6..6e3dcc28 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -603,10 +603,9 @@ fail:
 	return ret;
 }
 
-static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
-				    unsigned long cap)
+static bool msm_iommu_capable(enum iommu_cap cap)
 {
-	return 0;
+	return false;
 }
 
 static void print_ctx_regs(void __iomem *base, int ctx)
@@ -675,6 +674,7 @@ fail:
 }
 
 static const struct iommu_ops msm_iommu_ops = {
+	.capable = msm_iommu_capable,
 	.domain_init = msm_iommu_domain_init,
 	.domain_destroy = msm_iommu_domain_destroy,
 	.attach_dev = msm_iommu_attach_dev,
@@ -682,7 +682,6 @@ static const struct iommu_ops msm_iommu_ops = {
 	.map = msm_iommu_map,
 	.unmap = msm_iommu_unmap,
 	.iova_to_phys = msm_iommu_iova_to_phys,
-	.domain_has_cap = msm_iommu_domain_has_cap,
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 08/12] iommu/tegra: Convert to iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (6 preceding siblings ...)
  2014-09-05 10:52 ` [PATCH 07/12] iommu/msm: " Joerg Roedel
@ 2014-09-05 10:53 ` Joerg Roedel
  2014-09-05 10:53 ` [PATCH 09/12] kvm: iommu: Convert to use new " Joerg Roedel
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:53 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Hiroshi Doyu

From: Joerg Roedel <jroedel@suse.de>

Cc: Hiroshi Doyu <hdoyu@nvidia.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/tegra-gart.c | 7 +++----
 drivers/iommu/tegra-smmu.c | 7 +++----
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index b10a8ec..6f44ebb 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -303,13 +303,13 @@ static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
 	return pa;
 }
 
-static int gart_iommu_domain_has_cap(struct iommu_domain *domain,
-				     unsigned long cap)
+static bool gart_iommu_capable(enum iommu_cap cap)
 {
-	return 0;
+	return false;
 }
 
 static const struct iommu_ops gart_iommu_ops = {
+	.capable	= gart_iommu_capable,
 	.domain_init	= gart_iommu_domain_init,
 	.domain_destroy	= gart_iommu_domain_destroy,
 	.attach_dev	= gart_iommu_attach_dev,
@@ -317,7 +317,6 @@ static const struct iommu_ops gart_iommu_ops = {
 	.map		= gart_iommu_map,
 	.unmap		= gart_iommu_unmap,
 	.iova_to_phys	= gart_iommu_iova_to_phys,
-	.domain_has_cap	= gart_iommu_domain_has_cap,
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 };
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 3ded389..05d14e1 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -780,10 +780,9 @@ static phys_addr_t smmu_iommu_iova_to_phys(struct iommu_domain *domain,
 	return PFN_PHYS(pfn);
 }
 
-static int smmu_iommu_domain_has_cap(struct iommu_domain *domain,
-				     unsigned long cap)
+static bool smmu_iommu_capable(enum iommu_cap cap)
 {
-	return 0;
+	return false;
 }
 
 static int smmu_iommu_attach_dev(struct iommu_domain *domain,
@@ -949,6 +948,7 @@ static void smmu_iommu_domain_destroy(struct iommu_domain *domain)
 }
 
 static const struct iommu_ops smmu_iommu_ops = {
+	.capable	= smmu_iommu_capable,
 	.domain_init	= smmu_iommu_domain_init,
 	.domain_destroy	= smmu_iommu_domain_destroy,
 	.attach_dev	= smmu_iommu_attach_dev,
@@ -956,7 +956,6 @@ static const struct iommu_ops smmu_iommu_ops = {
 	.map		= smmu_iommu_map,
 	.unmap		= smmu_iommu_unmap,
 	.iova_to_phys	= smmu_iommu_iova_to_phys,
-	.domain_has_cap	= smmu_iommu_domain_has_cap,
 	.pgsize_bitmap	= SMMU_IOMMU_PGSIZES,
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 09/12] kvm: iommu: Convert to use new iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (7 preceding siblings ...)
  2014-09-05 10:53 ` [PATCH 08/12] iommu/tegra: " Joerg Roedel
@ 2014-09-05 10:53 ` Joerg Roedel
  2014-09-17  8:29   ` Joerg Roedel
  2014-09-05 10:53 ` [PATCH 10/12] vfio: " Joerg Roedel
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:53 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Gleb Natapov, Paolo Bonzini

From: Joerg Roedel <jroedel@suse.de>

Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 virt/kvm/iommu.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index 714b949..45ee080 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -191,8 +191,7 @@ int kvm_assign_device(struct kvm *kvm,
 		return r;
 	}
 
-	noncoherent = !iommu_domain_has_cap(kvm->arch.iommu_domain,
-					    IOMMU_CAP_CACHE_COHERENCY);
+	noncoherent = !iommu_capable(&pci_bus_type, IOMMU_CAP_CACHE_COHERENCY);
 
 	/* Check if need to update IOMMU page table for guest memory */
 	if (noncoherent != kvm->arch.iommu_noncoherent) {
@@ -254,8 +253,7 @@ int kvm_iommu_map_guest(struct kvm *kvm)
 	}
 
 	if (!allow_unsafe_assigned_interrupts &&
-	    !iommu_domain_has_cap(kvm->arch.iommu_domain,
-				  IOMMU_CAP_INTR_REMAP)) {
+	    !iommu_capable(&pci_bus_type, IOMMU_CAP_INTR_REMAP)) {
 		printk(KERN_WARNING "%s: No interrupt remapping support,"
 		       " disallowing device assignment."
 		       " Re-enble with \"allow_unsafe_assigned_interrupts=1\""
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 10/12] vfio: Convert to use new iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (8 preceding siblings ...)
  2014-09-05 10:53 ` [PATCH 09/12] kvm: iommu: Convert to use new " Joerg Roedel
@ 2014-09-05 10:53 ` Joerg Roedel
  2014-09-08 23:14   ` Alex Williamson
  2014-09-05 10:53 ` [PATCH 11/12] IB/usnic: " Joerg Roedel
  2014-09-05 10:53 ` [PATCH 12/12] iommu: Remove iommu_domain_has_cap() " Joerg Roedel
  11 siblings, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:53 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Alex Williamson

From: Joerg Roedel <jroedel@suse.de>

Cc: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/vfio/vfio_iommu_type1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 0734fbe..562f686 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -713,14 +713,14 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	list_add(&group->next, &domain->group_list);
 
 	if (!allow_unsafe_interrupts &&
-	    !iommu_domain_has_cap(domain->domain, IOMMU_CAP_INTR_REMAP)) {
+	    !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
 		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
 		       __func__);
 		ret = -EPERM;
 		goto out_detach;
 	}
 
-	if (iommu_domain_has_cap(domain->domain, IOMMU_CAP_CACHE_COHERENCY))
+	if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
 		domain->prot |= IOMMU_CACHE;
 
 	/*
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 11/12] IB/usnic: Convert to use new iommu_capable() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (9 preceding siblings ...)
  2014-09-05 10:53 ` [PATCH 10/12] vfio: " Joerg Roedel
@ 2014-09-05 10:53 ` Joerg Roedel
  2014-09-17  8:30   ` Joerg Roedel
  2014-09-05 10:53 ` [PATCH 12/12] iommu: Remove iommu_domain_has_cap() " Joerg Roedel
  11 siblings, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:53 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel, Upinder Malhi

From: Joerg Roedel <jroedel@suse.de>

Cc: Upinder Malhi <umalhi@cisco.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/infiniband/hw/usnic/usnic_uiom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index 801a1d6..417de1f 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -507,7 +507,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev)
 	if (err)
 		goto out_free_dev;
 
-	if (!iommu_domain_has_cap(pd->domain, IOMMU_CAP_CACHE_COHERENCY)) {
+	if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) {
 		usnic_err("IOMMU of %s does not support cache coherency\n",
 				dev_name(dev));
 		err = -EINVAL;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 12/12] iommu: Remove iommu_domain_has_cap() API function
  2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
                   ` (10 preceding siblings ...)
  2014-09-05 10:53 ` [PATCH 11/12] IB/usnic: " Joerg Roedel
@ 2014-09-05 10:53 ` Joerg Roedel
  11 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-05 10:53 UTC (permalink / raw)
  To: iommu; +Cc: linux-kernel, Joerg Roedel

From: Joerg Roedel <jroedel@suse.de>

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/iommu.c | 13 -------------
 include/linux/iommu.h | 11 -----------
 2 files changed, 24 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 319d40e..41c6a7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -954,19 +954,6 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
 }
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 
-int iommu_domain_has_cap(struct iommu_domain *domain,
-			 enum iommu_cap cap)
-{
-	if (domain->ops->domain_has_cap != NULL)
-		return domain->ops->domain_has_cap(domain, cap);
-
-	if (domain->ops->capable != NULL)
-		return domain->ops->capable(cap);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
-
 static size_t iommu_pgsize(struct iommu_domain *domain,
 			   unsigned long addr_merge, size_t size)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d5534d5..379a617 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -97,7 +97,6 @@ enum iommu_attr {
  * @map: map a physically contiguous memory region to an iommu domain
  * @unmap: unmap a physically contiguous memory region from an iommu domain
  * @iova_to_phys: translate iova to physical address
- * @domain_has_cap: domain capabilities query
  * @add_device: add device to iommu grouping
  * @remove_device: remove device from iommu grouping
  * @domain_get_attr: Query domain attributes
@@ -115,8 +114,6 @@ struct iommu_ops {
 	size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
 		     size_t size);
 	phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
-	int (*domain_has_cap)(struct iommu_domain *domain,
-			      unsigned long cap);
 	int (*add_device)(struct device *dev);
 	void (*remove_device)(struct device *dev);
 	int (*device_group)(struct device *dev, unsigned int *groupid);
@@ -159,8 +156,6 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
 extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
 		       size_t size);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
-extern int iommu_domain_has_cap(struct iommu_domain *domain,
-				enum iommu_cap cap);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
 			iommu_fault_handler_t handler, void *token);
 
@@ -314,12 +309,6 @@ static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_ad
 	return 0;
 }
 
-static inline int iommu_domain_has_cap(struct iommu_domain *domain,
-				       enum iommu_cap cap)
-{
-	return 0;
-}
-
 static inline void iommu_set_fault_handler(struct iommu_domain *domain,
 				iommu_fault_handler_t handler, void *token)
 {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 04/12] iommu/arm-smmu: Convert to iommu_capable() API function
  2014-09-05 10:52 ` [PATCH 04/12] iommu/arm-smmu: " Joerg Roedel
@ 2014-09-08 16:51   ` Will Deacon
  2014-09-09 13:57     ` Joerg Roedel
  2014-09-17  8:53     ` [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function Joerg Roedel
  0 siblings, 2 replies; 22+ messages in thread
From: Will Deacon @ 2014-09-08 16:51 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel, Joerg Roedel, devicetree

Hi Joerg,

[adding devicetree for the last paragraph]

On Fri, Sep 05, 2014 at 11:52:56AM +0100, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/arm-smmu.c | 35 ++++++++++++++++++++++++++---------
>  1 file changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index ca18d6d..47c2cb6 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1515,20 +1515,37 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
>  	return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
>  }
>  
> -static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
> -				   unsigned long cap)
> +static bool arm_smmu_capable(enum iommu_cap cap)
>  {
> -	struct arm_smmu_domain *smmu_domain = domain->priv;
> -	struct arm_smmu_device *smmu = smmu_domain->smmu;
> -	u32 features = smmu ? smmu->features : 0;
> +	struct arm_smmu_device *smmu;
> +	bool ret = false;
>  
>  	switch (cap) {
>  	case IOMMU_CAP_CACHE_COHERENCY:
> -		return features & ARM_SMMU_FEAT_COHERENT_WALK;
> +		/*
> +		 * Use ARM_SMMU_FEAT_COHERENT_WALK as an indicator on whether
> +		 * the SMMU can force coherency on the DMA transaction. If it
> +		 * supports COHERENT_WALK it must be behind a coherent
> +		 * interconnect.
> +		 * A domain can be attached to any SMMU, so to reliably support
> +		 * IOMMU_CAP_CACHE_COHERENCY all SMMUs in the system need to be
> +		 * behind a coherent interconnect.
> +		 */

I don't think we should rely on the SMMU's advertisement of the coherent
table walk to mean anything other than `the SMMU can emit cacheable page
table walks'. The actual walker is a separate observer, and could have a
different route to memory than transactions flowing through the SMMU.

In reality, all we can report here is what the SMMU (as opposed to the rest
of the system) is capable of. The SMMU can always emit cacheable
transactions for a master if a stage-1 translation is in use so, without
extending the device-tree binding, we should report true here
unconditionally.

An alternative is to extend the device-tree bindings to have something like
"dma-coherent" for the SMMU node, which would imply that the interconnect is
configured to honour snoops from the SMMU into the CPU caches. We might want
an additional property on top of that to indicate that the table walker is
also coherent (and we could check this against our ARM_SMMU_FEAT_COHERENT_WALK
flag)

Will

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 10/12] vfio: Convert to use new iommu_capable() API function
  2014-09-05 10:53 ` [PATCH 10/12] vfio: " Joerg Roedel
@ 2014-09-08 23:14   ` Alex Williamson
  0 siblings, 0 replies; 22+ messages in thread
From: Alex Williamson @ 2014-09-08 23:14 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel, Joerg Roedel

On Fri, 2014-09-05 at 12:53 +0200, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>

Nice, we can do some further simplifications if I no longer need to
create a domain and add properties to it in order to test capabilities,
but that can all be done later.

Acked-by: Alex Williamson <alex.williamson@redhat.com>

> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 0734fbe..562f686 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -713,14 +713,14 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>  	list_add(&group->next, &domain->group_list);
>  
>  	if (!allow_unsafe_interrupts &&
> -	    !iommu_domain_has_cap(domain->domain, IOMMU_CAP_INTR_REMAP)) {
> +	    !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
>  		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
>  		       __func__);
>  		ret = -EPERM;
>  		goto out_detach;
>  	}
>  
> -	if (iommu_domain_has_cap(domain->domain, IOMMU_CAP_CACHE_COHERENCY))
> +	if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
>  		domain->prot |= IOMMU_CACHE;
>  
>  	/*




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 04/12] iommu/arm-smmu: Convert to iommu_capable() API function
  2014-09-08 16:51   ` Will Deacon
@ 2014-09-09 13:57     ` Joerg Roedel
  2014-09-17  8:53     ` [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function Joerg Roedel
  1 sibling, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-09 13:57 UTC (permalink / raw)
  To: Will Deacon; +Cc: Joerg Roedel, iommu, linux-kernel, devicetree

Hi Will,

On Mon, Sep 08, 2014 at 05:51:36PM +0100, Will Deacon wrote:
> On Fri, Sep 05, 2014 at 11:52:56AM +0100, Joerg Roedel wrote:
> >  	switch (cap) {
> >  	case IOMMU_CAP_CACHE_COHERENCY:
> > -		return features & ARM_SMMU_FEAT_COHERENT_WALK;
> > +		/*
> > +		 * Use ARM_SMMU_FEAT_COHERENT_WALK as an indicator on whether
> > +		 * the SMMU can force coherency on the DMA transaction. If it
> > +		 * supports COHERENT_WALK it must be behind a coherent
> > +		 * interconnect.
> > +		 * A domain can be attached to any SMMU, so to reliably support
> > +		 * IOMMU_CAP_CACHE_COHERENCY all SMMUs in the system need to be
> > +		 * behind a coherent interconnect.
> > +		 */
> 
> I don't think we should rely on the SMMU's advertisement of the coherent
> table walk to mean anything other than `the SMMU can emit cacheable page
> table walks'. The actual walker is a separate observer, and could have a
> different route to memory than transactions flowing through the SMMU.

Okay, so this should be advertised via DT then.

> In reality, all we can report here is what the SMMU (as opposed to the rest
> of the system) is capable of. The SMMU can always emit cacheable
> transactions for a master if a stage-1 translation is in use so, without
> extending the device-tree binding, we should report true here
> unconditionally.

Sounds more like we should return false here unconditionally until we
have a reliable way to tell whether this feature is available, no? When
we return true the user of the IOMMU-API might rely on coherency that is
not available.

> An alternative is to extend the device-tree bindings to have something like
> "dma-coherent" for the SMMU node, which would imply that the interconnect is
> configured to honour snoops from the SMMU into the CPU caches. We might want
> an additional property on top of that to indicate that the table walker is
> also coherent (and we could check this against our ARM_SMMU_FEAT_COHERENT_WALK
> flag)

Sounds like a good idea, as long as there is no other way to detect
this.


	Joerg


^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function
  2014-09-05 10:52 ` [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function Joerg Roedel
@ 2014-09-09 18:38   ` Varun Sethi
  0 siblings, 0 replies; 22+ messages in thread
From: Varun Sethi @ 2014-09-09 18:38 UTC (permalink / raw)
  To: Joerg Roedel, iommu; +Cc: linux-kernel, Joerg Roedel



> -----Original Message-----
> From: Joerg Roedel [mailto:joro@8bytes.org]
> Sent: Friday, September 05, 2014 4:23 PM
> To: iommu@lists.linux-foundation.org
> Cc: linux-kernel@vger.kernel.org; Joerg Roedel; Sethi Varun-B16395
> Subject: [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function
> 
> From: Joerg Roedel <jroedel@suse.de>
> 
> Cc: Varun Sethi <Varun.Sethi@freescale.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/fsl_pamu_domain.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/fsl_pamu_domain.c
> b/drivers/iommu/fsl_pamu_domain.c index 61d1daf..f43a80d 100644
> --- a/drivers/iommu/fsl_pamu_domain.c
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -411,8 +411,7 @@ static phys_addr_t fsl_pamu_iova_to_phys(struct
> iommu_domain *domain,
>  	return get_phys_addr(dma_domain, iova);  }
> 
> -static int fsl_pamu_domain_has_cap(struct iommu_domain *domain,
> -				      unsigned long cap)
> +static bool fsl_pamu_capable(enum iommu_cap cap)
>  {
>  	return cap == IOMMU_CAP_CACHE_COHERENCY;  } @@ -1074,6
> +1073,7 @@ static u32 fsl_pamu_get_windows(struct iommu_domain
> *domain)  }
> 
>  static const struct iommu_ops fsl_pamu_ops = {
> +	.capable	= fsl_pamu_capable,
>  	.domain_init	= fsl_pamu_domain_init,
>  	.domain_destroy = fsl_pamu_domain_destroy,
>  	.attach_dev	= fsl_pamu_attach_device,
> @@ -1083,7 +1083,6 @@ static const struct iommu_ops fsl_pamu_ops = {
>  	.domain_get_windows = fsl_pamu_get_windows,
>  	.domain_set_windows = fsl_pamu_set_windows,
>  	.iova_to_phys	= fsl_pamu_iova_to_phys,
> -	.domain_has_cap = fsl_pamu_domain_has_cap,
>  	.domain_set_attr = fsl_pamu_set_domain_attr,
>  	.domain_get_attr = fsl_pamu_get_domain_attr,
>  	.add_device	= fsl_pamu_add_device,
Acked-by: Varun Sethi <varun.sethi@freescale.com>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 09/12] kvm: iommu: Convert to use new iommu_capable() API function
  2014-09-05 10:53 ` [PATCH 09/12] kvm: iommu: Convert to use new " Joerg Roedel
@ 2014-09-17  8:29   ` Joerg Roedel
  0 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-17  8:29 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel, Gleb Natapov, Paolo Bonzini

Hi Paolo, Gleb,

On Fri, Sep 05, 2014 at 12:53:01PM +0200, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Cc: Gleb Natapov <gleb@kernel.org>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  virt/kvm/iommu.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)

Do you have any objections against this patch? I would like to put this
series into the iommu tree.


Thanks,

	Joerg

> 
> diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
> index 714b949..45ee080 100644
> --- a/virt/kvm/iommu.c
> +++ b/virt/kvm/iommu.c
> @@ -191,8 +191,7 @@ int kvm_assign_device(struct kvm *kvm,
>  		return r;
>  	}
>  
> -	noncoherent = !iommu_domain_has_cap(kvm->arch.iommu_domain,
> -					    IOMMU_CAP_CACHE_COHERENCY);
> +	noncoherent = !iommu_capable(&pci_bus_type, IOMMU_CAP_CACHE_COHERENCY);
>  
>  	/* Check if need to update IOMMU page table for guest memory */
>  	if (noncoherent != kvm->arch.iommu_noncoherent) {
> @@ -254,8 +253,7 @@ int kvm_iommu_map_guest(struct kvm *kvm)
>  	}
>  
>  	if (!allow_unsafe_assigned_interrupts &&
> -	    !iommu_domain_has_cap(kvm->arch.iommu_domain,
> -				  IOMMU_CAP_INTR_REMAP)) {
> +	    !iommu_capable(&pci_bus_type, IOMMU_CAP_INTR_REMAP)) {
>  		printk(KERN_WARNING "%s: No interrupt remapping support,"
>  		       " disallowing device assignment."
>  		       " Re-enble with \"allow_unsafe_assigned_interrupts=1\""
> -- 
> 1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 11/12] IB/usnic: Convert to use new iommu_capable() API function
  2014-09-05 10:53 ` [PATCH 11/12] IB/usnic: " Joerg Roedel
@ 2014-09-17  8:30   ` Joerg Roedel
  0 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-17  8:30 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel, Upinder Malhi

Hi,

On Fri, Sep 05, 2014 at 12:53:03PM +0200, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Cc: Upinder Malhi <umalhi@cisco.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/infiniband/hw/usnic/usnic_uiom.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
> index 801a1d6..417de1f 100644
> --- a/drivers/infiniband/hw/usnic/usnic_uiom.c
> +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
> @@ -507,7 +507,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev)
>  	if (err)
>  		goto out_free_dev;
>  
> -	if (!iommu_domain_has_cap(pd->domain, IOMMU_CAP_CACHE_COHERENCY)) {
> +	if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) {
>  		usnic_err("IOMMU of %s does not support cache coherency\n",
>  				dev_name(dev));
>  		err = -EINVAL;

Any objections against this? I would like to apply this series to the
iommu tree.


	Joerg

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function
  2014-09-08 16:51   ` Will Deacon
  2014-09-09 13:57     ` Joerg Roedel
@ 2014-09-17  8:53     ` Joerg Roedel
  2014-09-19 16:42       ` Will Deacon
  1 sibling, 1 reply; 22+ messages in thread
From: Joerg Roedel @ 2014-09-17  8:53 UTC (permalink / raw)
  To: Will Deacon; +Cc: Joerg Roedel, iommu, linux-kernel, devicetree

Hi Will,

On Mon, Sep 08, 2014 at 05:51:36PM +0100, Will Deacon wrote:
> Hi Joerg,
> 
> [adding devicetree for the last paragraph]
> 
> On Fri, Sep 05, 2014 at 11:52:56AM +0100, Joerg Roedel wrote:
> > From: Joerg Roedel <jroedel@suse.de>
> > 
> > Cc: Will Deacon <will.deacon@arm.com>
> > Signed-off-by: Joerg Roedel <jroedel@suse.de>
> > ---
> >  drivers/iommu/arm-smmu.c | 35 ++++++++++++++++++++++++++---------
> >  1 file changed, 26 insertions(+), 9 deletions(-)

Okay, so here is the updated patch:

>From b5d895980849ba1a46a5250cd4cc5f3f9f28235d Mon Sep 17 00:00:00 2001
From: Joerg Roedel <jroedel@suse.de>
Date: Fri, 5 Sep 2014 10:49:34 +0200
Subject: [PATCH 04/13] iommu/arm-smmu: Convert to iommu_capable() API function

Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/arm-smmu.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a83cc2a..f5cacf4 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1526,20 +1526,20 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
 	return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
 }
 
-static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
-				   unsigned long cap)
+static bool arm_smmu_capable(enum iommu_cap cap)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
-	u32 features = smmu ? smmu->features : 0;
-
 	switch (cap) {
 	case IOMMU_CAP_CACHE_COHERENCY:
-		return features & ARM_SMMU_FEAT_COHERENT_WALK;
+		/*
+		 * Return false here until we have a way to find out whether the
+		 * SMMUs in the system a coherently connected and able to force
+		 * DMA coherency.
+		 */
+		return false;
 	case IOMMU_CAP_INTR_REMAP:
-		return 1; /* MSIs are just memory writes */
+		return true; /* MSIs are just memory writes */
 	default:
-		return 0;
+		return false;
 	}
 }
 
@@ -1609,6 +1609,7 @@ static void arm_smmu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops arm_smmu_ops = {
+	.capable	= arm_smmu_capable,
 	.domain_init	= arm_smmu_domain_init,
 	.domain_destroy	= arm_smmu_domain_destroy,
 	.attach_dev	= arm_smmu_attach_dev,
@@ -1616,7 +1617,6 @@ static const struct iommu_ops arm_smmu_ops = {
 	.map		= arm_smmu_map,
 	.unmap		= arm_smmu_unmap,
 	.iova_to_phys	= arm_smmu_iova_to_phys,
-	.domain_has_cap	= arm_smmu_domain_has_cap,
 	.add_device	= arm_smmu_add_device,
 	.remove_device	= arm_smmu_remove_device,
 	.pgsize_bitmap	= (SECTION_SIZE |
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function
  2014-09-17  8:53     ` [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function Joerg Roedel
@ 2014-09-19 16:42       ` Will Deacon
  2014-09-22 15:36         ` Joerg Roedel
  0 siblings, 1 reply; 22+ messages in thread
From: Will Deacon @ 2014-09-19 16:42 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Joerg Roedel, iommu, linux-kernel, devicetree

On Wed, Sep 17, 2014 at 09:53:12AM +0100, Joerg Roedel wrote:
> Hi Will,

Hello Joerg,

> On Mon, Sep 08, 2014 at 05:51:36PM +0100, Will Deacon wrote:
> > On Fri, Sep 05, 2014 at 11:52:56AM +0100, Joerg Roedel wrote:
> > > From: Joerg Roedel <jroedel@suse.de>
> > > 
> > > Cc: Will Deacon <will.deacon@arm.com>
> > > Signed-off-by: Joerg Roedel <jroedel@suse.de>
> > > ---
> > >  drivers/iommu/arm-smmu.c | 35 ++++++++++++++++++++++++++---------
> > >  1 file changed, 26 insertions(+), 9 deletions(-)
> 
> Okay, so here is the updated patch:

Thanks, comments inline.

> From b5d895980849ba1a46a5250cd4cc5f3f9f28235d Mon Sep 17 00:00:00 2001
> From: Joerg Roedel <jroedel@suse.de>
> Date: Fri, 5 Sep 2014 10:49:34 +0200
> Subject: [PATCH 04/13] iommu/arm-smmu: Convert to iommu_capable() API function
> 
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/arm-smmu.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index a83cc2a..f5cacf4 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1526,20 +1526,20 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
>  	return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
>  }
>  
> -static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
> -				   unsigned long cap)
> +static bool arm_smmu_capable(enum iommu_cap cap)
>  {
> -	struct arm_smmu_domain *smmu_domain = domain->priv;
> -	struct arm_smmu_device *smmu = smmu_domain->smmu;
> -	u32 features = smmu ? smmu->features : 0;
> -
>  	switch (cap) {
>  	case IOMMU_CAP_CACHE_COHERENCY:
> -		return features & ARM_SMMU_FEAT_COHERENT_WALK;
> +		/*
> +		 * Return false here until we have a way to find out whether the
> +		 * SMMUs in the system a coherently connected and able to force
> +		 * DMA coherency.
> +		 */

s/a/are/

However, I thought about this a bit more and the coherency isn't necessarily
a global property of the SMMU. In reality, it is dependent on the IOTLBs in
use by the domain, so it's not going to be possible to report true here in
many cases.

That means we'd need a way to say `this device is dma coherent when its
downstream IOMMU is enabled with IOMMU_CACHE mappings'. For the moment,
people will probably just add `dma-coherent' to the endpoint and dma-mapping
will request IOMMU_CACHE mappings regardless of the features advertised by
the IOMMU. In that case, it might make more sense to return `true' here as
we can always generated cacheable transactions from the SMMU. The
dma-coherent property on the device would then indicate whether those
transactions will snoop the CPU caches.

Will

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function
  2014-09-19 16:42       ` Will Deacon
@ 2014-09-22 15:36         ` Joerg Roedel
  0 siblings, 0 replies; 22+ messages in thread
From: Joerg Roedel @ 2014-09-22 15:36 UTC (permalink / raw)
  To: Will Deacon; +Cc: Joerg Roedel, iommu, linux-kernel, devicetree

Hi Will,

On Fri, Sep 19, 2014 at 05:42:20PM +0100, Will Deacon wrote:
> However, I thought about this a bit more and the coherency isn't necessarily
> a global property of the SMMU. In reality, it is dependent on the IOTLBs in
> use by the domain, so it's not going to be possible to report true here in
> many cases.
> 
> That means we'd need a way to say `this device is dma coherent when its
> downstream IOMMU is enabled with IOMMU_CACHE mappings'. For the moment,
> people will probably just add `dma-coherent' to the endpoint and dma-mapping
> will request IOMMU_CACHE mappings regardless of the features advertised by
> the IOMMU. In that case, it might make more sense to return `true' here as
> we can always generated cacheable transactions from the SMMU. The
> dma-coherent property on the device would then indicate whether those
> transactions will snoop the CPU caches.

Okay, when the SMMU can always generate cachable transactions it is
surely fine to return true here. I'll change that before I add the
patches to my tree.


	Joerg


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-09-22 15:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-05 10:52 [PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable() Joerg Roedel
2014-09-05 10:52 ` [PATCH 01/12] iommu: Introduce iommu_capable API function Joerg Roedel
2014-09-05 10:52 ` [PATCH 02/12] iommu: Convert iommu-caps from define to enum Joerg Roedel
2014-09-05 10:52 ` [PATCH 03/12] iommu/amd: Convert to iommu_capable() API function Joerg Roedel
2014-09-05 10:52 ` [PATCH 04/12] iommu/arm-smmu: " Joerg Roedel
2014-09-08 16:51   ` Will Deacon
2014-09-09 13:57     ` Joerg Roedel
2014-09-17  8:53     ` [PATCH 04/13 v2] iommu/arm-smmu: Convert to iommu_capable() API function function Joerg Roedel
2014-09-19 16:42       ` Will Deacon
2014-09-22 15:36         ` Joerg Roedel
2014-09-05 10:52 ` [PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function Joerg Roedel
2014-09-09 18:38   ` Varun Sethi
2014-09-05 10:52 ` [PATCH 06/12] iommu/vt-d: " Joerg Roedel
2014-09-05 10:52 ` [PATCH 07/12] iommu/msm: " Joerg Roedel
2014-09-05 10:53 ` [PATCH 08/12] iommu/tegra: " Joerg Roedel
2014-09-05 10:53 ` [PATCH 09/12] kvm: iommu: Convert to use new " Joerg Roedel
2014-09-17  8:29   ` Joerg Roedel
2014-09-05 10:53 ` [PATCH 10/12] vfio: " Joerg Roedel
2014-09-08 23:14   ` Alex Williamson
2014-09-05 10:53 ` [PATCH 11/12] IB/usnic: " Joerg Roedel
2014-09-17  8:30   ` Joerg Roedel
2014-09-05 10:53 ` [PATCH 12/12] iommu: Remove iommu_domain_has_cap() " Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).