LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 00/16 v2] iommu: Move domain allocation into drivers
@ 2015-03-26 12:43 Joerg Roedel
  2015-03-26 12:43 ` [PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops Joerg Roedel
                   ` (20 more replies)
  0 siblings, 21 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

Changes v1-v2:

	* Rebased to v4.0-rc5
	* Converted domain-types to a bit-field

Hi,

here is patch-set to replace the existing domain_init and
domain_destroy iommu-ops with the new domain_alloc and
domain_free callbacks

The new callbacks move the allocation of iommu domains into
the iommu driver, allowing them to put a generic
iommu_domain struct into their own domain struct. This makes
domain handling in the drivers more cache efficient and
prepares the introduction of default domains in another
patch-set.

While at it, this patch-set also introduces domain types.
These are internal to the iommu core code for now, there are
three of them:

	* DMA-API domains
	* Identity mapped domains
	* Domains unmanaged by the iommu-core, used for
	  iommu-api so that the users can create their own
	  mappings

The patches have been compile tested for x86, ARM and PPC
and runtime tested on x86 (Intel VT-d and AMD IOMMU).

Please review.

Thanks,

	Joerg

Joerg Roedel (15):
  iommu: Introduce domain_alloc and domain_free iommu_ops
  iommu: Introduce iommu domain types
  iommu/amd: Make use of domain_alloc and domain_free
  iommu/vt-d: Make use of domain_alloc and domain_free
  iommu/omap: Make use of domain_alloc and domain_free
  iommu/arm-smmu: Make use of domain_alloc and domain_free
  iommu/exynos: Make use of domain_alloc and domain_free
  iommu/tegra-smmu: Make use of domain_alloc and domain_free
  iommu/tegra-gart: Make use of domain_alloc and domain_free
  iommu/msm: Make use of domain_alloc and domain_free
  iommu/shmobile: Make use of domain_alloc and domain_free
  iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
  iommu/rockchip: Make use of domain_alloc and domain_free
  iommu/fsl: Make use of domain_alloc and domain_free
  iommu: Remove domain_init and domain_free iommu_ops

 drivers/iommu/amd_iommu.c       | 84 +++++++++++++++++++++------------------
 drivers/iommu/amd_iommu_types.h |  7 ++--
 drivers/iommu/arm-smmu.c        | 46 +++++++++++++---------
 drivers/iommu/exynos-iommu.c    | 87 ++++++++++++++++++++++-------------------
 drivers/iommu/fsl_pamu_domain.c | 60 +++++++++++++++-------------
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 drivers/iommu/intel-iommu.c     | 48 +++++++++++++----------
 drivers/iommu/iommu.c           | 20 ++--------
 drivers/iommu/ipmmu-vmsa.c      | 43 +++++++++++---------
 drivers/iommu/msm_iommu.c       | 73 +++++++++++++++++-----------------
 drivers/iommu/omap-iommu.c      | 49 +++++++++++++----------
 drivers/iommu/rockchip-iommu.c  | 40 +++++++++++--------
 drivers/iommu/shmobile-iommu.c  | 40 +++++++++++--------
 drivers/iommu/tegra-gart.c      | 67 +++++++++++++++++++++----------
 drivers/iommu/tegra-smmu.c      | 41 ++++++++++---------
 include/linux/iommu.h           | 17 ++++++--
 16 files changed, 407 insertions(+), 317 deletions(-)

-- 
1.8.4.5
Joerg Roedel (16):
  iommu: Introduce domain_alloc and domain_free iommu_ops
  iommu: Introduce iommu domain types
  iommu: Only allow iommu_map/unmap for paging domains
  iommu/amd: Make use of domain_alloc and domain_free
  iommu/vt-d: Make use of domain_alloc and domain_free
  iommu/omap: Make use of domain_alloc and domain_free
  iommu/arm-smmu: Make use of domain_alloc and domain_free
  iommu/exynos: Make use of domain_alloc and domain_free
  iommu/tegra-smmu: Make use of domain_alloc and domain_free
  iommu/tegra-gart: Make use of domain_alloc and domain_free
  iommu/msm: Make use of domain_alloc and domain_free
  iommu/shmobile: Make use of domain_alloc and domain_free
  iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
  iommu/rockchip: Make use of domain_alloc and domain_free
  iommu/fsl: Make use of domain_alloc and domain_free
  iommu: Remove domain_init and domain_free iommu_ops

 drivers/iommu/amd_iommu.c       | 84 +++++++++++++++++++++------------------
 drivers/iommu/amd_iommu_types.h |  7 ++--
 drivers/iommu/arm-smmu.c        | 46 +++++++++++++---------
 drivers/iommu/exynos-iommu.c    | 87 ++++++++++++++++++++++-------------------
 drivers/iommu/fsl_pamu_domain.c | 60 +++++++++++++++-------------
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 drivers/iommu/intel-iommu.c     | 48 +++++++++++++----------
 drivers/iommu/iommu.c           | 26 +++++-------
 drivers/iommu/ipmmu-vmsa.c      | 41 ++++++++++---------
 drivers/iommu/msm_iommu.c       | 73 +++++++++++++++++-----------------
 drivers/iommu/omap-iommu.c      | 49 +++++++++++++----------
 drivers/iommu/rockchip-iommu.c  | 40 +++++++++++--------
 drivers/iommu/shmobile-iommu.c  | 39 ++++++++++--------
 drivers/iommu/tegra-gart.c      | 67 +++++++++++++++++++++----------
 drivers/iommu/tegra-smmu.c      | 41 ++++++++++---------
 include/linux/iommu.h           | 33 ++++++++++++++--
 16 files changed, 427 insertions(+), 316 deletions(-)

-- 
1.9.1


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

* [PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 02/16] iommu: Introduce iommu domain types Joerg Roedel
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

These new call-backs defer the allocation and destruction of
'struct iommu_domain' to the iommu driver. This allows
drivers to embed this struct into their private domain
structures and to get rid of the domain_init and
domain_destroy call-backs when all drivers have been
converted.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 72e683d..11de262 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -900,26 +900,34 @@ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
 
 struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
+	const struct iommu_ops *ops;
 	struct iommu_domain *domain;
-	int ret;
 
 	if (bus == NULL || bus->iommu_ops == NULL)
 		return NULL;
 
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	ops = bus->iommu_ops;
+
+	if (ops->domain_alloc)
+		domain = ops->domain_alloc();
+	else
+		domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+
 	if (!domain)
 		return NULL;
 
 	domain->ops = bus->iommu_ops;
 
-	ret = domain->ops->domain_init(domain);
-	if (ret)
+	if (ops->domain_init && domain->ops->domain_init(domain))
 		goto out_free;
 
 	return domain;
 
 out_free:
-	kfree(domain);
+	if (ops->domain_free)
+		ops->domain_free(domain);
+	else
+		kfree(domain);
 
 	return NULL;
 }
@@ -927,10 +935,15 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
-	if (likely(domain->ops->domain_destroy != NULL))
-		domain->ops->domain_destroy(domain);
+	const struct iommu_ops *ops = domain->ops;
 
