Re: [PATCH v5 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops
Hi Joerg, On Thu, Sep 22, 2016 at 11:45 PM, Joerg Roedelwrote: > 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
From: Magnus DammNeither 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
From: Magnus DammThe 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
From: Magnus DammBreak 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
From: Magnus DammIntroduce 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
From: Magnus DammNot 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
From: Magnus DammIntroduce 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
From: Magnus DammBreak 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
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()
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
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()
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
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
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