Re: [PATCH v5 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops

2016-10-19 Thread Magnus Damm
Hi Joerg,

On Thu, Sep 22, 2016 at 11:45 PM, Joerg Roedel  wrote:
> On Tue, Sep 20, 2016 at 10:44:46PM +0900, Magnus Damm wrote:
>> +#ifdef CONFIG_IOMMU_DMA
>> +
>> +static struct iommu_domain *ipmmu_domain_alloc_dma(unsigned type)
>> +{
>> + struct iommu_domain *io_domain;
>> +
>> + if (type != IOMMU_DOMAIN_DMA)
>> + return NULL;
>> +
>> + io_domain = __ipmmu_domain_alloc(type);
>> + if (io_domain)
>> + iommu_get_dma_cookie(io_domain);
>> +
>> + return io_domain;
>> +}
>> +
>> +static void ipmmu_domain_free_dma(struct iommu_domain *io_domain)
>> +{
>> + iommu_put_dma_cookie(io_domain);
>> + ipmmu_domain_free(io_domain);
>> +}
>
>> [...]
>
>> +static const struct iommu_ops ipmmu_ops = {
>> + .domain_alloc = ipmmu_domain_alloc_dma,
>> + .domain_free = ipmmu_domain_free_dma,
>
> Okay, so when CONFIG_IOMMU_DMA is enabled, you only support allocation
> of DMA domains, not UNMANAGED domains anymore. Is there a reason for
> that?

Just historical reason migrating from UNMANAGED only to DMA only.

> You can reduce the #ifdef'ed coded by supporting both types of domains
> and call into allocation-subfunctions for DMA and UNMANAGED domains. The
> #ifdef could then only let the dma-allocation function return NULL.
>
> This would be much more compatible to what other IOMMU drivers do and
> will allow VFIO usage in the future.

Thanks for your suggestion. I've now updated the code in V6, hopefully
it would match your expectation better.

Cheers,

/ magnus
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 07/07] iommu/ipmmu-vmsa: Drop LPAE Kconfig dependency

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Neither the ARM page table code enabled by IOMMU_IO_PGTABLE_LPAE
nor the IPMMU_VMSA driver actually depends on ARM_LPAE, so get
rid of the dependency.

Tested with ipmmu-vmsa on r8a7794 ALT and a kernel config using:
 # CONFIG_ARM_LPAE is not set

Signed-off-by: Magnus Damm 
Acked-by: Laurent Pinchart 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - Rebased patch to fit on top of earlier Kconfig changes in series

 Changes since V3:
 - None

 Changes since V2:
 - None

 Changes since V1:
 - Rebased on top of ARCH_RENESAS change
 - Added Acked-by from Laurent

 drivers/iommu/Kconfig |1 -
 1 file changed, 1 deletion(-)

--- 0008/drivers/iommu/Kconfig
+++ work/drivers/iommu/Kconfig  2016-09-20 22:13:03.500607110 +0900
@@ -275,7 +275,6 @@ config EXYNOS_IOMMU_DEBUG
 config IPMMU_VMSA
bool "Renesas VMSA-compatible IPMMU"
depends on ARM || IOMMU_DMA
-   depends on ARM_LPAE
depends on ARCH_RENESAS || COMPILE_TEST
select IOMMU_API
select IOMMU_IO_PGTABLE_LPAE
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 01/07] iommu/ipmmu-vmsa: Remove platform data handling

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

The IPMMU driver is using DT these days, and platform data is no longer
used by the driver. Remove unused code.

Signed-off-by: Magnus Damm 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - None

 Changes since V3:
 - None

 Changes since V2:
 - None

 Changes since V1:
 - Added Reviewed-by from Laurent

 drivers/iommu/ipmmu-vmsa.c |5 -
 1 file changed, 5 deletions(-)