-	kfree(domain);
+	if (likely(ops->domain_destroy != NULL))
+		ops->domain_destroy(domain);
+
+	if (ops->domain_free)
+		ops->domain_free(domain);
+	else
+		kfree(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 38daa45..69d1d12 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -115,6 +115,11 @@ struct iommu_ops {
 	bool (*capable)(enum iommu_cap);
 	int (*domain_init)(struct iommu_domain *domain);
 	void (*domain_destroy)(struct iommu_domain *domain);
+
+	/* Domain allocation and freeing by the iommu driver */
+	struct iommu_domain *(*domain_alloc)(void);
+	void (*domain_free)(struct iommu_domain *);
+
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 	int (*map)(struct iommu_domain *domain, unsigned long iova,
-- 
1.9.1


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

* [PATCH 02/16] iommu: Introduce iommu domain types
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
  2015-03-26 12:43 ` [PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:52   ` Swapna Nannapaneni
  2015-03-26 12:43 ` [PATCH 03/16] iommu: Only allow iommu_map/unmap for paging domains Joerg Roedel
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

This allows to handle domains differently based on their
type in the future. An IOMMU driver can implement certain
optimizations for DMA-API domains for example.

The domain types can be extended later and some of the
existing domain attributes can be migrated to become domain
flags.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 11de262..4920605 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -909,14 +909,15 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 	ops = bus->iommu_ops;
 
 	if (ops->domain_alloc)
-		domain = ops->domain_alloc();
+		domain = ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
 	else
 		domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 
 	if (!domain)
 		return NULL;
 
-	domain->ops = bus->iommu_ops;
+	domain->ops  = bus->iommu_ops;
+	domain->type = IOMMU_DOMAIN_UNMANAGED;
 
 	if (ops->domain_init && domain->ops->domain_init(domain))
 		goto out_free;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 69d1d12..72d03fe 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -51,7 +51,32 @@ struct iommu_domain_geometry {
 	bool force_aperture;       /* DMA only allowed in mappable range? */
 };
 
+/* Domain feature flags */
+#define __IOMMU_DOMAIN_PAGING	(1U << 0)  /* Support for iommu_map/unmap */
+#define __IOMMU_DOMAIN_DMA_API	(1U << 1)  /* Domain for use in DMA-API
+					      implementation              */
+#define __IOMMU_DOMAIN_PT	(1U << 2)  /* Domain is identity mapped   */
+
+/*
+ * This are the possible domain-types
+ *
+ *	IOMMU_DOMAIN_BLOCKED	- All DMA is blocked, can be used to isolate
+ *				  devices
+ *	IOMMU_DOMAIN_IDENTITY	- DMA addresses are system physical addresses
+ *	IOMMU_DOMAIN_UNMANAGED	- DMA mappings managed by IOMMU-API user, used
+ *				  for VMs
+ *	IOMMU_DOMAIN_DMA	- Internally used for DMA-API implementations.
+ *				  This flag allows IOMMU drivers to implement
+ *				  certain optimizations for these domains
+ */
+#define IOMMU_DOMAIN_BLOCKED	(0U)
+#define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
+#define IOMMU_DOMAIN_UNMANAGED	(__IOMMU_DOMAIN_PAGING)
+#define IOMMU_DOMAIN_DMA	(__IOMMU_DOMAIN_PAGING |	\
+				 __IOMMU_DOMAIN_DMA_API)
+
 struct iommu_domain {
+	unsigned type;
 	const struct iommu_ops *ops;
 	void *priv;
 	iommu_fault_handler_t handler;
@@ -117,7 +142,7 @@ struct iommu_ops {
 	void (*domain_destroy)(struct iommu_domain *domain);
 
 	/* Domain allocation and freeing by the iommu driver */
-	struct iommu_domain *(*domain_alloc)(void);
+	struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
 	void (*domain_free)(struct iommu_domain *);
 
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
-- 
1.9.1


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

* [PATCH 03/16] iommu: Only allow iommu_map/unmap for paging domains
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
  2015-03-26 12:43 ` [PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops Joerg Roedel
  2015-03-26 12:43 ` [PATCH 02/16] iommu: Introduce iommu domain types Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 04/16] iommu/amd: Make use of domain_alloc and domain_free Joerg Roedel
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Check for the new __IOMMU_DOMAIN_PAGING flag before calling
into the iommu drivers ->map and ->unmap call-backs.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 4920605..656b949 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1063,6 +1063,9 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
 		     domain->ops->pgsize_bitmap == 0UL))
 		return -ENODEV;
 
+	if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
+		return -EINVAL;
+
 	/* find out the minimum page size supported */
 	min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
 
@@ -1114,6 +1117,9 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
 		     domain->ops->pgsize_bitmap == 0UL))
 		return -ENODEV;
 
+	if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
+		return -EINVAL;
+
 	/* find out the minimum page size supported */
 	min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
 
-- 
1.9.1


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

* [PATCH 04/16] iommu/amd: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (2 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 03/16] iommu: Only allow iommu_map/unmap for paging domains Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 05/16] iommu/vt-d: " Joerg Roedel
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement the new iommu-ops function pointers and remove the
obsolete domain_init and domain_destroy functions.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/amd_iommu.c       | 84 ++++++++++++++++++++++-------------------
 drivers/iommu/amd_iommu_types.h |  7 ++--
 2 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 48882c1..e8c412d 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -126,6 +126,11 @@ static int __init alloc_passthrough_domain(void);
  *
  ****************************************************************************/
 
+static struct protection_domain *to_pdomain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct protection_domain, domain);
+}
+
 static struct iommu_dev_data *alloc_dev_data(u16 devid)
 {
 	struct iommu_dev_data *dev_data;
@@ -3236,42 +3241,45 @@ static int __init alloc_passthrough_domain(void)
 
 	return 0;
 }
-static int amd_iommu_domain_init(struct iommu_domain *dom)
+
+static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
 {
-	struct protection_domain *domain;
+	struct protection_domain *pdomain;
 
-	domain = protection_domain_alloc();
-	if (!domain)
-		goto out_free;
+	/* We only support unmanaged domains for now */
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
 
-	domain->mode    = PAGE_MODE_3_LEVEL;
-	domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);
-	if (!domain->pt_root)
+	pdomain = protection_domain_alloc();
+	if (!pdomain)
 		goto out_free;
 
-	domain->iommu_domain = dom;
-
-	dom->priv = domain;
+	pdomain->mode    = PAGE_MODE_3_LEVEL;
+	pdomain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);
+	if (!pdomain->pt_root)
+		goto out_free;
 
-	dom->geometry.aperture_start = 0;
-	dom->geometry.aperture_end   = ~0ULL;
-	dom->geometry.force_aperture = true;
+	pdomain->domain.geometry.aperture_start = 0;
+	pdomain->domain.geometry.aperture_end   = ~0ULL;
+	pdomain->domain.geometry.force_aperture = true;
 
-	return 0;
+	return &pdomain->domain;
 
 out_free:
-	protection_domain_free(domain);
+	protection_domain_free(pdomain);
 
-	return -ENOMEM;
+	return NULL;
 }
 
-static void amd_iommu_domain_destroy(struct iommu_domain *dom)
+static void amd_iommu_domain_free(struct iommu_domain *dom)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain;
 
-	if (!domain)
+	if (!dom)
 		return;
 
+	domain = to_pdomain(dom);
+
 	if (domain->dev_cnt > 0)
 		cleanup_domain(domain);
 
@@ -3284,8 +3292,6 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
 		free_gcr3_table(domain);
 
 	protection_domain_free(domain);
-
-	dom->priv = NULL;
 }
 
 static void amd_iommu_detach_device(struct iommu_domain *dom,
@@ -3313,7 +3319,7 @@ static void amd_iommu_detach_device(struct iommu_domain *dom,
 static int amd_iommu_attach_device(struct iommu_domain *dom,
 				   struct device *dev)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	struct iommu_dev_data *dev_data;
 	struct amd_iommu *iommu;
 	int ret;
@@ -3340,7 +3346,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
 static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
 			 phys_addr_t paddr, size_t page_size, int iommu_prot)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	int prot = 0;
 	int ret;
 
@@ -3362,7 +3368,7 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
 static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
 			   size_t page_size)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	size_t unmap_size;
 
 	if (domain->mode == PAGE_MODE_NONE)
@@ -3380,7 +3386,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
 					  dma_addr_t iova)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long offset_mask;
 	phys_addr_t paddr;
 	u64 *pte, __pte;
@@ -3420,8 +3426,8 @@ static bool amd_iommu_capable(enum iommu_cap cap)
 
 static const struct iommu_ops amd_iommu_ops = {
 	.capable = amd_iommu_capable,
-	.domain_init = amd_iommu_domain_init,
-	.domain_destroy = amd_iommu_domain_destroy,
+	.domain_alloc = amd_iommu_domain_alloc,
+	.domain_free  = amd_iommu_domain_free,
 	.attach_dev = amd_iommu_attach_device,
 	.detach_dev = amd_iommu_detach_device,
 	.map = amd_iommu_map,
@@ -3483,7 +3489,7 @@ EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier);
 
 void amd_iommu_domain_direct_map(struct iommu_domain *dom)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 
 	spin_lock_irqsave(&domain->lock, flags);
@@ -3504,7 +3510,7 @@ EXPORT_SYMBOL(amd_iommu_domain_direct_map);
 
 int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 	int levels, ret;
 
@@ -3616,7 +3622,7 @@ static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid,
 int amd_iommu_flush_page(struct iommu_domain *dom, int pasid,
 			 u64 address)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 	int ret;
 
@@ -3638,7 +3644,7 @@ static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid)
 
 int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 	int ret;
 
@@ -3718,7 +3724,7 @@ static int __clear_gcr3(struct protection_domain *domain, int pasid)
 int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid,
 			      unsigned long cr3)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 	int ret;
 
@@ -3732,7 +3738,7 @@ EXPORT_SYMBOL(amd_iommu_domain_set_gcr3);
 
 int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid)
 {
-	struct protection_domain *domain = dom->priv;
+	struct protection_domain *domain = to_pdomain(dom);
 	unsigned long flags;
 	int ret;
 
@@ -3765,17 +3771,17 @@ EXPORT_SYMBOL(amd_iommu_complete_ppr);
 
 struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev)
 {
-	struct protection_domain *domain;
+	struct protection_domain *pdomain;
 
-	domain = get_domain(&pdev->dev);
-	if (IS_ERR(domain))
+	pdomain = get_domain(&pdev->dev);
+	if (IS_ERR(pdomain))
 		return NULL;
 
 	/* Only return IOMMUv2 domains */
-	if (!(domain->flags & PD_IOMMUV2_MASK))
+	if (!(pdomain->flags & PD_IOMMUV2_MASK))
 		return NULL;
 
-	return domain->iommu_domain;
+	return &pdomain->domain;
 }
 EXPORT_SYMBOL(amd_iommu_get_v2_domain);
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index c4fffb7..2b1276b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -400,6 +400,8 @@ struct iommu_domain;
 struct protection_domain {
 	struct list_head list;  /* for list of all protection domains */
 	struct list_head dev_list; /* List of all devices in this domain */
+	struct iommu_domain domain; /* generic domain handle used by
+				       iommu core code */
 	spinlock_t lock;	/* mostly used to lock the page table*/
 	struct mutex api_lock;	/* protect page tables in the iommu-api path */
 	u16 id;			/* the domain id written to the device table */
@@ -411,10 +413,7 @@ struct protection_domain {
 	bool updated;		/* complete domain flush required */
 	unsigned dev_cnt;	/* devices assigned to this domain */
 	unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
-	void *priv;		/* private data */
-	struct iommu_domain *iommu_domain; /* Pointer to generic
-					      domain structure */
-
+	void *priv;             /* private data */
 };
 
 /*
-- 
1.9.1


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

* [PATCH 05/16] iommu/vt-d: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (3 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 04/16] iommu/amd: Make use of domain_alloc and domain_free Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 06/16] iommu/omap: " Joerg Roedel
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Get rid of domain_init and domain_destroy and implement
domain_alloc/domain_free instead.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/intel-iommu.c | 48 ++++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ae4c1a8..a312e49 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -339,7 +339,7 @@ struct dmar_domain {
 	DECLARE_BITMAP(iommu_bmp, DMAR_UNITS_SUPPORTED);
 					/* bitmap of iommus this domain uses*/
 
-	struct list_head devices; 	/* all devices' list */
+	struct list_head devices;	/* all devices' list */
 	struct iova_domain iovad;	/* iova's that belong to this domain */
 
 	struct dma_pte	*pgd;		/* virtual address */
@@ -358,6 +358,9 @@ struct dmar_domain {
 					   2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
 	spinlock_t	iommu_lock;	/* protect iommu set in domain */
 	u64		max_addr;	/* maximum mapped address */
+
+	struct iommu_domain domain;	/* generic domain data structure for
+					   iommu core */
 };
 
 /* PCI domain-device relationship */
@@ -449,6 +452,12 @@ static LIST_HEAD(device_domain_list);
 
 static const struct iommu_ops intel_iommu_ops;
 
+/* Convert generic 'struct iommu_domain to private struct dmar_domain */
+static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct dmar_domain, domain);
+}
+
 static int __init intel_iommu_setup(char *str)
 {
 	if (!str)
@@ -4340,44 +4349,45 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
 	return 0;
 }
 
-static int intel_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 {
 	struct dmar_domain *dmar_domain;
+	struct iommu_domain *domain;
+
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
 
 	dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
 	if (!dmar_domain) {
 		printk(KERN_ERR
 			"intel_iommu_domain_init: dmar_domain == NULL\n");
-		return -ENOMEM;
+		return NULL;
 	}
 	if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
 		printk(KERN_ERR
 			"intel_iommu_domain_init() failed\n");
 		domain_exit(dmar_domain);
-		return -ENOMEM;
+		return NULL;
 	}
 	domain_update_iommu_cap(dmar_domain);
-	domain->priv = dmar_domain;
 
+	domain = &dmar_domain->domain;
 	domain->geometry.aperture_start = 0;
 	domain->geometry.aperture_end   = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
 	domain->geometry.force_aperture = true;
 
-	return 0;
+	return domain;
 }
 
-static void intel_iommu_domain_destroy(struct iommu_domain *domain)
+static void intel_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
-
-	domain->priv = NULL;
-	domain_exit(dmar_domain);
+	domain_exit(to_dmar_domain(domain));
 }
 
 static int intel_iommu_attach_device(struct iommu_domain *domain,
 				     struct device *dev)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
+	struct dmar_domain *dmar_domain = to_dmar_domain(domain);
 	struct intel_iommu *iommu;
 	int addr_width;
 	u8 bus, devfn;
@@ -4442,16 +4452,14 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 static void intel_iommu_detach_device(struct iommu_domain *domain,
 				      struct device *dev)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
-
-	domain_remove_one_dev_info(dmar_domain, dev);
+	domain_remove_one_dev_info(to_dmar_domain(domain), dev);
 }
 
 static int intel_iommu_map(struct iommu_domain *domain,
 			   unsigned long iova, phys_addr_t hpa,
 			   size_t size, int iommu_prot)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
+	struct dmar_domain *dmar_domain = to_dmar_domain(domain);
 	u64 max_addr;
 	int prot = 0;
 	int ret;
@@ -4488,7 +4496,7 @@ static int intel_iommu_map(struct iommu_domain *domain,
 static size_t intel_iommu_unmap(struct iommu_domain *domain,
 				unsigned long iova, size_t size)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
+	struct dmar_domain *dmar_domain = to_dmar_domain(domain);
 	struct page *freelist = NULL;
 	struct intel_iommu *iommu;
 	unsigned long start_pfn, last_pfn;
@@ -4536,7 +4544,7 @@ static size_t intel_iommu_unmap(struct iommu_domain *domain,
 static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
 					    dma_addr_t iova)
 {
-	struct dmar_domain *dmar_domain = domain->priv;
+	struct dmar_domain *dmar_domain = to_dmar_domain(domain);
 	struct dma_pte *pte;
 	int level = 0;
 	u64 phys = 0;
@@ -4595,8 +4603,8 @@ 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,
+	.domain_alloc	= intel_iommu_domain_alloc,
+	.domain_free	= intel_iommu_domain_free,
 	.attach_dev	= intel_iommu_attach_device,
 	.detach_dev	= intel_iommu_detach_device,
 	.map		= intel_iommu_map,
-- 
1.9.1


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

* [PATCH 06/16] iommu/omap: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (4 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 05/16] iommu/vt-d: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 07/16] iommu/arm-smmu: " Joerg Roedel
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement the new domain_alloc and domain_free call-backs
and remove the old domain_init/destroy ones.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/omap-iommu.c | 49 +++++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index a4ba851..a22c33d 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -59,6 +59,7 @@ struct omap_iommu_domain {
 	struct omap_iommu *iommu_dev;
 	struct device *dev;
 	spinlock_t lock;
+	struct iommu_domain domain;
 };
 
 #define MMU_LOCK_BASE_SHIFT	10
@@ -80,6 +81,15 @@ static struct platform_driver omap_iommu_driver;
 static struct kmem_cache *iopte_cachep;
 
 /**
+ * to_omap_domain - Get struct omap_iommu_domain from generic iommu_domain
+ * @dom:	generic iommu domain handle
+ **/
+static struct omap_iommu_domain *to_omap_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct omap_iommu_domain, domain);
+}
+
+/**
  * omap_iommu_save_ctx - Save registers for pm off-mode support
  * @dev:	client device
  **/
@@ -901,7 +911,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
 	u32 *iopgd, *iopte;
 	struct omap_iommu *obj = data;
 	struct iommu_domain *domain = obj->domain;
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
 	if (!omap_domain->iommu_dev)
 		return IRQ_NONE;
@@ -1113,7 +1123,7 @@ static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, int pgsz)
 static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
 			 phys_addr_t pa, size_t bytes, int prot)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 	struct omap_iommu *oiommu = omap_domain->iommu_dev;
 	struct device *dev = oiommu->dev;
 	struct iotlb_entry e;
@@ -1140,7 +1150,7 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
 static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
 			    size_t size)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 	struct omap_iommu *oiommu = omap_domain->iommu_dev;
 	struct device *dev = oiommu->dev;
 
@@ -1152,7 +1162,7 @@ static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
 static int
 omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 	struct omap_iommu *oiommu;
 	struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
 	int ret = 0;
@@ -1212,17 +1222,20 @@ static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain,
 static void omap_iommu_detach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
 	spin_lock(&omap_domain->lock);
 	_omap_iommu_detach_dev(omap_domain, dev);
 	spin_unlock(&omap_domain->lock);
 }
 
-static int omap_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *omap_iommu_domain_alloc(unsigned type)
 {
 	struct omap_iommu_domain *omap_domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	omap_domain = kzalloc(sizeof(*omap_domain), GFP_KERNEL);
 	if (!omap_domain) {
 		pr_err("kzalloc failed\n");
@@ -1244,25 +1257,21 @@ static int omap_iommu_domain_init(struct iommu_domain *domain)
 	clean_dcache_area(omap_domain->pgtable, IOPGD_TABLE_SIZE);
 	spin_lock_init(&omap_domain->lock);
 
-	domain->priv = omap_domain;
+	omap_domain->domain.geometry.aperture_start = 0;
+	omap_domain->domain.geometry.aperture_end   = (1ULL << 32) - 1;
+	omap_domain->domain.geometry.force_aperture = true;
 
-	domain->geometry.aperture_start = 0;
-	domain->geometry.aperture_end   = (1ULL << 32) - 1;
-	domain->geometry.force_aperture = true;
-
-	return 0;
+	return &omap_domain->domain;
 
 fail_nomem:
 	kfree(omap_domain);
 out:
-	return -ENOMEM;
+	return NULL;
 }
 
-static void omap_iommu_domain_destroy(struct iommu_domain *domain)
+static void omap_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
-
-	domain->priv = NULL;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
 	/*
 	 * An iommu device is still attached
@@ -1278,7 +1287,7 @@ static void omap_iommu_domain_destroy(struct iommu_domain *domain)
 static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain,
 					  dma_addr_t da)
 {
-	struct omap_iommu_domain *omap_domain = domain->priv;
+	struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 	struct omap_iommu *oiommu = omap_domain->iommu_dev;
 	struct device *dev = oiommu->dev;
 	u32 *pgd, *pte;
@@ -1358,8 +1367,8 @@ static void omap_iommu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops omap_iommu_ops = {
-	.domain_init	= omap_iommu_domain_init,
-	.domain_destroy	= omap_iommu_domain_destroy,
+	.domain_alloc	= omap_iommu_domain_alloc,
+	.domain_free	= omap_iommu_domain_free,
 	.attach_dev	= omap_iommu_attach_dev,
 	.detach_dev	= omap_iommu_detach_dev,
 	.map		= omap_iommu_map,
-- 
1.9.1


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

* [PATCH 07/16] iommu/arm-smmu: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (5 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 06/16] iommu/omap: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 08/16] iommu/exynos: " Joerg Roedel
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/arm-smmu.c | 46 +++++++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fc13dd5..5575c3d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -343,6 +343,7 @@ struct arm_smmu_domain {
 	struct arm_smmu_cfg		cfg;
 	enum arm_smmu_domain_stage	stage;
 	struct mutex			init_mutex; /* Protects smmu pointer */
+	struct iommu_domain		domain;
 };
 
 static struct iommu_ops arm_smmu_ops;
@@ -360,6 +361,11 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 	{ 0, NULL},
 };
 
+static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct arm_smmu_domain, domain);
+}
+
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
 	int i = 0;
@@ -645,7 +651,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
 	u32 fsr, far, fsynr, resume;
 	unsigned long iova;
 	struct iommu_domain *domain = dev;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	void __iomem *cb_base;
@@ -836,7 +842,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 	struct io_pgtable_ops *pgtbl_ops;
 	struct io_pgtable_cfg pgtbl_cfg;
 	enum io_pgtable_fmt fmt;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 
 	mutex_lock(&smmu_domain->init_mutex);
@@ -958,7 +964,7 @@ out_unlock:
 
 static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	void __iomem *cb_base;
@@ -985,10 +991,12 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
 	__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
 }
 
-static int arm_smmu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
 	struct arm_smmu_domain *smmu_domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
 	/*
 	 * Allocate the domain and initialise some of its data structures.
 	 * We can't really do anything meaningful until we've added a
@@ -996,17 +1004,17 @@ static int arm_smmu_domain_init(struct iommu_domain *domain)
 	 */
 	smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL);
 	if (!smmu_domain)
-		return -ENOMEM;
+		return NULL;
 
 	mutex_init(&smmu_domain->init_mutex);
 	spin_lock_init(&smmu_domain->pgtbl_lock);
-	domain->priv = smmu_domain;
-	return 0;
+
+	return &smmu_domain->domain;
 }
 
-static void arm_smmu_domain_destroy(struct iommu_domain *domain)
+static void arm_smmu_domain_free(struct iommu_domain *domain)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
 	/*
 	 * Free the domain resources. We assume that all devices have
@@ -1143,7 +1151,7 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
 	int ret;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu;
 	struct arm_smmu_master_cfg *cfg;
 
@@ -1187,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_master_cfg *cfg;
 
 	cfg = find_smmu_master_cfg(dev);
@@ -1203,7 +1211,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
 {
 	int ret;
 	unsigned long flags;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
 
 	if (!ops)
@@ -1220,7 +1228,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 {
 	size_t ret;
 	unsigned long flags;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
 
 	if (!ops)
@@ -1235,7 +1243,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
 					      dma_addr_t iova)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
@@ -1281,7 +1289,7 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
 {
 	phys_addr_t ret;
 	unsigned long flags;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
 
 	if (!ops)
@@ -1389,7 +1397,7 @@ static void arm_smmu_remove_device(struct device *dev)
 static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
 				    enum iommu_attr attr, void *data)
 {
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
 	switch (attr) {
 	case DOMAIN_ATTR_NESTING:
@@ -1404,7 +1412,7 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
 				    enum iommu_attr attr, void *data)
 {
 	int ret = 0;
-	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
 	mutex_lock(&smmu_domain->init_mutex);
 
@@ -1432,8 +1440,8 @@ out_unlock:
 
 static struct iommu_ops arm_smmu_ops = {
 	.capable		= arm_smmu_capable,
-	.domain_init		= arm_smmu_domain_init,
-	.domain_destroy		= arm_smmu_domain_destroy,
+	.domain_alloc		= arm_smmu_domain_alloc,
+	.domain_free		= arm_smmu_domain_free,
 	.attach_dev		= arm_smmu_attach_dev,
 	.detach_dev		= arm_smmu_detach_dev,
 	.map			= arm_smmu_map,
-- 
1.9.1


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

* [PATCH 08/16] iommu/exynos: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (6 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 07/16] iommu/arm-smmu: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 09/16] iommu/tegra-smmu: " Joerg Roedel
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/exynos-iommu.c | 87 ++++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 40 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index dc14fec4..3e89850 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -200,6 +200,7 @@ struct exynos_iommu_domain {
 	short *lv2entcnt; /* free lv2 entry counter for each section */
 	spinlock_t lock; /* lock for this structure */
 	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
+	struct iommu_domain domain; /* generic domain data structure */
 };
 
 struct sysmmu_drvdata {
@@ -214,6 +215,11 @@ struct sysmmu_drvdata {
 	phys_addr_t pgtable;
 };
 
+static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct exynos_iommu_domain, domain);
+}
+
 static bool set_sysmmu_active(struct sysmmu_drvdata *data)
 {
 	/* return true if the System MMU was not active previously
@@ -696,58 +702,60 @@ static inline void pgtable_flush(void *vastart, void *vaend)
 				virt_to_phys(vaend));
 }
 
-static int exynos_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 {
-	struct exynos_iommu_domain *priv;
+	struct exynos_iommu_domain *exynos_domain;
 	int i;
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
+	exynos_domain = kzalloc(sizeof(*exynos_domain), GFP_KERNEL);
+	if (!exynos_domain)
+		return NULL;
 
-	priv->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
-	if (!priv->pgtable)
+	exynos_domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
+	if (!exynos_domain->pgtable)
 		goto err_pgtable;
 
-	priv->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
-	if (!priv->lv2entcnt)
+	exynos_domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
+	if (!exynos_domain->lv2entcnt)
 		goto err_counter;
 
 	/* Workaround for System MMU v3.3 to prevent caching 1MiB mapping */
 	for (i = 0; i < NUM_LV1ENTRIES; i += 8) {
-		priv->pgtable[i + 0] = ZERO_LV2LINK;
-		priv->pgtable[i + 1] = ZERO_LV2LINK;
-		priv->pgtable[i + 2] = ZERO_LV2LINK;
-		priv->pgtable[i + 3] = ZERO_LV2LINK;
-		priv->pgtable[i + 4] = ZERO_LV2LINK;
-		priv->pgtable[i + 5] = ZERO_LV2LINK;
-		priv->pgtable[i + 6] = ZERO_LV2LINK;
-		priv->pgtable[i + 7] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 0] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 1] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 2] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 3] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 4] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 5] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 6] = ZERO_LV2LINK;
+		exynos_domain->pgtable[i + 7] = ZERO_LV2LINK;
 	}
 
-	pgtable_flush(priv->pgtable, priv->pgtable + NUM_LV1ENTRIES);
+	pgtable_flush(exynos_domain->pgtable, exynos_domain->pgtable + NUM_LV1ENTRIES);
 
-	spin_lock_init(&priv->lock);
-	spin_lock_init(&priv->pgtablelock);
-	INIT_LIST_HEAD(&priv->clients);
+	spin_lock_init(&exynos_domain->lock);
+	spin_lock_init(&exynos_domain->pgtablelock);
+	INIT_LIST_HEAD(&exynos_domain->clients);
 
-	domain->geometry.aperture_start = 0;
-	domain->geometry.aperture_end   = ~0UL;
-	domain->geometry.force_aperture = true;
+	exynos_domain->domain.geometry.aperture_start = 0;
+	exynos_domain->domain.geometry.aperture_end   = ~0UL;
+	exynos_domain->domain.geometry.force_aperture = true;
 
-	domain->priv = priv;
-	return 0;
+	return &exynos_domain->domain;
 
 err_counter:
-	free_pages((unsigned long)priv->pgtable, 2);
+	free_pages((unsigned long)exynos_domain->pgtable, 2);
 err_pgtable:
-	kfree(priv);
-	return -ENOMEM;
+	kfree(exynos_domain);
+	return NULL;
 }
 
-static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+static void exynos_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	struct exynos_iommu_owner *owner;
 	unsigned long flags;
 	int i;
@@ -773,15 +781,14 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
 
 	free_pages((unsigned long)priv->pgtable, 2);
 	free_pages((unsigned long)priv->lv2entcnt, 1);
-	kfree(domain->priv);
-	domain->priv = NULL;
+	kfree(priv);
 }
 
 static int exynos_iommu_attach_device(struct iommu_domain *domain,
 				   struct device *dev)
 {
 	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
 	unsigned long flags;
 	int ret;
@@ -812,7 +819,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 				    struct device *dev)
 {
 	struct exynos_iommu_owner *owner;
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
 	unsigned long flags;
 
@@ -988,7 +995,7 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
 static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
 			 phys_addr_t paddr, size_t size, int prot)
 {
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	sysmmu_pte_t *entry;
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	unsigned long flags;
@@ -1042,7 +1049,7 @@ static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
 static size_t exynos_iommu_unmap(struct iommu_domain *domain,
 					unsigned long l_iova, size_t size)
 {
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	sysmmu_pte_t *ent;
 	size_t err_pgsize;
@@ -1119,7 +1126,7 @@ err:
 static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
 					  dma_addr_t iova)
 {
-	struct exynos_iommu_domain *priv = domain->priv;
+	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	sysmmu_pte_t *entry;
 	unsigned long flags;
 	phys_addr_t phys = 0;
@@ -1171,8 +1178,8 @@ static void exynos_iommu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops exynos_iommu_ops = {
-	.domain_init = exynos_iommu_domain_init,
-	.domain_destroy = exynos_iommu_domain_destroy,
+	.domain_alloc = exynos_iommu_domain_alloc,
+	.domain_free = exynos_iommu_domain_free,
 	.attach_dev = exynos_iommu_attach_device,
 	.detach_dev = exynos_iommu_detach_device,
 	.map = exynos_iommu_map,
-- 
1.9.1


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

* [PATCH 09/16] iommu/tegra-smmu: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (7 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 08/16] iommu/exynos: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-27 10:59   ` Thierry Reding
  2015-03-26 12:43 ` [PATCH 10/16] iommu/tegra-gart: " Joerg Roedel
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/tegra-smmu.c | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6e134c7..7208297 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -31,7 +31,7 @@ struct tegra_smmu {
 };
 
 struct tegra_smmu_as {
-	struct iommu_domain *domain;
+	struct iommu_domain domain;
 	struct tegra_smmu *smmu;
 	unsigned int use_count;
 	struct page *count;
@@ -40,6 +40,11 @@ struct tegra_smmu_as {
 	u32 attr;
 };
 
+static struct tegra_smmu_as *to_smmu_as(struct iommu_domain *dom)
+{
+	return container_of(dom, struct tegra_smmu_as, domain);
+}
+
 static inline void smmu_writel(struct tegra_smmu *smmu, u32 value,
 			       unsigned long offset)
 {
@@ -224,30 +229,32 @@ static bool tegra_smmu_capable(enum iommu_cap cap)
 	return false;
 }
 
-static int tegra_smmu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
 {
 	struct tegra_smmu_as *as;
 	unsigned int i;
 	uint32_t *pd;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	as = kzalloc(sizeof(*as), GFP_KERNEL);
 	if (!as)
-		return -ENOMEM;
+		return NULL;
 
 	as->attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE;
-	as->domain = domain;
 
 	as->pd = alloc_page(GFP_KERNEL | __GFP_DMA);
 	if (!as->pd) {
 		kfree(as);
-		return -ENOMEM;
+		return NULL;
 	}
 
 	as->count = alloc_page(GFP_KERNEL);
 	if (!as->count) {
 		__free_page(as->pd);
 		kfree(as);
-		return -ENOMEM;
+		return NULL;
 	}
 
 	/* clear PDEs */
@@ -264,14 +271,12 @@ static int tegra_smmu_domain_init(struct iommu_domain *domain)
 	for (i = 0; i < SMMU_NUM_PDE; i++)
 		pd[i] = 0;
 
-	domain->priv = as;
-
-	return 0;
+	return &as->domain;
 }
 
-static void tegra_smmu_domain_destroy(struct iommu_domain *domain)
+static void tegra_smmu_domain_free(struct iommu_domain *domain)
 {
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 
 	/* TODO: free page directory and page tables */
 	ClearPageReserved(as->pd);
@@ -395,7 +400,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
 	struct tegra_smmu *smmu = dev->archdata.iommu;
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 	struct device_node *np = dev->of_node;
 	struct of_phandle_args args;
 	unsigned int index = 0;
@@ -428,7 +433,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 
 static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
 {
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 	struct device_node *np = dev->of_node;
 	struct tegra_smmu *smmu = as->smmu;
 	struct of_phandle_args args;
@@ -524,7 +529,7 @@ static void as_put_pte(struct tegra_smmu_as *as, dma_addr_t iova)
 static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
 			  phys_addr_t paddr, size_t size, int prot)
 {
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 	struct tegra_smmu *smmu = as->smmu;
 	unsigned long offset;
 	struct page *page;
@@ -548,7 +553,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
 static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 			       size_t size)
 {
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 	struct tegra_smmu *smmu = as->smmu;
 	unsigned long offset;
 	struct page *page;
@@ -572,7 +577,7 @@ static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
 					   dma_addr_t iova)
 {
-	struct tegra_smmu_as *as = domain->priv;
+	struct tegra_smmu_as *as = to_smmu_as(domain);
 	struct page *page;
 	unsigned long pfn;
 	u32 *pte;
@@ -633,8 +638,8 @@ static void tegra_smmu_remove_device(struct device *dev)
 
 static const struct iommu_ops tegra_smmu_ops = {
 	.capable = tegra_smmu_capable,
-	.domain_init = tegra_smmu_domain_init,
-	.domain_destroy = tegra_smmu_domain_destroy,
+	.domain_alloc = tegra_smmu_domain_alloc,
+	.domain_free = tegra_smmu_domain_free,
 	.attach_dev = tegra_smmu_attach_dev,
 	.detach_dev = tegra_smmu_detach_dev,
 	.add_device = tegra_smmu_add_device,
-- 
1.9.1


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

* [PATCH 10/16] iommu/tegra-gart: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (8 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 09/16] iommu/tegra-smmu: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-27 11:00   ` Thierry Reding
  2015-03-26 12:43 ` [PATCH 11/16] iommu/msm: " Joerg Roedel
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/tegra-gart.c | 67 +++++++++++++++++++++++++++++++---------------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index c48da05..fc588a1 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -63,11 +63,21 @@ struct gart_device {
 	struct device		*dev;
 };
 
+struct gart_domain {
+	struct iommu_domain domain;		/* generic domain handle */
+	struct gart_device *gart;		/* link to gart device   */
+};
+
 static struct gart_device *gart_handle; /* unique for a system */
 
 #define GART_PTE(_pfn)						\
 	(GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT))
 
+static struct gart_domain *to_gart_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct gart_domain, domain);
+}
+
 /*
  * Any interaction between any block on PPSB and a block on APB or AHB
  * must have these read-back to ensure the APB/AHB bus transaction is
@@ -156,6 +166,7 @@ static inline bool gart_iova_range_valid(struct gart_device *gart,
 static int gart_iommu_attach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
+	struct gart_domain *gart_domain = to_gart_domain(domain);
 	struct gart_device *gart;
 	struct gart_client *client, *c;
 	int err = 0;
@@ -163,7 +174,7 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain,
 	gart = gart_handle;
 	if (!gart)
 		return -EINVAL;
-	domain->priv = gart;
+	gart_domain->gart = gart;
 
 	domain->geometry.aperture_start = gart->iovmm_base;
 	domain->geometry.aperture_end   = gart->iovmm_base +
@@ -198,7 +209,8 @@ fail:
 static void gart_iommu_detach_dev(struct iommu_domain *domain,
 				  struct device *dev)
 {
-	struct gart_device *gart = domain->priv;
+	struct gart_domain *gart_domain = to_gart_domain(domain);
+	struct gart_device *gart = gart_domain->gart;
 	struct gart_client *c;
 
 	spin_lock(&gart->client_lock);
@@ -216,33 +228,44 @@ out:
 	spin_unlock(&gart->client_lock);
 }
 
-static int gart_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *gart_iommu_domain_alloc(unsigned type)
 {
-	return 0;
+	struct gart_domain *gart_domain;
+
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
+	gart_domain = kzalloc(sizeof(*gart_domain), GFP_KERNEL);
+	if (!gart_domain)
+		return NULL;
+
+	return &gart_domain->domain;
 }
 
-static void gart_iommu_domain_destroy(struct iommu_domain *domain)
+static void gart_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct gart_device *gart = domain->priv;
-
-	if (!gart)
-		return;
+	struct gart_domain *gart_domain = to_gart_domain(domain);
+	struct gart_device *gart = gart_domain->gart;
 
-	spin_lock(&gart->client_lock);
-	if (!list_empty(&gart->client)) {
-		struct gart_client *c;
+	if (gart) {
+		spin_lock(&gart->client_lock);
+		if (!list_empty(&gart->client)) {
+			struct gart_client *c;
 
-		list_for_each_entry(c, &gart->client, list)
-			gart_iommu_detach_dev(domain, c->dev);
+			list_for_each_entry(c, &gart->client, list)
+				gart_iommu_detach_dev(domain, c->dev);
+		}
+		spin_unlock(&gart->client_lock);
 	}
-	spin_unlock(&gart->client_lock);
-	domain->priv = NULL;
+
+	kfree(gart_domain);
 }
 
 static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
 			  phys_addr_t pa, size_t bytes, int prot)
 {
-	struct gart_device *gart = domain->priv;
+	struct gart_domain *gart_domain = to_gart_domain(domain);
+	struct gart_device *gart = gart_domain->gart;
 	unsigned long flags;
 	unsigned long pfn;
 
@@ -265,7 +288,8 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
 static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
 			       size_t bytes)
 {
-	struct gart_device *gart = domain->priv;
+	struct gart_domain *gart_domain = to_gart_domain(domain);
+	struct gart_device *gart = gart_domain->gart;
 	unsigned long flags;
 
 	if (!gart_iova_range_valid(gart, iova, bytes))
@@ -281,7 +305,8 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
 static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
 					   dma_addr_t iova)
 {
-	struct gart_device *gart = domain->priv;
+	struct gart_domain *gart_domain = to_gart_domain(domain);
+	struct gart_device *gart = gart_domain->gart;
 	unsigned long pte;
 	phys_addr_t pa;
 	unsigned long flags;
@@ -310,8 +335,8 @@ static bool gart_iommu_capable(enum iommu_cap cap)
 
 static const struct iommu_ops gart_iommu_ops = {
 	.capable	= gart_iommu_capable,
-	.domain_init	= gart_iommu_domain_init,
-	.domain_destroy	= gart_iommu_domain_destroy,
+	.domain_alloc	= gart_iommu_domain_alloc,
+	.domain_free	= gart_iommu_domain_free,
 	.attach_dev	= gart_iommu_attach_dev,
 	.detach_dev	= gart_iommu_detach_dev,
 	.map		= gart_iommu_map,
-- 
1.9.1


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

* [PATCH 11/16] iommu/msm: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (9 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 10/16] iommu/tegra-gart: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 12/16] iommu/shmobile: " Joerg Roedel
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

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

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index e1b0537..15a2063 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -52,8 +52,14 @@ DEFINE_SPINLOCK(msm_iommu_lock);
 struct msm_priv {
 	unsigned long *pgtable;
 	struct list_head list_attached;
+	struct iommu_domain domain;
 };
 
+static struct msm_priv *to_msm_priv(struct iommu_domain *dom)
+{
+	return container_of(dom, struct msm_priv, domain);
+}
+
 static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
 {
 	int ret;
@@ -79,7 +85,7 @@ static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
 
 static int __flush_iotlb(struct iommu_domain *domain)
 {
-	struct msm_priv *priv = domain->priv;
+	struct msm_priv *priv = to_msm_priv(domain);
 	struct msm_iommu_drvdata *iommu_drvdata;
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret = 0;
@@ -209,10 +215,14 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
 	SET_M(base, ctx, 1);
 }
 
-static int msm_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *msm_iommu_domain_alloc(unsigned type)
 {
-	struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	struct msm_priv *priv;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		goto fail_nomem;
 
@@ -224,20 +234,19 @@ static int msm_iommu_domain_init(struct iommu_domain *domain)
 		goto fail_nomem;
 
 	memset(priv->pgtable, 0, SZ_16K);
-	domain->priv = priv;
 
-	domain->geometry.aperture_start = 0;
-	domain->geometry.aperture_end   = (1ULL << 32) - 1;
-	domain->geometry.force_aperture = true;
+	priv->domain.geometry.aperture_start = 0;
+	priv->domain.geometry.aperture_end   = (1ULL << 32) - 1;
+	priv->domain.geometry.force_aperture = true;
 
-	return 0;
+	return &priv->domain;
 
 fail_nomem:
 	kfree(priv);
-	return -ENOMEM;
+	return NULL;
 }
 
-static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+static void msm_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct msm_priv *priv;
 	unsigned long flags;
@@ -245,20 +254,17 @@ static void msm_iommu_domain_destroy(struct iommu_domain *domain)
 	int i;
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
-	priv = domain->priv;
-	domain->priv = NULL;
+	priv = to_msm_priv(domain);
 
-	if (priv) {
-		fl_table = priv->pgtable;
+	fl_table = priv->pgtable;
 
-		for (i = 0; i < NUM_FL_PTE; i++)
-			if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
-				free_page((unsigned long) __va(((fl_table[i]) &
-								FL_BASE_MASK)));
+	for (i = 0; i < NUM_FL_PTE; i++)
+		if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
+			free_page((unsigned long) __va(((fl_table[i]) &
+							FL_BASE_MASK)));
 
-		free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
-		priv->pgtable = NULL;
-	}
+	free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
+	priv->pgtable = NULL;
 
 	kfree(priv);
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
@@ -276,9 +282,9 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
 
-	priv = domain->priv;
+	priv = to_msm_priv(domain);
 
-	if (!priv || !dev) {
+	if (!dev) {
 		ret = -EINVAL;
 		goto fail;
 	}
@@ -330,9 +336,9 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
 	int ret;
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
-	priv = domain->priv;
+	priv = to_msm_priv(domain);
 
-	if (!priv || !dev)
+	if (!dev)
 		goto fail;
 
 	iommu_drvdata = dev_get_drvdata(dev->parent);
@@ -382,11 +388,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 		goto fail;
 	}
 
-	priv = domain->priv;
-	if (!priv) {
-		ret = -EINVAL;
-		goto fail;
-	}
+	priv = to_msm_priv(domain);
 
 	fl_table = priv->pgtable;
 
@@ -484,10 +486,7 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
 
-	priv = domain->priv;
-
-	if (!priv)
-		goto fail;
+	priv = to_msm_priv(domain);
 
 	fl_table = priv->pgtable;
 
@@ -566,7 +565,7 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
 
-	priv = domain->priv;
+	priv = to_msm_priv(domain);
 	if (list_empty(&priv->list_attached))
 		goto fail;
 
@@ -674,8 +673,8 @@ 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,
+	.domain_alloc = msm_iommu_domain_alloc,
+	.domain_free = msm_iommu_domain_free,
 	.attach_dev = msm_iommu_attach_dev,
 	.detach_dev = msm_iommu_detach_dev,
 	.map = msm_iommu_map,
-- 
1.9.1


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

* [PATCH 12/16] iommu/shmobile: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (10 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 11/16] iommu/msm: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 13/16] iommu/ipmmu-vmsa: " Joerg Roedel
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/shmobile-iommu.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index f1b0077..a028751 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -42,11 +42,17 @@ struct shmobile_iommu_domain {
 	spinlock_t map_lock;
 	spinlock_t attached_list_lock;
 	struct list_head attached_list;
+	struct iommu_domain domain;
 };
 
 static struct shmobile_iommu_archdata *ipmmu_archdata;
 static struct kmem_cache *l1cache, *l2cache;
 
+static struct shmobile_iommu_domain *to_sh_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct shmobile_iommu_domain, domain);
+}
+
 static int pgtable_alloc(struct shmobile_iommu_domain_pgtable *pgtable,
 			 struct kmem_cache *cache, size_t size)
 {
@@ -82,31 +88,33 @@ static void pgtable_write(struct shmobile_iommu_domain_pgtable *pgtable,
 				   sizeof(val) * count, DMA_TO_DEVICE);
 }
 
-static int shmobile_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *shmobile_iommu_domain_alloc(unsigned type)
 {
 	struct shmobile_iommu_domain *sh_domain;
 	int i, ret;
 
-	sh_domain = kmalloc(sizeof(*sh_domain), GFP_KERNEL);
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
+	sh_domain = kzalloc(sizeof(*sh_domain), GFP_KERNEL);
 	if (!sh_domain)
-		return -ENOMEM;
+		return NULL;
 	ret = pgtable_alloc(&sh_domain->l1, l1cache, L1_SIZE);
 	if (ret < 0) {
 		kfree(sh_domain);
-		return ret;
+		return NULL;
 	}
 	for (i = 0; i < L1_LEN; i++)
 		sh_domain->l2[i].pgtable = NULL;
 	spin_lock_init(&sh_domain->map_lock);
 	spin_lock_init(&sh_domain->attached_list_lock);
 	INIT_LIST_HEAD(&sh_domain->attached_list);
-	domain->priv = sh_domain;
-	return 0;
+	return &sh_domain->domain;
 }
 
-static void shmobile_iommu_domain_destroy(struct iommu_domain *domain)
+static void shmobile_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 	int i;
 
 	for (i = 0; i < L1_LEN; i++) {
@@ -115,14 +123,13 @@ static void shmobile_iommu_domain_destroy(struct iommu_domain *domain)
 	}
 	pgtable_free(&sh_domain->l1, l1cache, L1_SIZE);
 	kfree(sh_domain);
-	domain->priv = NULL;
 }
 
 static int shmobile_iommu_attach_device(struct iommu_domain *domain,
 					struct device *dev)
 {
 	struct shmobile_iommu_archdata *archdata = dev->archdata.iommu;
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 	int ret = -EBUSY;
 
 	if (!archdata)
@@ -151,7 +158,7 @@ static void shmobile_iommu_detach_device(struct iommu_domain *domain,
 					 struct device *dev)
 {
 	struct shmobile_iommu_archdata *archdata = dev->archdata.iommu;
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 
 	if (!archdata)
 		return;
@@ -214,7 +221,7 @@ static int shmobile_iommu_map(struct iommu_domain *domain, unsigned long iova,
 			      phys_addr_t paddr, size_t size, int prot)
 {
 	struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 	unsigned int l1index, l2index;
 	int ret;
 
@@ -258,7 +265,7 @@ static size_t shmobile_iommu_unmap(struct iommu_domain *domain,
 				   unsigned long iova, size_t size)
 {
 	struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 	unsigned int l1index, l2index;
 	uint32_t l2entry = 0;
 	size_t ret = 0;
@@ -298,7 +305,7 @@ done:
 static phys_addr_t shmobile_iommu_iova_to_phys(struct iommu_domain *domain,
 					       dma_addr_t iova)
 {
-	struct shmobile_iommu_domain *sh_domain = domain->priv;
+	struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 	uint32_t l1entry = 0, l2entry = 0;
 	unsigned int l1index, l2index;
 
@@ -355,8 +362,8 @@ static int shmobile_iommu_add_device(struct device *dev)
 }
 
 static const struct iommu_ops shmobile_iommu_ops = {
-	.domain_init = shmobile_iommu_domain_init,
-	.domain_destroy = shmobile_iommu_domain_destroy,
+	.domain_alloc = shmobile_iommu_domain_alloc,
+	.domain_free = shmobile_iommu_domain_free,
 	.attach_dev = shmobile_iommu_attach_device,
 	.detach_dev = shmobile_iommu_detach_device,
 	.map = shmobile_iommu_map,
-- 
1.9.1


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

* [PATCH 13/16] iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (11 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 12/16] iommu/shmobile: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 14/16] iommu/rockchip: " Joerg Roedel
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/ipmmu-vmsa.c | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 10186ca..274c08d 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -38,7 +38,7 @@ struct ipmmu_vmsa_device {
 
 struct ipmmu_vmsa_domain {
 	struct ipmmu_vmsa_device *mmu;
-	struct iommu_domain *io_domain;
+	struct iommu_domain io_domain;
 
 	struct io_pgtable_cfg cfg;
 	struct io_pgtable_ops *iop;
@@ -56,6 +56,11 @@ struct ipmmu_vmsa_archdata {
 static DEFINE_SPINLOCK(ipmmu_devices_lock);
 static LIST_HEAD(ipmmu_devices);
 
+static struct ipmmu_vmsa_domain *to_vmsa_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct ipmmu_vmsa_domain, io_domain);
+}
+
 #define TLB_LOOP_TIMEOUT		100	/* 100us */
 
 /* -----------------------------------------------------------------------------
@@ -428,7 +433,7 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain)
 	 * TODO: We need to look up the faulty device based on the I/O VA. Use
 	 * the IOMMU device for now.
 	 */
-	if (!report_iommu_fault(domain->io_domain, mmu->dev, iova, 0))
+	if (!report_iommu_fault(&domain->io_domain, mmu->dev, iova, 0))
 		return IRQ_HANDLED;
 
 	dev_err_ratelimited(mmu->dev,
@@ -448,7 +453,7 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
 		return IRQ_NONE;
 
 	io_domain = mmu->mapping->domain;
-	domain = io_domain->priv;
+	domain = to_vmsa_domain(io_domain);
 
 	return ipmmu_domain_irq(domain);
 }
@@ -457,25 +462,25 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
  * IOMMU Operations
  */
 
-static int ipmmu_domain_init(struct iommu_domain *io_domain)
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
 {
 	struct ipmmu_vmsa_domain *domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
-		return -ENOMEM;
+		return NULL;
 
 	spin_lock_init(&domain->lock);
 
-	io_domain->priv = domain;
-	domain->io_domain = io_domain;
-
-	return 0;
+	return &domain->io_domain;
 }
 
-static void ipmmu_domain_destroy(struct iommu_domain *io_domain)
+static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
 	/*
 	 * Free the domain resources. We assume that all devices have already
@@ -491,7 +496,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 {
 	struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
 	struct ipmmu_vmsa_device *mmu = archdata->mmu;
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 	unsigned long flags;
 	unsigned int i;
 	int ret = 0;
@@ -532,7 +537,7 @@ static void ipmmu_detach_device(struct iommu_domain *io_domain,
 				struct device *dev)
 {
 	struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 	unsigned int i;
 
 	for (i = 0; i < archdata->num_utlbs; ++i)
@@ -546,7 +551,7 @@ static void ipmmu_detach_device(struct iommu_domain *io_domain,
 static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova,
 		     phys_addr_t paddr, size_t size, int prot)
 {
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
 	if (!domain)
 		return -ENODEV;
@@ -557,7 +562,7 @@ static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova,
 static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova,
 			  size_t size)
 {
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
 	return domain->iop->unmap(domain->iop, iova, size);
 }
@@ -565,7 +570,7 @@ static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova,
 static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain,
 				      dma_addr_t iova)
 {
-	struct ipmmu_vmsa_domain *domain = io_domain->priv;
+	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
 	/* TODO: Is locking needed ? */
 
@@ -737,8 +742,8 @@ static void ipmmu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops ipmmu_ops = {
-	.domain_init = ipmmu_domain_init,
-	.domain_destroy = ipmmu_domain_destroy,
+	.domain_alloc = ipmmu_domain_alloc,
+	.domain_free = ipmmu_domain_free,
 	.attach_dev = ipmmu_attach_device,
 	.detach_dev = ipmmu_detach_device,
 	.map = ipmmu_map,
-- 
1.9.1


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

* [PATCH 14/16] iommu/rockchip: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (12 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 13/16] iommu/ipmmu-vmsa: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-26 12:43 ` [PATCH 15/16] iommu/fsl: " Joerg Roedel
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/rockchip-iommu.c | 40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9f74fdd..4015560 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -80,6 +80,8 @@ struct rk_iommu_domain {
 	u32 *dt; /* page directory table */
 	spinlock_t iommus_lock; /* lock for iommus list */
 	spinlock_t dt_lock; /* lock for modifying page directory table */
+
+	struct iommu_domain domain;
 };
 
 struct rk_iommu {
@@ -100,6 +102,11 @@ static inline void rk_table_flush(u32 *va, unsigned int count)
 	outer_flush_range(pa_start, pa_end);
 }
 
+static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct rk_iommu_domain, domain);
+}
+
 /**
  * Inspired by _wait_for in intel_drv.h
  * This is NOT safe for use in interrupt context.
@@ -503,7 +510,7 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain,
 					 dma_addr_t iova)
 {
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
 	phys_addr_t pt_phys, phys = 0;
 	u32 dte, pte;
@@ -639,7 +646,7 @@ unwind:
 static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
 			phys_addr_t paddr, size_t size, int prot)
 {
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
 	dma_addr_t iova = (dma_addr_t)_iova;
 	u32 *page_table, *pte_addr;
@@ -670,7 +677,7 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
 static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
 			     size_t size)
 {
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
 	dma_addr_t iova = (dma_addr_t)_iova;
 	phys_addr_t pt_phys;
@@ -726,7 +733,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 				  struct device *dev)
 {
 	struct rk_iommu *iommu;
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
 	int ret;
 	phys_addr_t dte_addr;
@@ -778,7 +785,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 				   struct device *dev)
 {
 	struct rk_iommu *iommu;
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
 
 	/* Allow 'virtual devices' (eg drm) to detach from domain */
@@ -804,13 +811,16 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 	dev_info(dev, "Detached from iommu domain\n");
 }
 
-static int rk_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 {
 	struct rk_iommu_domain *rk_domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL);
 	if (!rk_domain)
-		return -ENOMEM;
+		return NULL;
 
 	/*
 	 * rk32xx iommus use a 2 level pagetable.
@@ -827,17 +837,16 @@ static int rk_iommu_domain_init(struct iommu_domain *domain)
 	spin_lock_init(&rk_domain->dt_lock);
 	INIT_LIST_HEAD(&rk_domain->iommus);
 
-	domain->priv = rk_domain;
+	return &rk_domain->domain;
 
-	return 0;
 err_dt:
 	kfree(rk_domain);
-	return -ENOMEM;
+	return NULL;
 }
 
-static void rk_iommu_domain_destroy(struct iommu_domain *domain)
+static void rk_iommu_domain_free(struct iommu_domain *domain)
 {
-	struct rk_iommu_domain *rk_domain = domain->priv;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	int i;
 
 	WARN_ON(!list_empty(&rk_domain->iommus));
@@ -852,8 +861,7 @@ static void rk_iommu_domain_destroy(struct iommu_domain *domain)
 	}
 
 	free_page((unsigned long)rk_domain->dt);
-	kfree(domain->priv);
-	domain->priv = NULL;
+	kfree(rk_domain);
 }
 
 static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -952,8 +960,8 @@ static void rk_iommu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops rk_iommu_ops = {
-	.domain_init = rk_iommu_domain_init,
-	.domain_destroy = rk_iommu_domain_destroy,
+	.domain_alloc = rk_iommu_domain_alloc,
+	.domain_free = rk_iommu_domain_free,
 	.attach_dev = rk_iommu_attach_device,
 	.detach_dev = rk_iommu_detach_device,
 	.map = rk_iommu_map,
-- 
1.9.1


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

* [PATCH 15/16] iommu/fsl: Make use of domain_alloc and domain_free
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (13 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 14/16] iommu/rockchip: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-04-12 14:25   ` Varun Sethi
  2015-03-26 12:43 ` [PATCH 16/16] iommu: Remove domain_init and domain_free iommu_ops Joerg Roedel
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/fsl_pamu_domain.c | 60 ++++++++++++++++++++++-------------------
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index ceebd28..1d45293 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -33,6 +33,11 @@ static struct kmem_cache *fsl_pamu_domain_cache;
 static struct kmem_cache *iommu_devinfo_cache;
 static DEFINE_SPINLOCK(device_domain_lock);
 
+static struct fsl_dma_domain *to_fsl_dma_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct fsl_dma_domain, iommu_domain);
+}
+
 static int __init iommu_init_mempool(void)
 {
 	fsl_pamu_domain_cache = kmem_cache_create("fsl_pamu_domain",
@@ -65,7 +70,7 @@ static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, dma_addr_t i
 	struct dma_window *win_ptr = &dma_domain->win_arr[0];
 	struct iommu_domain_geometry *geom;
 
-	geom = &dma_domain->iommu_domain->geometry;
+	geom = &dma_domain->iommu_domain.geometry;
 
 	if (!win_cnt || !dma_domain->geom_size) {
 		pr_debug("Number of windows/geometry not configured for the domain\n");
@@ -123,7 +128,7 @@ static int map_win(int liodn, struct fsl_dma_domain *dma_domain)
 {
 	int ret;
 	struct dma_window *wnd = &dma_domain->win_arr[0];
-	phys_addr_t wnd_addr = dma_domain->iommu_domain->geometry.aperture_start;
+	phys_addr_t wnd_addr = dma_domain->iommu_domain.geometry.aperture_start;
 	unsigned long flags;
 
 	spin_lock_irqsave(&iommu_lock, flags);
@@ -172,7 +177,7 @@ static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr
 	} else {
 		phys_addr_t wnd_addr;
 
-		wnd_addr = dma_domain->iommu_domain->geometry.aperture_start;
+		wnd_addr = dma_domain->iommu_domain.geometry.aperture_start;
 
 		ret = pamu_config_ppaace(liodn, wnd_addr,
 					 wnd->size,
@@ -384,7 +389,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
 static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
 					 dma_addr_t iova)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 
 	if (iova < domain->geometry.aperture_start ||
 	    iova > domain->geometry.aperture_end)
@@ -398,11 +403,9 @@ static bool fsl_pamu_capable(enum iommu_cap cap)
 	return cap == IOMMU_CAP_CACHE_COHERENCY;
 }
 
-static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
+static void fsl_pamu_domain_free(struct iommu_domain *domain)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
-
-	domain->priv = NULL;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 
 	/* remove all the devices from the device list */
 	detach_device(NULL, dma_domain);
@@ -413,23 +416,24 @@ static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
 	kmem_cache_free(fsl_pamu_domain_cache, dma_domain);
 }
 
-static int fsl_pamu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type)
 {
 	struct fsl_dma_domain *dma_domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	dma_domain = iommu_alloc_dma_domain();
 	if (!dma_domain) {
 		pr_debug("dma_domain allocation failed\n");
-		return -ENOMEM;
+		return NULL;
 	}
-	domain->priv = dma_domain;
-	dma_domain->iommu_domain = domain;
 	/* defaul geometry 64 GB i.e. maximum system address */
-	domain->geometry.aperture_start = 0;
-	domain->geometry.aperture_end = (1ULL << 36) - 1;
-	domain->geometry.force_aperture = true;
+	dma_domain->iommu_domain. geometry.aperture_start = 0;
+	dma_domain->iommu_domain.geometry.aperture_end = (1ULL << 36) - 1;
+	dma_domain->iommu_domain.geometry.force_aperture = true;
 
-	return 0;
+	return &dma_domain->iommu_domain;
 }
 
 /* Configure geometry settings for all LIODNs associated with domain */
@@ -499,7 +503,7 @@ static int disable_domain_win(struct fsl_dma_domain *dma_domain, u32 wnd_nr)
 
 static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	unsigned long flags;
 	int ret;
 
@@ -530,7 +534,7 @@ static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr)
 static int fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr,
 				  phys_addr_t paddr, u64 size, int prot)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	struct dma_window *wnd;
 	int pamu_prot = 0;
 	int ret;
@@ -607,7 +611,7 @@ static int handle_attach_device(struct fsl_dma_domain *dma_domain,
 				int num)
 {
 	unsigned long flags;
-	struct iommu_domain *domain = dma_domain->iommu_domain;
+	struct iommu_domain *domain = &dma_domain->iommu_domain;
 	int ret = 0;
 	int i;
 
@@ -653,7 +657,7 @@ static int handle_attach_device(struct fsl_dma_domain *dma_domain,
 static int fsl_pamu_attach_device(struct iommu_domain *domain,
 				  struct device *dev)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	const u32 *liodn;
 	u32 liodn_cnt;
 	int len, ret = 0;
@@ -691,7 +695,7 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
 static void fsl_pamu_detach_device(struct iommu_domain *domain,
 				   struct device *dev)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	const u32 *prop;
 	int len;
 	struct pci_dev *pdev = NULL;
@@ -723,7 +727,7 @@ static void fsl_pamu_detach_device(struct iommu_domain *domain,
 static  int configure_domain_geometry(struct iommu_domain *domain, void *data)
 {
 	struct iommu_domain_geometry *geom_attr = data;
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	dma_addr_t geom_size;
 	unsigned long flags;
 
@@ -813,7 +817,7 @@ static int configure_domain_dma_state(struct fsl_dma_domain *dma_domain, bool en
 static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
 				    enum iommu_attr attr_type, void *data)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	int ret = 0;
 
 	switch (attr_type) {
@@ -838,7 +842,7 @@ static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
 static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
 				    enum iommu_attr attr_type, void *data)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	int ret = 0;
 
 	switch (attr_type) {
@@ -999,7 +1003,7 @@ static void fsl_pamu_remove_device(struct device *dev)
 
 static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 	unsigned long flags;
 	int ret;
 
@@ -1048,15 +1052,15 @@ static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
 
 static u32 fsl_pamu_get_windows(struct iommu_domain *domain)
 {
-	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 
 	return dma_domain->win_cnt;
 }
 
 static const struct iommu_ops fsl_pamu_ops = {
 	.capable	= fsl_pamu_capable,
-	.domain_init	= fsl_pamu_domain_init,
-	.domain_destroy = fsl_pamu_domain_destroy,
+	.domain_alloc	= fsl_pamu_domain_alloc,
+	.domain_free    = fsl_pamu_domain_free,
 	.attach_dev	= fsl_pamu_attach_device,
 	.detach_dev	= fsl_pamu_detach_device,
 	.domain_window_enable = fsl_pamu_window_enable,
diff --git a/drivers/iommu/fsl_pamu_domain.h b/drivers/iommu/fsl_pamu_domain.h
index c90293f..f2b0f74 100644
--- a/drivers/iommu/fsl_pamu_domain.h
+++ b/drivers/iommu/fsl_pamu_domain.h
@@ -71,7 +71,7 @@ struct fsl_dma_domain {
 	u32				stash_id;
 	struct pamu_stash_attribute	dma_stash;
 	u32				snoop_id;
-	struct iommu_domain		*iommu_domain;
+	struct iommu_domain		iommu_domain;
 	spinlock_t			domain_lock;
 };
 
-- 
1.9.1


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

* [PATCH 16/16] iommu: Remove domain_init and domain_free iommu_ops
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (14 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 15/16] iommu/fsl: " Joerg Roedel
@ 2015-03-26 12:43 ` Joerg Roedel
  2015-03-27 11:03 ` [PATCH 00/16 v2] iommu: Move domain allocation into drivers Thierry Reding
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-26 12:43 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

From: Joerg Roedel <jroedel@suse.de>

All drivers have been converted to the new domain_alloc and
domain_free iommu-ops. So remove the old ones and get rid of
iommu_domain->priv too, as this is no longer needed when the
struct iommu_domain is embedded in the private structures of
the iommu drivers.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 656b949..d4f527e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -900,51 +900,25 @@ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
 
 struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
-	const struct iommu_ops *ops;
 	struct iommu_domain *domain;
 
 	if (bus == NULL || bus->iommu_ops == NULL)
 		return NULL;
 
-	ops = bus->iommu_ops;
-
-	if (ops->domain_alloc)
-		domain = ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
-	else
-		domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-
+	domain = bus->iommu_ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
 	if (!domain)
 		return NULL;
 
 	domain->ops  = bus->iommu_ops;
 	domain->type = IOMMU_DOMAIN_UNMANAGED;
 
-	if (ops->domain_init && domain->ops->domain_init(domain))
-		goto out_free;
-
 	return domain;
-
-out_free:
-	if (ops->domain_free)
-		ops->domain_free(domain);
-	else
-		kfree(domain);
-
-	return NULL;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
-	const struct iommu_ops *ops = domain->ops;
-
-	if (likely(ops->domain_destroy != NULL))
-		ops->domain_destroy(domain);
-
-	if (ops->domain_free)
-		ops->domain_free(domain);
-	else
-		kfree(domain);
+	domain->ops->domain_free(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 72d03fe..0546b87 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -78,7 +78,6 @@ struct iommu_domain_geometry {
 struct iommu_domain {
 	unsigned type;
 	const struct iommu_ops *ops;
-	void *priv;
 	iommu_fault_handler_t handler;
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
@@ -138,8 +137,6 @@ enum iommu_attr {
  */
 struct iommu_ops {
 	bool (*capable)(enum iommu_cap);
-	int (*domain_init)(struct iommu_domain *domain);
-	void (*domain_destroy)(struct iommu_domain *domain);
 
 	/* Domain allocation and freeing by the iommu driver */
 	struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
-- 
1.9.1


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

* Re: [PATCH 02/16] iommu: Introduce iommu domain types
  2015-03-26 12:43 ` [PATCH 02/16] iommu: Introduce iommu domain types Joerg Roedel
@ 2015-03-26 12:52   ` Swapna Nannapaneni
  0 siblings, 0 replies; 28+ messages in thread
From: Swapna Nannapaneni @ 2015-03-26 12:52 UTC (permalink / raw)
  To: Joerg Roedel, iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	Joerg Roedel, jroedel

X

Sent from my BlackBerry 10 smartphone on the TELUS network.
  Original Message  
From: Joerg Roedel
Sentuv: Thursday, March 26, 2015 8:51 AM
To: iommu@lists.linux-foundation.org
Cc: Will Deacon; Kukjin Kim; David Woodhouse; Heiko Stuebner; Hiroshi Doyu; Stephen Warren; Thierry Reding; Alexandre Courbot; Alex Williamson; Arnd Bergmann; Yingjoe Chen; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-samsung-soc@vger.kernel.org; linux-rockchip@lists.infradead.org; linux-tegra@vger.kernel.org; Joerg Roedel; jroedel@suse.de
Subject: [PATCH 02/16] iommu: Introduce iommu domain types

From: Joerg Roedel <jroedel@suse.de>

This allows to handle domains differently based on their
type in the future. An IOMMU driver can implement certain
optimizations for DMA-API domains for example.

The domain types can be extended later and some of the
existing domain attributes can be migrated to become domain
flags.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 11de262..4920605 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -909,14 +909,15 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
ops = bus->iommu_ops;

if (ops->domain_alloc)
-	 domain = ops->domain_alloc();
+	 domain = ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
else
domain = kzalloc(sizeof(*domain), GFP_KERNEL);

if (!domain)
return NULL;

-	domain->ops = bus->iommu_ops;
+	domain->ops = bus->iommu_ops;
+	domain->type = IOMMU_DOMAIN_UNMANAGED;

if (ops->domain_init && domain->ops->domain_init(domain))
goto out_free;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 69d1d12..72d03fe 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -51,7 +51,32 @@ struct iommu_domain_geometry {
bool force_aperture; /* DMA only allowed in mappable range? */
};

+/* Domain feature flags */
+#define __IOMMU_DOMAIN_PAGING	(1U << 0) /* Support for iommu_map/unmap */
+#define __IOMMU_DOMAIN_DMA_API	(1U << 1) /* Domain for use in DMA-API
+	 implementation */
+#define __IOMMU_DOMAIN_PT	(1U << 2) /* Domain is identity mapped */
+
+/*
+ * This are the possible domain-types
+ *
+ *	IOMMU_DOMAIN_BLOCKED	- All DMA is blocked, can be used to isolate
+ *	 devices
+ *	IOMMU_DOMAIN_IDENTITY	- DMA addresses are system physical addresses
+ *	IOMMU_DOMAIN_UNMANAGED	- DMA mappings managed by IOMMU-API user, used
+ *	 for VMs
+ *	IOMMU_DOMAIN_DMA	- Internally used for DMA-API implementations.
+ *	 This flag allows IOMMU drivers to implement
+ *	 certain optimizations for these domains
+ */
+#define IOMMU_DOMAIN_BLOCKED	(0U)
+#define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
+#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
+#define IOMMU_DOMAIN_DMA	(__IOMMU_DOMAIN_PAGING |	\
+	 __IOMMU_DOMAIN_DMA_API)
+
struct iommu_domain {
+	unsigned type;
const struct iommu_ops *ops;
void *priv;
iommu_fault_handler_t handler;
@@ -117,7 +142,7 @@ struct iommu_ops {
void (*domain_destroy)(struct iommu_domain *domain);

/* Domain allocation and freeing by the iommu driver */
-	struct iommu_domain *(*domain_alloc)(void);
+	struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
void (*domain_free)(struct iommu_domain *);

int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 09/16] iommu/tegra-smmu: Make use of domain_alloc and domain_free
  2015-03-26 12:43 ` [PATCH 09/16] iommu/tegra-smmu: " Joerg Roedel
@ 2015-03-27 10:59   ` Thierry Reding
  0 siblings, 0 replies; 28+ messages in thread
From: Thierry Reding @ 2015-03-27 10:59 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Alexandre Courbot, Alex Williamson,
	Arnd Bergmann, Yingjoe Chen, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-rockchip, linux-tegra, jroedel

[-- Attachment #1: Type: text/plain, Size: 452 bytes --]

On Thu, Mar 26, 2015 at 01:43:12PM +0100, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Implement domain_alloc and domain_free iommu-ops as a
> replacement for domain_init/domain_destroy.
> 
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/tegra-smmu.c | 41 +++++++++++++++++++++++------------------
>  1 file changed, 23 insertions(+), 18 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 10/16] iommu/tegra-gart: Make use of domain_alloc and domain_free
  2015-03-26 12:43 ` [PATCH 10/16] iommu/tegra-gart: " Joerg Roedel
@ 2015-03-27 11:00   ` Thierry Reding
  0 siblings, 0 replies; 28+ messages in thread
From: Thierry Reding @ 2015-03-27 11:00 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Alexandre Courbot, Alex Williamson,
	Arnd Bergmann, Yingjoe Chen, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-rockchip, linux-tegra, jroedel

[-- Attachment #1: Type: text/plain, Size: 457 bytes --]

On Thu, Mar 26, 2015 at 01:43:13PM +0100, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> Implement domain_alloc and domain_free iommu-ops as a
> replacement for domain_init/domain_destroy.
> 
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/tegra-gart.c | 67 +++++++++++++++++++++++++++++++---------------
>  1 file changed, 46 insertions(+), 21 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (15 preceding siblings ...)
  2015-03-26 12:43 ` [PATCH 16/16] iommu: Remove domain_init and domain_free iommu_ops Joerg Roedel
@ 2015-03-27 11:03 ` Thierry Reding
  2015-03-27 16:39 ` Heiko Stuebner
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Thierry Reding @ 2015-03-27 11:03 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Alexandre Courbot, Alex Williamson,
	Arnd Bergmann, Yingjoe Chen, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-rockchip, linux-tegra, jroedel

[-- Attachment #1: Type: text/plain, Size: 3191 bytes --]

On Thu, Mar 26, 2015 at 01:43:03PM +0100, Joerg Roedel wrote:
> Changes v1-v2:
> 
> 	* Rebased to v4.0-rc5
> 	* Converted domain-types to a bit-field
> 
> Hi,
> 
> here is patch-set to replace the existing domain_init and
> domain_destroy iommu-ops with the new domain_alloc and
> domain_free callbacks
> 
> The new callbacks move the allocation of iommu domains into
> the iommu driver, allowing them to put a generic
> iommu_domain struct into their own domain struct. This makes
> domain handling in the drivers more cache efficient and
> prepares the introduction of default domains in another
> patch-set.
> 
> While at it, this patch-set also introduces domain types.
> These are internal to the iommu core code for now, there are
> three of them:
> 
> 	* DMA-API domains
> 	* Identity mapped domains
> 	* Domains unmanaged by the iommu-core, used for
> 	  iommu-api so that the users can create their own
> 	  mappings
> 
> The patches have been compile tested for x86, ARM and PPC
> and runtime tested on x86 (Intel VT-d and AMD IOMMU).
> 
> Please review.
> 
> Thanks,
> 
> 	Joerg
> 
> Joerg Roedel (15):
>   iommu: Introduce domain_alloc and domain_free iommu_ops
>   iommu: Introduce iommu domain types
>   iommu/amd: Make use of domain_alloc and domain_free
>   iommu/vt-d: Make use of domain_alloc and domain_free
>   iommu/omap: Make use of domain_alloc and domain_free
>   iommu/arm-smmu: Make use of domain_alloc and domain_free
>   iommu/exynos: Make use of domain_alloc and domain_free
>   iommu/tegra-smmu: Make use of domain_alloc and domain_free
>   iommu/tegra-gart: Make use of domain_alloc and domain_free
>   iommu/msm: Make use of domain_alloc and domain_free
>   iommu/shmobile: Make use of domain_alloc and domain_free
>   iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
>   iommu/rockchip: Make use of domain_alloc and domain_free
>   iommu/fsl: Make use of domain_alloc and domain_free
>   iommu: Remove domain_init and domain_free iommu_ops
> 
>  drivers/iommu/amd_iommu.c       | 84 +++++++++++++++++++++------------------
>  drivers/iommu/amd_iommu_types.h |  7 ++--
>  drivers/iommu/arm-smmu.c        | 46 +++++++++++++---------
>  drivers/iommu/exynos-iommu.c    | 87 ++++++++++++++++++++++-------------------
>  drivers/iommu/fsl_pamu_domain.c | 60 +++++++++++++++-------------
>  drivers/iommu/fsl_pamu_domain.h |  2 +-
>  drivers/iommu/intel-iommu.c     | 48 +++++++++++++----------
>  drivers/iommu/iommu.c           | 20 ++--------
>  drivers/iommu/ipmmu-vmsa.c      | 43 +++++++++++---------
>  drivers/iommu/msm_iommu.c       | 73 +++++++++++++++++-----------------
>  drivers/iommu/omap-iommu.c      | 49 +++++++++++++----------
>  drivers/iommu/rockchip-iommu.c  | 40 +++++++++++--------
>  drivers/iommu/shmobile-iommu.c  | 40 +++++++++++--------
>  drivers/iommu/tegra-gart.c      | 67 +++++++++++++++++++++----------
>  drivers/iommu/tegra-smmu.c      | 41 ++++++++++---------
>  include/linux/iommu.h           | 17 ++++++--
>  16 files changed, 407 insertions(+), 317 deletions(-)

The core and Tegra bits:

Tested-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (16 preceding siblings ...)
  2015-03-27 11:03 ` [PATCH 00/16 v2] iommu: Move domain allocation into drivers Thierry Reding
@ 2015-03-27 16:39 ` Heiko Stuebner
  2015-03-28  4:24 ` Alex Williamson
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Heiko Stuebner @ 2015-03-27 16:39 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Hiroshi Doyu,
	Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	jroedel

Am Donnerstag, 26. März 2015, 13:43:03 schrieb Joerg Roedel:
> Changes v1-v2:
> 
> 	* Rebased to v4.0-rc5
> 	* Converted domain-types to a bit-field
> 
> Hi,
> 
> here is patch-set to replace the existing domain_init and
> domain_destroy iommu-ops with the new domain_alloc and
> domain_free callbacks
> 
> The new callbacks move the allocation of iommu domains into
> the iommu driver, allowing them to put a generic
> iommu_domain struct into their own domain struct. This makes
> domain handling in the drivers more cache efficient and
> prepares the introduction of default domains in another
> patch-set.
> 
> While at it, this patch-set also introduces domain types.
> These are internal to the iommu core code for now, there are
> three of them:
> 
> 	* DMA-API domains
> 	* Identity mapped domains
> 	* Domains unmanaged by the iommu-core, used for
> 	  iommu-api so that the users can create their own
> 	  mappings
> 
> The patches have been compile tested for x86, ARM and PPC
> and runtime tested on x86 (Intel VT-d and AMD IOMMU).
> 
> Please review.

core and Rockchip bits
Tested-by: Heiko Stuebner <heiko@sntech.de>


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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (17 preceding siblings ...)
  2015-03-27 16:39 ` Heiko Stuebner
@ 2015-03-28  4:24 ` Alex Williamson
  2015-03-31 13:14   ` Joerg Roedel
  2015-03-30 17:43 ` Will Deacon
  2015-03-31 13:33 ` Joerg Roedel
  20 siblings, 1 reply; 28+ messages in thread
From: Alex Williamson @ 2015-03-28  4:24 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Arnd Bergmann, Yingjoe Chen, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-rockchip, linux-tegra, jroedel

On Thu, 2015-03-26 at 13:43 +0100, Joerg Roedel wrote:
> Changes v1-v2:
> 
> 	* Rebased to v4.0-rc5
> 	* Converted domain-types to a bit-field
> 
> Hi,
> 
> here is patch-set to replace the existing domain_init and
> domain_destroy iommu-ops with the new domain_alloc and
> domain_free callbacks
> 
> The new callbacks move the allocation of iommu domains into
> the iommu driver, allowing them to put a generic
> iommu_domain struct into their own domain struct. This makes
> domain handling in the drivers more cache efficient and
> prepares the introduction of default domains in another
> patch-set.
> 
> While at it, this patch-set also introduces domain types.
> These are internal to the iommu core code for now, there are
> three of them:
> 
> 	* DMA-API domains
> 	* Identity mapped domains
> 	* Domains unmanaged by the iommu-core, used for
> 	  iommu-api so that the users can create their own
> 	  mappings
> 
> The patches have been compile tested for x86, ARM and PPC
> and runtime tested on x86 (Intel VT-d and AMD IOMMU).
> 
> Please review.

For 1-5,16

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

My only comment/question is whether you'd want to consider using
ERR_PTR() return values from domain_alloc().  It's an alloc functions,
so NULL == -ENOMEM is pretty standard, but we could at least have the
interface to the iommu driver return more info even if we continue to
mask that as NULL out to the IOMMU API users for now.  Thanks,

Alex


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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (18 preceding siblings ...)
  2015-03-28  4:24 ` Alex Williamson
@ 2015-03-30 17:43 ` Will Deacon
  2015-03-31 13:18   ` Joerg Roedel
  2015-03-31 13:33 ` Joerg Roedel
  20 siblings, 1 reply; 28+ messages in thread
From: Will Deacon @ 2015-03-30 17:43 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, Kukjin Kim, David Woodhouse, Heiko Stuebner, Hiroshi Doyu,
	Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	jroedel

Hi Joerg,

On Thu, Mar 26, 2015 at 12:43:03PM +0000, Joerg Roedel wrote:
> Changes v1-v2:
> 
> 	* Rebased to v4.0-rc5
> 	* Converted domain-types to a bit-field
> 
> Hi,
> 
> here is patch-set to replace the existing domain_init and
> domain_destroy iommu-ops with the new domain_alloc and
> domain_free callbacks

Whilst I'm still a bit worried about the ability of the IOMMU driver to do
very much in the ->domain_alloc callback (since we don't know which IOMMU
instance the domain is for), it doesn't leave us any worse off than we
currently are.

So, for the arm-smmu patch and the core IOMMU changes:

  Acked-by: Will Deacon <will.deacon@arm.com>

Hopefully this doesn't conflict too badly with my outstanding arm-smmu
pull requests to you, but do shout if you have any trouble.

Will

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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-28  4:24 ` Alex Williamson
@ 2015-03-31 13:14   ` Joerg Roedel
  0 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-31 13:14 UTC (permalink / raw)
  To: Alex Williamson
  Cc: iommu, Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Arnd Bergmann, Yingjoe Chen, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-rockchip, linux-tegra, jroedel

Hi Alex,

On Fri, Mar 27, 2015 at 10:24:22PM -0600, Alex Williamson wrote:
> For 1-5,16
> 
> Reviewed-by: Alex Williamson <alex.williamson@redhat.com>

Thanks a lot for your review.

> My only comment/question is whether you'd want to consider using
> ERR_PTR() return values from domain_alloc().  It's an alloc functions,
> so NULL == -ENOMEM is pretty standard, but we could at least have the
> interface to the iommu driver return more info even if we continue to
> mask that as NULL out to the IOMMU API users for now.  Thanks,

Yes, that might make sense. But to do anything useful with the ERR_PTR
we also need to change the iommu_domain_alloc() interface. This is
out-of-scope for this patch-set, we can discuss this seperatly.


	Joerg


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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-30 17:43 ` Will Deacon
@ 2015-03-31 13:18   ` Joerg Roedel
  0 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-31 13:18 UTC (permalink / raw)
  To: Will Deacon
  Cc: iommu, Kukjin Kim, David Woodhouse, Heiko Stuebner, Hiroshi Doyu,
	Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	jroedel

Hi Will,

On Mon, Mar 30, 2015 at 06:43:15PM +0100, Will Deacon wrote:
> Whilst I'm still a bit worried about the ability of the IOMMU driver to do
> very much in the ->domain_alloc callback (since we don't know which IOMMU
> instance the domain is for), it doesn't leave us any worse off than we
> currently are.

The IOMMU driver should just allocate the data-structures for a domain
in the domain_alloc call-back. It should not be necessary to care about
any relations of the domain with specific iommu instances.
 
> So, for the arm-smmu patch and the core IOMMU changes:
> 
>   Acked-by: Will Deacon <will.deacon@arm.com>

Thanks a lot!


	Joerg


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

* Re: [PATCH 00/16 v2] iommu: Move domain allocation into drivers
  2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
                   ` (19 preceding siblings ...)
  2015-03-30 17:43 ` Will Deacon
@ 2015-03-31 13:33 ` Joerg Roedel
  20 siblings, 0 replies; 28+ messages in thread
From: Joerg Roedel @ 2015-03-31 13:33 UTC (permalink / raw)
  To: iommu
  Cc: Will Deacon, Kukjin Kim, David Woodhouse, Heiko Stuebner,
	Hiroshi Doyu, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Alex Williamson, Arnd Bergmann, Yingjoe Chen, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, linux-rockchip, linux-tegra,
	jroedel

On Thu, Mar 26, 2015 at 01:43:03PM +0100, Joerg Roedel wrote:
> Changes v1-v2:
> 
> 	* Rebased to v4.0-rc5
> 	* Converted domain-types to a bit-field

Applied this series to the core branch.


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

* RE: [PATCH 15/16] iommu/fsl: Make use of domain_alloc and domain_free
  2015-03-26 12:43 ` [PATCH 15/16] iommu/fsl: " Joerg Roedel
@ 2015-04-12 14:25   ` Varun Sethi
  0 siblings, 0 replies; 28+ messages in thread
From: Varun Sethi @ 2015-04-12 14:25 UTC (permalink / raw)
  To: Joerg Roedel, iommu
  Cc: Alexandre Courbot, linux-samsung-soc, Heiko Stuebner,
	Arnd Bergmann, Stephen Warren, Will Deacon, linux-kernel,
	linux-rockchip, Kukjin Kim, Thierry Reding, jroedel, linux-tegra,
	Yingjoe Chen, David Woodhouse, linux-arm-kernel



> -----Original Message-----
> From: iommu-bounces@lists.linux-foundation.org [mailto:iommu-
> bounces@lists.linux-foundation.org] On Behalf Of Joerg Roedel
> Sent: Thursday, March 26, 2015 6:13 PM
> To: iommu@lists.linux-foundation.org
> Cc: Alexandre Courbot; linux-samsung-soc@vger.kernel.org; Heiko Stuebner;
> Arnd Bergmann; Stephen Warren; Will Deacon; linux-
> kernel@vger.kernel.org; linux-rockchip@lists.infradead.org; Kukjin Kim;
> Thierry Reding; jroedel@suse.de; linux-tegra@vger.kernel.org; Yingjoe
> Chen; David Woodhouse; linux-arm-kernel@lists.infradead.org
> Subject: [PATCH 15/16] iommu/fsl: Make use of domain_alloc and
> domain_free
> 
> From: Joerg Roedel <jroedel@suse.de>
> 
> Implement domain_alloc and domain_free iommu-ops as a replacement for
> domain_init/domain_destroy.
> 
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/fsl_pamu_domain.c | 60 ++++++++++++++++++++++--------
> -----------
>  drivers/iommu/fsl_pamu_domain.h |  2 +-
>  2 files changed, 33 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/iommu/fsl_pamu_domain.c
> b/drivers/iommu/fsl_pamu_domain.c index ceebd28..1d45293 100644
> --- a/drivers/iommu/fsl_pamu_domain.c
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -33,6 +33,11 @@ static struct kmem_cache *fsl_pamu_domain_cache;
> static struct kmem_cache *iommu_devinfo_cache;  static
> DEFINE_SPINLOCK(device_domain_lock);
> 
> +static struct fsl_dma_domain *to_fsl_dma_domain(struct iommu_domain
> +*dom) {
> +	return container_of(dom, struct fsl_dma_domain, iommu_domain);
> }
> +
>  static int __init iommu_init_mempool(void)  {
>  	fsl_pamu_domain_cache =
> kmem_cache_create("fsl_pamu_domain",
> @@ -65,7 +70,7 @@ static phys_addr_t get_phys_addr(struct
> fsl_dma_domain *dma_domain, dma_addr_t i
>  	struct dma_window *win_ptr = &dma_domain->win_arr[0];
>  	struct iommu_domain_geometry *geom;
> 
> -	geom = &dma_domain->iommu_domain->geometry;
> +	geom = &dma_domain->iommu_domain.geometry;
> 
>  	if (!win_cnt || !dma_domain->geom_size) {
>  		pr_debug("Number of windows/geometry not configured
> for the domain\n"); @@ -123,7 +128,7 @@ static int map_win(int liodn,
> struct fsl_dma_domain *dma_domain)  {
>  	int ret;
>  	struct dma_window *wnd = &dma_domain->win_arr[0];
> -	phys_addr_t wnd_addr = dma_domain->iommu_domain-
> >geometry.aperture_start;
> +	phys_addr_t wnd_addr =
> +dma_domain->iommu_domain.geometry.aperture_start;
>  	unsigned long flags;
> 
>  	spin_lock_irqsave(&iommu_lock, flags); @@ -172,7 +177,7 @@ static
> int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32
> wnd_nr
>  	} else {
>  		phys_addr_t wnd_addr;
> 
> -		wnd_addr = dma_domain->iommu_domain-
> >geometry.aperture_start;
> +		wnd_addr = dma_domain-
> >iommu_domain.geometry.aperture_start;
> 
>  		ret = pamu_config_ppaace(liodn, wnd_addr,
>  					 wnd->size,
> @@ -384,7 +389,7 @@ static void attach_device(struct fsl_dma_domain
> *dma_domain, int liodn, struct d  static phys_addr_t
> fsl_pamu_iova_to_phys(struct iommu_domain *domain,
>  					 dma_addr_t iova)
>  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
> 
>  	if (iova < domain->geometry.aperture_start ||
>  	    iova > domain->geometry.aperture_end) @@ -398,11 +403,9 @@
> static bool fsl_pamu_capable(enum iommu_cap cap)
>  	return cap == IOMMU_CAP_CACHE_COHERENCY;  }
> 
> -static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
> +static void fsl_pamu_domain_free(struct iommu_domain *domain)
>  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> -
> -	domain->priv = NULL;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
> 
>  	/* remove all the devices from the device list */
>  	detach_device(NULL, dma_domain);
> @@ -413,23 +416,24 @@ static void fsl_pamu_domain_destroy(struct
> iommu_domain *domain)
>  	kmem_cache_free(fsl_pamu_domain_cache, dma_domain);  }
> 
> -static int fsl_pamu_domain_init(struct iommu_domain *domain)
> +static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type)
>  {
>  	struct fsl_dma_domain *dma_domain;
> 
> +	if (type != IOMMU_DOMAIN_UNMANAGED)
> +		return NULL;
> +
>  	dma_domain = iommu_alloc_dma_domain();
>  	if (!dma_domain) {
>  		pr_debug("dma_domain allocation failed\n");
> -		return -ENOMEM;
> +		return NULL;
>  	}
> -	domain->priv = dma_domain;
> -	dma_domain->iommu_domain = domain;
>  	/* defaul geometry 64 GB i.e. maximum system address */
> -	domain->geometry.aperture_start = 0;
> -	domain->geometry.aperture_end = (1ULL << 36) - 1;
> -	domain->geometry.force_aperture = true;
> +	dma_domain->iommu_domain. geometry.aperture_start = 0;
> +	dma_domain->iommu_domain.geometry.aperture_end = (1ULL <<
> 36) - 1;
> +	dma_domain->iommu_domain.geometry.force_aperture = true;
> 
> -	return 0;
> +	return &dma_domain->iommu_domain;
>  }
> 
>  /* Configure geometry settings for all LIODNs associated with domain */
> @@ -499,7 +503,7 @@ static int disable_domain_win(struct fsl_dma_domain
> *dma_domain, u32 wnd_nr)
> 
>  static void fsl_pamu_window_disable(struct iommu_domain *domain, u32
> wnd_nr)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	unsigned long flags;
>  	int ret;
> 
> @@ -530,7 +534,7 @@ static void fsl_pamu_window_disable(struct
> iommu_domain *domain, u32 wnd_nr)  static int
> fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr,
>  				  phys_addr_t paddr, u64 size, int prot)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	struct dma_window *wnd;
>  	int pamu_prot = 0;
>  	int ret;
> @@ -607,7 +611,7 @@ static int handle_attach_device(struct
> fsl_dma_domain *dma_domain,
>  				int num)
>  {
>  	unsigned long flags;
> -	struct iommu_domain *domain = dma_domain->iommu_domain;
> +	struct iommu_domain *domain = &dma_domain->iommu_domain;
>  	int ret = 0;
>  	int i;
> 
> @@ -653,7 +657,7 @@ static int handle_attach_device(struct
> fsl_dma_domain *dma_domain,  static int fsl_pamu_attach_device(struct
> iommu_domain *domain,
>  				  struct device *dev)
>  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	const u32 *liodn;
>  	u32 liodn_cnt;
>  	int len, ret = 0;
> @@ -691,7 +695,7 @@ static int fsl_pamu_attach_device(struct
> iommu_domain *domain,  static void fsl_pamu_detach_device(struct
> iommu_domain *domain,
>  				   struct device *dev)
>  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	const u32 *prop;
>  	int len;
>  	struct pci_dev *pdev = NULL;
> @@ -723,7 +727,7 @@ static void fsl_pamu_detach_device(struct
> iommu_domain *domain,  static  int configure_domain_geometry(struct
> iommu_domain *domain, void *data)  {
>  	struct iommu_domain_geometry *geom_attr = data;
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	dma_addr_t geom_size;
>  	unsigned long flags;
> 
> @@ -813,7 +817,7 @@ static int configure_domain_dma_state(struct
> fsl_dma_domain *dma_domain, bool en  static int
> fsl_pamu_set_domain_attr(struct iommu_domain *domain,
>  				    enum iommu_attr attr_type, void *data)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	int ret = 0;
> 
>  	switch (attr_type) {
> @@ -838,7 +842,7 @@ static int fsl_pamu_set_domain_attr(struct
> iommu_domain *domain,  static int fsl_pamu_get_domain_attr(struct
> iommu_domain *domain,
>  				    enum iommu_attr attr_type, void *data)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	int ret = 0;
> 
>  	switch (attr_type) {
> @@ -999,7 +1003,7 @@ static void fsl_pamu_remove_device(struct device
> *dev)
> 
>  static int fsl_pamu_set_windows(struct iommu_domain *domain, u32
> w_count)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
>  	unsigned long flags;
>  	int ret;
> 
> @@ -1048,15 +1052,15 @@ static int fsl_pamu_set_windows(struct
> iommu_domain *domain, u32 w_count)
> 
>  static u32 fsl_pamu_get_windows(struct iommu_domain *domain)  {
> -	struct fsl_dma_domain *dma_domain = domain->priv;
> +	struct fsl_dma_domain *dma_domain =
> to_fsl_dma_domain(domain);
> 
>  	return dma_domain->win_cnt;
>  }
> 
>  static const struct iommu_ops fsl_pamu_ops = {
>  	.capable	= fsl_pamu_capable,
> -	.domain_init	= fsl_pamu_domain_init,
> -	.domain_destroy = fsl_pamu_domain_destroy,
> +	.domain_alloc	= fsl_pamu_domain_alloc,
> +	.domain_free    = fsl_pamu_domain_free,
>  	.attach_dev	= fsl_pamu_attach_device,
>  	.detach_dev	= fsl_pamu_detach_device,
>  	.domain_window_enable = fsl_pamu_window_enable, diff --git
> a/drivers/iommu/fsl_pamu_domain.h b/drivers/iommu/fsl_pamu_domain.h
> index c90293f..f2b0f74 100644
> --- a/drivers/iommu/fsl_pamu_domain.h
> +++ b/drivers/iommu/fsl_pamu_domain.h
> @@ -71,7 +71,7 @@ struct fsl_dma_domain {
>  	u32				stash_id;
>  	struct pamu_stash_attribute	dma_stash;
>  	u32				snoop_id;
> -	struct iommu_domain		*iommu_domain;
> +	struct iommu_domain		iommu_domain;
>  	spinlock_t			domain_lock;
>  };
Acked-by: Varun Sethi <varun.sethi@freescale.com>

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

end of thread, other threads:[~2015-04-12 15:00 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-26 12:43 [PATCH 00/16 v2] iommu: Move domain allocation into drivers Joerg Roedel
2015-03-26 12:43 ` [PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops Joerg Roedel
2015-03-26 12:43 ` [PATCH 02/16] iommu: Introduce iommu domain types Joerg Roedel
2015-03-26 12:52   ` Swapna Nannapaneni
2015-03-26 12:43 ` [PATCH 03/16] iommu: Only allow iommu_map/unmap for paging domains Joerg Roedel
2015-03-26 12:43 ` [PATCH 04/16] iommu/amd: Make use of domain_alloc and domain_free Joerg Roedel
2015-03-26 12:43 ` [PATCH 05/16] iommu/vt-d: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 06/16] iommu/omap: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 07/16] iommu/arm-smmu: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 08/16] iommu/exynos: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 09/16] iommu/tegra-smmu: " Joerg Roedel
2015-03-27 10:59   ` Thierry Reding
2015-03-26 12:43 ` [PATCH 10/16] iommu/tegra-gart: " Joerg Roedel
2015-03-27 11:00   ` Thierry Reding
2015-03-26 12:43 ` [PATCH 11/16] iommu/msm: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 12/16] iommu/shmobile: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 13/16] iommu/ipmmu-vmsa: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 14/16] iommu/rockchip: " Joerg Roedel
2015-03-26 12:43 ` [PATCH 15/16] iommu/fsl: " Joerg Roedel
2015-04-12 14:25   ` Varun Sethi
2015-03-26 12:43 ` [PATCH 16/16] iommu: Remove domain_init and domain_free iommu_ops Joerg Roedel
2015-03-27 11:03 ` [PATCH 00/16 v2] iommu: Move domain allocation into drivers Thierry Reding
2015-03-27 16:39 ` Heiko Stuebner
2015-03-28  4:24 ` Alex Williamson
2015-03-31 13:14   ` Joerg Roedel
2015-03-30 17:43 ` Will Deacon
2015-03-31 13:18   ` Joerg Roedel
2015-03-31 13:33 ` 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).