--- 0002/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-09-20 21:46:26.0 +0900
@@ -766,11 +766,6 @@ static int ipmmu_probe(struct platform_d
int irq;
int ret;
 
-   if (!IS_ENABLED(CONFIG_OF) && !pdev->dev.platform_data) {
-   dev_err(>dev, "missing platform data\n");
-   return -EINVAL;
-   }
-
mmu = devm_kzalloc(>dev, sizeof(*mmu), GFP_KERNEL);
if (!mmu) {
dev_err(>dev, "cannot allocate device data\n");
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 04/07] iommu/ipmmu-vmsa: Break out domain allocation code

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Break out the domain allocation code into a separate function.
This is preparation for future code sharing.

Signed-off-by: Magnus Damm 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - None

 Changes since V3:
 - None

 Changes since V2:
 - Included this new patch as-is from the following series:
   [PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update

 drivers/iommu/ipmmu-vmsa.c |   13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

--- 0008/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-09-20 21:56:59.220607110 +0900
@@ -507,13 +507,10 @@ static irqreturn_t ipmmu_irq(int irq, vo
  * IOMMU Operations
  */
 
-static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
+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 NULL;
@@ -523,6 +520,14 @@ static struct iommu_domain *ipmmu_domain
return >io_domain;
 }
 
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
+{
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   return __ipmmu_domain_alloc(type);
+}
+
 static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Introduce an alternative set of iommu_ops suitable for 64-bit ARM
as well as 32-bit ARM when CONFIG_IOMMU_DMA=y. Also adjust the
Kconfig to depend on ARM or IOMMU_DMA.

Signed-off-by: Magnus Damm 
---

 Changes since V5:
 - Made domain allocation/free code more consistent - thanks Joerg!

 Changes since V4:
 - Added Kconfig hunk to depend on ARM or IOMMU_DMA

 Changes since V3:
 - Removed group parameter from ipmmu_init_platform_device()

 Changes since V2:
 - Included this new patch from the following series:
   [PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
 - Use only a single iommu_ops structure with #ifdef CONFIG_IOMMU_DMA
 - Folded in #ifdefs to handle CONFIG_ARM and CONFIG_IOMMU_DMA
 - of_xlate() is now used without #ifdefs
 - Made sure code compiles on both 32-bit and 64-bit ARM.

 drivers/iommu/Kconfig  |1 
 drivers/iommu/ipmmu-vmsa.c |  122 +---
 2 files changed, 115 insertions(+), 8 deletions(-)

--- 0001/drivers/iommu/Kconfig
+++ work/drivers/iommu/Kconfig  2016-10-20 08:16:40.980607110 +0900
@@ -274,6 +274,7 @@ config EXYNOS_IOMMU_DEBUG
 
 config IPMMU_VMSA
bool "Renesas VMSA-compatible IPMMU"
+   depends on ARM || IOMMU_DMA
depends on ARM_LPAE
depends on ARCH_RENESAS || COMPILE_TEST
select IOMMU_API
--- 0006/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-10-20 08:16:48.440607110 +0900
@@ -10,6 +10,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -22,8 +23,10 @@
 #include 
 #include 
 
+#if defined(CONFIG_ARM) && !defined(CONFIG_IOMMU_DMA)
 #include 
 #include 
+#endif
 
 #include "io-pgtable.h"
 
@@ -520,14 +523,6 @@ static struct iommu_domain *__ipmmu_doma
return >io_domain;
 }
 
-static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
-{
-   if (type != IOMMU_DOMAIN_UNMANAGED)
-   return NULL;
-
-   return __ipmmu_domain_alloc(type);
-}
-
 static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
@@ -714,6 +709,8 @@ error:
return ret;
 }
 
+#if defined(CONFIG_ARM) && !defined(CONFIG_IOMMU_DMA)
+
 static int ipmmu_add_device(struct device *dev)
 {
struct ipmmu_vmsa_archdata *archdata;
@@ -807,6 +804,14 @@ static void ipmmu_remove_device(struct d
dev->archdata.iommu = NULL;
 }
 
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
+{
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   return __ipmmu_domain_alloc(type);
+}
+
 static const struct iommu_ops ipmmu_ops = {
.domain_alloc = ipmmu_domain_alloc,
.domain_free = ipmmu_domain_free,
@@ -821,6 +826,105 @@ static const struct iommu_ops ipmmu_ops
.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 };
 
+#endif /* !CONFIG_ARM && CONFIG_IOMMU_DMA */
+
+#ifdef CONFIG_IOMMU_DMA
+
+static struct iommu_domain *ipmmu_domain_alloc_dma(unsigned type)
+{
+   struct iommu_domain *io_domain = NULL;
+
+   switch (type) {
+   case IOMMU_DOMAIN_UNMANAGED:
+   io_domain = __ipmmu_domain_alloc(type);
+   break;
+
+   case IOMMU_DOMAIN_DMA:
+   io_domain = __ipmmu_domain_alloc(type);
+   if (io_domain)
+   iommu_get_dma_cookie(io_domain);
+   break;
+   }
+
+   return io_domain;
+}
+
+static void ipmmu_domain_free_dma(struct iommu_domain *io_domain)
+{
+   switch (io_domain->type) {
+   case IOMMU_DOMAIN_DMA:
+   iommu_put_dma_cookie(io_domain);
+   /* fall-through */
+   default:
+   ipmmu_domain_free(io_domain);
+   break;
+   }
+}
+
+static int ipmmu_add_device_dma(struct device *dev)
+{
+   struct iommu_group *group;
+
+   /* only accept devices with iommus property */
+   if (of_count_phandle_with_args(dev->of_node, "iommus",
+  "#iommu-cells") < 0)
+   return -ENODEV;
+
+   group = iommu_group_get_for_dev(dev);
+   if (IS_ERR(group))
+   return PTR_ERR(group);
+
+   return 0;
+}
+
+static void ipmmu_remove_device_dma(struct device *dev)
+{
+   iommu_group_remove_device(dev);
+}
+
+static struct iommu_group *ipmmu_device_group_dma(struct device *dev)
+{
+   struct iommu_group *group;
+   int ret;
+
+   group = generic_device_group(dev);
+   if (IS_ERR(group))
+   return group;
+
+   ret = ipmmu_init_platform_device(dev);
+   if (ret) {
+   iommu_group_put(group);
+   group = ERR_PTR(ret);
+   }
+
+   return group;
+}
+
+static int ipmmu_of_xlate_dma(struct device *dev,
+ struct of_phandle_args *spec)
+{
+   /* dummy callback to satisfy of_iommu_configure() */
+   return 0;
+}
+
+static const 

[PATCH v6 06/07] iommu/ipmmu-vmsa: ARM and ARM64 archdata access

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Not all architectures have an iommu member in their archdata, so
use #ifdefs support build wit COMPILE_TEST on any architecture.

Signed-off-by: Magnus Damm 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - None

 Changes since V3:
 - New patch

 drivers/iommu/ipmmu-vmsa.c |   37 +++--
 1 file changed, 27 insertions(+), 10 deletions(-)

--- 0012/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-09-20 21:59:21.690607110 +0900
@@ -70,6 +70,25 @@ static struct ipmmu_vmsa_domain *to_vmsa
return container_of(dom, struct ipmmu_vmsa_domain, io_domain);
 }
 
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+static struct ipmmu_vmsa_archdata *to_archdata(struct device *dev)
+{
+   return dev->archdata.iommu;
+}
+static void set_archdata(struct device *dev, struct ipmmu_vmsa_archdata *p)
+{
+   dev->archdata.iommu = p;
+}
+#else
+static struct ipmmu_vmsa_archdata *to_archdata(struct device *dev)
+{
+   return NULL;
+}
+static void set_archdata(struct device *dev, struct ipmmu_vmsa_archdata *p)
+{
+}
+#endif
+
 #define TLB_LOOP_TIMEOUT   100 /* 100us */
 
 /* 
-
@@ -539,7 +558,7 @@ static void ipmmu_domain_free(struct iom
 static int ipmmu_attach_device(struct iommu_domain *io_domain,
   struct device *dev)
 {
-   struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
+   struct ipmmu_vmsa_archdata *archdata = to_archdata(dev);
struct ipmmu_vmsa_device *mmu = archdata->mmu;
struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
unsigned long flags;
@@ -581,7 +600,7 @@ static int ipmmu_attach_device(struct io
 static void ipmmu_detach_device(struct iommu_domain *io_domain,
struct device *dev)
 {
-   struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
+   struct ipmmu_vmsa_archdata *archdata = to_archdata(dev);
struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
unsigned int i;
 
@@ -701,7 +720,7 @@ static int ipmmu_init_platform_device(st
archdata->mmu = mmu;
archdata->utlbs = utlbs;
archdata->num_utlbs = num_utlbs;
-   dev->archdata.iommu = archdata;
+   set_archdata(dev, archdata);
return 0;
 
 error:
@@ -713,12 +732,11 @@ error:
 
 static int ipmmu_add_device(struct device *dev)
 {
-   struct ipmmu_vmsa_archdata *archdata;
struct ipmmu_vmsa_device *mmu = NULL;
struct iommu_group *group;
int ret;
 
-   if (dev->archdata.iommu) {
+   if (to_archdata(dev)) {
dev_warn(dev, "IOMMU driver already assigned to device %s\n",
 dev_name(dev));
return -EINVAL;
@@ -754,8 +772,7 @@ static int ipmmu_add_device(struct devic
 * - Make the mapping size configurable ? We currently use a 2GB mapping
 *   at a 1GB offset to ensure that NULL VAs will fault.
 */
-   archdata = dev->archdata.iommu;
-   mmu = archdata->mmu;
+   mmu = to_archdata(dev)->mmu;
if (!mmu->mapping) {
struct dma_iommu_mapping *mapping;
 
@@ -783,7 +800,7 @@ error:
if (mmu)
arm_iommu_release_mapping(mmu->mapping);
 
-   dev->archdata.iommu = NULL;
+   set_archdata(dev, NULL);
 
if (!IS_ERR_OR_NULL(group))
iommu_group_remove_device(dev);
@@ -793,7 +810,7 @@ error:
 
 static void ipmmu_remove_device(struct device *dev)
 {
-   struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
+   struct ipmmu_vmsa_archdata *archdata = to_archdata(dev);
 
arm_iommu_detach_device(dev);
iommu_group_remove_device(dev);
@@ -801,7 +818,7 @@ static void ipmmu_remove_device(struct d
kfree(archdata->utlbs);
kfree(archdata);
 
-   dev->archdata.iommu = NULL;
+   set_archdata(dev, NULL);
 }
 
 static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 02/07] iommu/ipmmu-vmsa: Rework interrupt code and use bitmap for context

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Introduce a bitmap for context handing and convert the
interrupt routine to handle all registered contexts.

At this point the number of contexts are still limited.

Also remove the use of the ARM specific mapping variable
from ipmmu_irq() to allow compile on ARM64.

Signed-off-by: Magnus Damm 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - None

 Changes since V3:
 - None

 Changes since V2: (Thanks again to Laurent!)
 - Introduce a spinlock together with the bitmap and domain array.
 - Break out code into separate functions for alloc and free.
 - Perform free after (instead of before) configuring hardware registers.
 - Use the spinlock to protect the domain array in the interrupt handler.

 Changes since V1: (Thanks to Laurent for feedback!)
 - Use simple find_first_zero()/set_bit()/clear_bit() for context management.
 - For allocation rely on spinlock held when calling ipmmu_domain_init_context()
 - For test/free use atomic bitops
 - Return IRQ_HANDLED if any of the contexts generated interrupts

 drivers/iommu/ipmmu-vmsa.c |   76 ++--
 1 file changed, 66 insertions(+), 10 deletions(-)

--- 0004/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-09-20 21:48:23.770607110 +0900
@@ -8,6 +8,7 @@
  * the Free Software Foundation; version 2 of the License.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -26,12 +27,17 @@
 
 #include "io-pgtable.h"
 
+#define IPMMU_CTX_MAX 1
+
 struct ipmmu_vmsa_device {
struct device *dev;
void __iomem *base;
struct list_head list;
 
unsigned int num_utlbs;
+   spinlock_t lock;/* Protects ctx and domains[] */
+   DECLARE_BITMAP(ctx, IPMMU_CTX_MAX);
+   struct ipmmu_vmsa_domain *domains[IPMMU_CTX_MAX];
 
struct dma_iommu_mapping *mapping;
 };
@@ -293,9 +299,29 @@ static struct iommu_gather_ops ipmmu_gat
  * Domain/Context Management
  */
 
+static int ipmmu_domain_allocate_context(struct ipmmu_vmsa_device *mmu,
+struct ipmmu_vmsa_domain *domain)
+{
+   unsigned long flags;
+   int ret;
+
+   spin_lock_irqsave(>lock, flags);
+
+   ret = find_first_zero_bit(mmu->ctx, IPMMU_CTX_MAX);
+   if (ret != IPMMU_CTX_MAX) {
+   mmu->domains[ret] = domain;
+   set_bit(ret, mmu->ctx);
+   }
+
+   spin_unlock_irqrestore(>lock, flags);
+
+   return ret;
+}
+
 static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
 {
u64 ttbr;
+   int ret;
 
/*
 * Allocate the page table operations.
@@ -325,10 +351,15 @@ static int ipmmu_domain_init_context(str
return -EINVAL;
 
/*
-* TODO: When adding support for multiple contexts, find an unused
-* context.
+* Find an unused context.
 */
-   domain->context_id = 0;
+   ret = ipmmu_domain_allocate_context(domain->mmu, domain);
+   if (ret == IPMMU_CTX_MAX) {
+   free_io_pgtable_ops(domain->iop);
+   return -EBUSY;
+   }
+
+   domain->context_id = ret;
 
/* TTBR0 */
ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr[0];
@@ -370,6 +401,19 @@ static int ipmmu_domain_init_context(str
return 0;
 }
 
+static void ipmmu_domain_free_context(struct ipmmu_vmsa_device *mmu,
+ unsigned int context_id)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+
+   clear_bit(context_id, mmu->ctx);
+   mmu->domains[context_id] = NULL;
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
 static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain)
 {
/*
@@ -380,6 +424,7 @@ static void ipmmu_domain_destroy_context
 */
ipmmu_ctx_write(domain, IMCTR, IMCTR_FLUSH);
ipmmu_tlb_sync(domain);
+   ipmmu_domain_free_context(domain->mmu, domain->context_id);
 }
 
 /* 
-
@@ -437,16 +482,25 @@ static irqreturn_t ipmmu_domain_irq(stru
 static irqreturn_t ipmmu_irq(int irq, void *dev)
 {
struct ipmmu_vmsa_device *mmu = dev;
-   struct iommu_domain *io_domain;
-   struct ipmmu_vmsa_domain *domain;
+   irqreturn_t status = IRQ_NONE;
+   unsigned int i;
+   unsigned long flags;
 
-   if (!mmu->mapping)
-   return IRQ_NONE;
+   spin_lock_irqsave(>lock, flags);
+
+   /*
+* Check interrupts for all active contexts.
+*/
+   for (i = 0; i < IPMMU_CTX_MAX; i++) {
+   if (!mmu->domains[i])
+   continue;
+   if (ipmmu_domain_irq(mmu->domains[i]) == IRQ_HANDLED)
+   status = IRQ_HANDLED;
+   }
 
-   io_domain = mmu->mapping->domain;
-   domain = 

[PATCH v6 03/07] iommu/ipmmu-vmsa: Break out utlb parsing code

2016-10-19 Thread Magnus Damm
From: Magnus Damm 

Break out the utlb parsing code and dev_data allocation into a
separate function. This is preparation for future code sharing.

Signed-off-by: Magnus Damm 
Reviewed-by: Joerg Roedel 
---

 Changes since V5:
 - None

 Changes since V4:
 - Dropped hunk with fix to apply on top of:
   b1e2afc iommu/ipmmu-vmsa: Fix wrong error handle of ipmmu_add_device
 
 Changes since V3:
 - Initialize "mmu" to NULL, check before accessing
 - Removed group parameter from ipmmu_init_platform_device()

 Changes since V2:
 - Included this new patch from the following series:
   [PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
 - Reworked code to fit on top on previous two patches in current series.

 drivers/iommu/ipmmu-vmsa.c |   58 
 1 file changed, 37 insertions(+), 21 deletions(-)

--- 0006/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c 2016-09-20 21:49:34.580607110 +0900
@@ -647,22 +647,15 @@ static int ipmmu_find_utlbs(struct ipmmu
return 0;
 }
 
-static int ipmmu_add_device(struct device *dev)
+static int ipmmu_init_platform_device(struct device *dev)
 {
struct ipmmu_vmsa_archdata *archdata;
struct ipmmu_vmsa_device *mmu;
-   struct iommu_group *group = NULL;
unsigned int *utlbs;
unsigned int i;
int num_utlbs;
int ret = -ENODEV;
 
-   if (dev->archdata.iommu) {
-   dev_warn(dev, "IOMMU driver already assigned to device %s\n",
-dev_name(dev));
-   return -EINVAL;
-   }
-
/* Find the master corresponding to the device. */
 
num_utlbs = of_count_phandle_with_args(dev->of_node, "iommus",
@@ -699,6 +692,36 @@ static int ipmmu_add_device(struct devic
}
}
 
+   archdata = kzalloc(sizeof(*archdata), GFP_KERNEL);
+   if (!archdata) {
+   ret = -ENOMEM;
+   goto error;
+   }
+
+   archdata->mmu = mmu;
+   archdata->utlbs = utlbs;
+   archdata->num_utlbs = num_utlbs;
+   dev->archdata.iommu = archdata;
+   return 0;
+
+error:
+   kfree(utlbs);
+   return ret;
+}
+
+static int ipmmu_add_device(struct device *dev)
+{
+   struct ipmmu_vmsa_archdata *archdata;
+   struct ipmmu_vmsa_device *mmu = NULL;
+   struct iommu_group *group;
+   int ret;
+
+   if (dev->archdata.iommu) {
+   dev_warn(dev, "IOMMU driver already assigned to device %s\n",
+dev_name(dev));
+   return -EINVAL;
+   }
+
/* Create a device group and add the device to it. */
group = iommu_group_alloc();
if (IS_ERR(group)) {
@@ -716,16 +739,9 @@ static int ipmmu_add_device(struct devic
goto error;
}
 
-   archdata = kzalloc(sizeof(*archdata), GFP_KERNEL);
-   if (!archdata) {
-   ret = -ENOMEM;
+   ret = ipmmu_init_platform_device(dev);
+   if (ret < 0)
goto error;
-   }
-
-   archdata->mmu = mmu;
-   archdata->utlbs = utlbs;
-   archdata->num_utlbs = num_utlbs;
-   dev->archdata.iommu = archdata;
 
/*
 * Create the ARM mapping, used by the ARM DMA mapping core to allocate
@@ -736,6 +752,8 @@ static int ipmmu_add_device(struct devic
 * - Make the mapping size configurable ? We currently use a 2GB mapping
 *   at a 1GB offset to ensure that NULL VAs will fault.
 */
+   archdata = dev->archdata.iommu;
+   mmu = archdata->mmu;
if (!mmu->mapping) {
struct dma_iommu_mapping *mapping;
 
@@ -760,10 +778,8 @@ static int ipmmu_add_device(struct devic
return 0;
 
 error:
-   arm_iommu_release_mapping(mmu->mapping);
-
-   kfree(dev->archdata.iommu);
-   kfree(utlbs);
+   if (mmu)
+   arm_iommu_release_mapping(mmu->mapping);
 
dev->archdata.iommu = NULL;
 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 00/07] iommu/ipmmu-vmsa: IPMMU multi-arch update V6

2016-10-19 Thread Magnus Damm
iommu/ipmmu-vmsa: IPMMU multi-arch update V6

[PATCH v6 01/07] iommu/ipmmu-vmsa: Remove platform data handling
[PATCH v6 02/07] iommu/ipmmu-vmsa: Rework interrupt code and use bitmap for 
context
[PATCH v6 03/07] iommu/ipmmu-vmsa: Break out utlb parsing code
[PATCH v6 04/07] iommu/ipmmu-vmsa: Break out domain allocation code
[PATCH v6 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops
[PATCH v6 06/07] iommu/ipmmu-vmsa: ARM and ARM64 archdata access
[PATCH v6 07/07] iommu/ipmmu-vmsa: Drop LPAE Kconfig dependency

These patches update the IPMMU driver with a couple of changes
to support build on multiple architectures. In the process of
doing so the interrupt code gets reworked and the foundation
for supporting multiple contexts are added.

Changes since V5:
 - Rebased series on top of next-20161019
 - Updated patch 5/7 to simplify domain allocation/free code - thanks Joerg!
 - Added reviewed-by tag from Joerg for patch 1-4 and 6-7.
 
Changes since V4:
 - Updated patch 3/7 to work on top on the following commit in next-20160920:
   b1e2afc iommu/ipmmu-vmsa: Fix wrong error handle of ipmmu_add_device
 - Add Kconfig hunk to patch 5/7 to avoid undeclared ipmmu_ops if COMPILE_TEST
 - Rebased patch 7/7 to fit on top of new Kconfig bits in 5/7

Changes since V3:
 - Updated patch 3/7 to fix hang-on-boot issue on 32-bit ARM - thanks Geert!
 - Reworked group parameter handling in patch 3/7 and 5/7.
 - Added patch 6/7 to fix build of the driver on s390/tile/um architectures

Changes since V2:
 - Got rid of patch 3 from the V2 however patch 1, 2 and 4 are kept.
 - V3 patch 3, 4 and 5 come from
   [PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
 - Patch 5 has been reworked to include patch 3 of the V1 of this series 

Changes since V1:
 - Got rid of patch 2 and 3 from initial series
 - Updated bitmap code locking and also used lighter bitop functions
 - Updated the Kconfig bits to apply on top of ARCH_RENESAS

Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
---

 Built on top next-20161019:

 drivers/iommu/Kconfig  |2 
 drivers/iommu/ipmmu-vmsa.c |  311 +++-
 2 files changed, 254 insertions(+), 59 deletions(-)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu/dma: Implement dma_{map,unmap}_resource()

2016-10-19 Thread Will Deacon
On Mon, Oct 17, 2016 at 01:05:29PM +0100, Robin Murphy wrote:
> With the new dma_{map,unmap}_resource() functions added to the DMA API
> for the benefit of cases like slave DMA, add suitable implementations to
> the arsenal of our generic layer. Since cache maintenance should not be
> a concern, these can both be standalone versions without the need for
> architecture-specific wrappers.
> 
> CC: Joerg Roedel 
> Signed-off-by: Robin Murphy 
> ---
> 
> Since patch 2 has a build dependency on this one, they should probably
> go together through either the arm64 tree or the iommu tree, but I can't
> make up my mind which one seems more appropriate...

I can take it via the smmu tree, if you like. However, comment below.

>  drivers/iommu/dma-iommu.c | 13 +
>  include/linux/dma-iommu.h |  4 
>  2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index c5ab8667e6f2..50acd71915db 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -624,6 +624,19 @@ void iommu_dma_unmap_sg(struct device *dev, struct 
> scatterlist *sg, int nents,
>   __iommu_dma_unmap(iommu_get_domain_for_dev(dev), sg_dma_address(sg));
>  }
>  
> +dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys,
> + size_t size, enum dma_data_direction dir, unsigned long attrs)
> +{
> + return iommu_dma_map_page(dev, phys_to_page(phys), offset_in_page(phys),
> + size, dma_direction_to_prot(dir, false) | IOMMU_MMIO);
> +}
>
> +void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle,
> + size_t size, enum dma_data_direction dir, unsigned long attrs)
> +{
> + __iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
> +}

I think it's better to call iommu_dma_unmap_page instead. That said, are
you sure it's safe to ignore the "size" parameter here? Is it permitted
to unmap part of a region? If not, why does that parameter exist?

Will
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu/arm-smmu: Don't inadvertently reject multiple SMMUv3s

2016-10-19 Thread Will Deacon
On Mon, Oct 17, 2016 at 12:06:20PM +0100, Robin Murphy wrote:
> We now delay installing our per-bus iommu_ops until we know an SMMU has
> successfully probed, as they don't serve much purpose beforehand, and
> doing so also avoids fights between multiple IOMMU drivers in a single
> kernel. However, the upshot of passing the return value of bus_set_iommu()
> back from our probe function is that if there happens to be more than
> one SMMUv3 device in a system, the second and subsequent probes will
> wind up returning -EBUSY to the driver core and getting torn down again.
> 
> There are essentially 3 cases in which bus_set_iommu() returns nonzero:
> 1. The bus already has iommu_ops installed
> 2. One of the add_device callbacks from the initial notifier failed
> 3. Allocating or installing the notifier itself failed
> 
> The first two are down to devices other than the SMMU in question, so
> shouldn't abort an otherwise-successful SMMU probe, whilst the third is
> indicative of the kind of catastrophic system failure which isn't going
> to get much further anyway. Consequently, there is little harm in
> ignoring the return value either way.
> 
> CC: Lorenzo Pieralisi 
> Signed-off-by: Robin Murphy 
> ---
>  drivers/iommu/arm-smmu-v3.c | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 15c01c3cd540..74fbef384deb 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2637,16 +2637,13 @@ static int arm_smmu_device_dt_probe(struct 
> platform_device *pdev)
>   of_iommu_set_ops(dev->of_node, _smmu_ops);
>  #ifdef CONFIG_PCI
>   pci_request_acs();
> - ret = bus_set_iommu(_bus_type, _smmu_ops);
> - if (ret)
> - return ret;
> + bus_set_iommu(_bus_type, _smmu_ops);
>  #endif
>  #ifdef CONFIG_ARM_AMBA
> - ret = bus_set_iommu(_bustype, _smmu_ops);
> - if (ret)
> - return ret;
> + bus_set_iommu(_bustype, _smmu_ops);
>  #endif
> - return bus_set_iommu(_bus_type, _smmu_ops);
> + bus_set_iommu(_bus_type, _smmu_ops);
> + return 0;

In which case, we should probably add an iommu_present check, like we
have for the v2 driver.

Will
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu: convert DT component matching to component_match_add_release()

2016-10-19 Thread Russell King
Convert DT component matching to use component_match_add_release().

Signed-off-by: Russell King 
---
 drivers/iommu/mtk_iommu.c| 8 +---
 drivers/iommu/mtk_iommu.h| 5 +
 drivers/iommu/mtk_iommu_v1.c | 8 +---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b12c12d74c33..41604796fca3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -583,17 +583,19 @@ static int mtk_iommu_probe(struct platform_device *pdev)
continue;
 
plarbdev = of_find_device_by_node(larbnode);
-   of_node_put(larbnode);
if (!plarbdev) {
plarbdev = of_platform_device_create(
larbnode, NULL,
platform_bus_type.dev_root);
-   if (!plarbdev)
+   if (!plarbdev) {
+   of_node_put(larbnode);
return -EPROBE_DEFER;
+   }
}
data->smi_imu.larb_imu[i].dev = >dev;
 
-   component_match_add(dev, , compare_of, larbnode);
+   component_match_add_release(dev, , release_of,
+   compare_of, larbnode);
}
 
platform_set_drvdata(pdev, data);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 3dab13b4a211..44ca38095c6a 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -60,6 +60,11 @@ static inline int compare_of(struct device *dev, void *data)
return dev->of_node == data;
 }
 
+static inline void release_of(struct device *dev, void *data)
+{
+   of_node_put(data);
+}
+
 static inline int mtk_iommu_bind(struct device *dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index b8aeb0768483..92341ef33354 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -624,17 +624,19 @@ static int mtk_iommu_probe(struct platform_device *pdev)
continue;
 
plarbdev = of_find_device_by_node(larb_spec.np);
-   of_node_put(larb_spec.np);
if (!plarbdev) {
plarbdev = of_platform_device_create(
larb_spec.np, NULL,
platform_bus_type.dev_root);
-   if (!plarbdev)
+   if (!plarbdev) {
+   of_node_put(larb_spec.np);
return -EPROBE_DEFER;
+   }
}
 
data->smi_imu.larb_imu[larb_nr].dev = >dev;
-   component_match_add(dev, , compare_of, larb_spec.np);
+   component_match_add_release(dev, , release_of,
+   compare_of, larb_spec.np);
larb_nr++;
}
 
-- 
2.1.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [v12, 0/8] Fix eSDHC host version register bug

2016-10-19 Thread gre...@linuxfoundation.org
On Wed, Oct 19, 2016 at 02:47:07AM +, Y.B. Lu wrote:
> + Greg
> 
> Hi Greg,
> 
> I submitted this patchset for a MMC bug fix, and introduce the below patch 
> which needs your ACK.
> > > Arnd Bergmann (1):
> > >   base: soc: introduce soc_device_match() interface
> https://patchwork.kernel.org/patch/9342913/
> 
> Could you help to review it and give some comments or ACK.
> Thank you very much.

Now acked.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/2] iommu/mediatek: Convert M4Uv1 to iommu_fwspec

2016-10-19 Thread Honghui Zhang
On Mon, 2016-10-17 at 12:49 +0100, Robin Murphy wrote:
> Our per-device data consists of the M4U instance and firmware-provided
> list of LARB IDs, which is a perfect fit for the generic iommu_fwspec
> machinery. Use that directly instead of the custom archdata code - while
> we can't rely on the of_xlate() mechanism to initialise things until the
> 32-bit ARM DMA code learns about groups and default domains, it still
> results in a reasonable simplification overall.
> 
> CC: Honghui Zhang 
> Signed-off-by: Robin Murphy 

Thanks Robin.
Tested-by: Honghui Zhang 

> ---
>  drivers/iommu/mtk_iommu.h|  6 ---
>  drivers/iommu/mtk_iommu_v1.c | 95 
> +---
>  2 files changed, 36 insertions(+), 65 deletions(-)
> 


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu