Kill off pgsize_bitmap field from struct iommu_ops
Subsystems (13)
cover Kill off pgsize_bitmap field from struct iommu_ops
Hi all,
These patches move the pgsize_bitmap field out of iommu_ops and into the iommu_domain structure, as there are systems containing multiple instances of a given IOMMU (e.g. the ARM SMMU) with different page size support on the individual devices.
Once that's done, we can get back to treating the iommu_ops as constant, since they just contain function pointers.
Comments welcome,
Will
--->8
Robin Murphy (1):
iommu: of: enforce const-ness of struct iommu_ops
Will Deacon (1):
iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
arch/arm/include/asm/dma-mapping.h | 2 +- arch/arm/mm/dma-mapping.c | 6 +++--- arch/arm64/include/asm/dma-mapping.h | 3 ++- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/of_iommu.c | 12 ++++++------ drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/of/platform.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/dma-mapping.h | 2 +- include/linux/iommu.h | 6 +----- include/linux/of_iommu.h | 8 ++++---- 21 files changed, 46 insertions(+), 49 deletions(-)
Signature · 1 line
2.1.4
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
struct iommu_ops contains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned long pgsize_bitmap field, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.
This patch moves the field from iommu_ops into the iommu_domain and updates all users accordingly.
--- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/iommu.h | 6 +----- 14 files changed, 28 insertions(+), 32 deletions(-)
drivers/iommu/amd_iommu.c +1 -1
@@ -3257,6 +3257,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) dom->geometry.aperture_end = ~0ULL ; dom->geometry.force_aperture = true; + dom->pgsize_bitmap =AMD_IOMMU_PGSIZES ;return 0 ; out_free:
@@ -3428,7 +3429,6 @@ static const struct iommu_ops amd_iommu_ops = { .unmap = amd_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = amd_iommu_iova_to_phys, - .pgsize_bitmap = AMD_IOMMU_PGSIZES, };/*****************************************************************************
drivers/iommu/arm-smmu.c +5 -7
@@ -287,6 +287,7 @@ struct arm_smmu_device {void __iomem *base;unsigned long size;unsigned long pgshift; +unsigned long pgsize_bitmap;#define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0)#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)
@@ -345,8 +346,6 @@ struct arm_smmu_domain {struct mutex init_mutex;/* Protects smmu pointer */ }; -static struct iommu_ops arm_smmu_ops; -static DEFINE_SPINLOCK (arm_smmu_devices_lock);static LIST_HEAD (arm_smmu_devices);
@@ -911,7 +910,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, } pgtbl_cfg = (struct io_pgtable_cfg ) { - .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, + .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, .oas = oas, .tlb = &arm_smmu_gather_ops,
@@ -925,7 +924,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, }/* Update our support page sizes to reflect the page table format */ - arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;/* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank (smmu_domain, &pgtbl_cfg);
@@ -1430,7 +1429,7 @@ out_unlock:return ret; } -static struct iommu_ops arm_smmu_ops = { +static const struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_init = arm_smmu_domain_init, .domain_destroy = arm_smmu_domain_destroy,
@@ -1444,7 +1443,6 @@ static struct iommu_ops arm_smmu_ops = { .remove_device = arm_smmu_remove_device, .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, - .pgsize_bitmap = -1UL, /* Restricted during device attach */ };static void arm_smmu_device_reset (struct arm_smmu_device *smmu)
@@ -1648,7 +1646,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) size |=SZ_64K |SZ_512M ; } - arm_smmu_ops.pgsize_bitmap &= size; + smmu->pgsize_bitmap = size;dev_notice (smmu->dev,"\tSupported page sizes: 0x%08lx\n" , size);if (smmu->features &ARM_SMMU_FEAT_TRANS_S1 )
drivers/iommu/exynos-iommu.c +2 -1
@@ -735,6 +735,8 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = ~0UL ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =SECT_SIZE |LPAGE_SIZE |SPAGE_SIZE ; + domain->priv = priv;return 0 ;
@@ -1181,7 +1183,6 @@ static const struct iommu_ops exynos_iommu_ops = { .iova_to_phys = exynos_iommu_iova_to_phys, .add_device = exynos_iommu_add_device, .remove_device = exynos_iommu_remove_device, - .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE, };static int __init exynos_iommu_init (void )
drivers/iommu/intel-iommu.c +1 -1
@@ -4363,6 +4363,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end =__DOMAIN_MAX_ADDR (dmar_domain->gaw); domain->geometry.force_aperture = true; + domain->pgsize_bitmap =INTEL_IOMMU_PGSIZES ;return 0 ; }
@@ -4605,7 +4606,6 @@ static const struct iommu_ops intel_iommu_ops = { .iova_to_phys = intel_iommu_iova_to_phys, .add_device = intel_iommu_add_device, .remove_device = intel_iommu_remove_device, - .pgsize_bitmap = INTEL_IOMMU_PGSIZES, };static void quirk_iommu_g4x_gfx (struct pci_dev *dev)
drivers/iommu/iommu.c +8 -8
@@ -1025,7 +1025,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, pgsize = (1UL << (pgsize_idx +1 )) -1 ;/* throw away page sizes not supported by the hardware */ - pgsize &= domain->ops->pgsize_bitmap; + pgsize &= domain->pgsize_bitmap;/* make sure we're still sane */ BUG_ON (!pgsize);
@@ -1046,11 +1046,11 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,int ret =0 ;if (unlikely (domain->ops->map ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * both the virtual address and the physical one, as well as
@@ -1097,11 +1097,11 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)unsigned long orig_iova = iova;if (unlikely (domain->ops->unmap ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * The virtual address, as well as the size of the mapping, must be
@@ -1147,10 +1147,10 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,unsigned int i, min_pagesz;int ret; -if (unlikely (domain->ops->pgsize_bitmap ==0UL )) +if (unlikely (domain->pgsize_bitmap ==0UL ))return 0 ; - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);for_each_sg (sg, s, nents, i) {phys_addr_t phys =page_to_phys (sg_page (s)) + s->offset;
@@ -1231,7 +1231,7 @@ int iommu_domain_get_attr(struct iommu_domain *domain,break ;case DOMAIN_ATTR_PAGING : paging = data; - *paging = (domain->ops->pgsize_bitmap !=0UL ); + *paging = (domain->pgsize_bitmap !=0UL );break ;case DOMAIN_ATTR_WINDOWS : count = data;
drivers/iommu/ipmmu-vmsa.c +1 -1
@@ -469,6 +469,7 @@ static int ipmmu_domain_init(struct iommu_domain *io_domain) io_domain->priv = domain; domain->io_domain = io_domain; + domain->pgsize_bitmap =SZ_2M |SZ_64K |SZ_4K ;return 0 ; }
@@ -747,7 +748,6 @@ static const struct iommu_ops ipmmu_ops = { .iova_to_phys = ipmmu_iova_to_phys, .add_device = ipmmu_add_device, .remove_device = ipmmu_remove_device, - .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K, };/* -----------------------------------------------------------------------------
drivers/iommu/msm_iommu.c +2 -1
@@ -230,6 +230,8 @@ static int msm_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL <<32 ) -1 ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =MSM_IOMMU_PGSIZES ; +return 0 ; fail_nomem:
@@ -682,7 +684,6 @@ static const struct iommu_ops msm_iommu_ops = { .unmap = msm_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = msm_iommu_iova_to_phys, - .pgsize_bitmap = MSM_IOMMU_PGSIZES, };static int __init get_tex_class (int icp,int ocp,int mt,int nos)
drivers/iommu/omap-iommu.c +2 -1
@@ -1250,6 +1250,8 @@ static int omap_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL <<32 ) -1 ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =OMAP_IOMMU_PGSIZES ; +return 0 ; fail_nomem:
@@ -1368,7 +1370,6 @@ static const struct iommu_ops omap_iommu_ops = { .iova_to_phys = omap_iommu_iova_to_phys, .add_device = omap_iommu_add_device, .remove_device = omap_iommu_remove_device, - .pgsize_bitmap = OMAP_IOMMU_PGSIZES, };static int __init omap_iommu_init (void )
drivers/iommu/rockchip-iommu.c +1 -1
@@ -828,6 +828,7 @@ static int rk_iommu_domain_init(struct iommu_domain *domain)INIT_LIST_HEAD (&rk_domain->iommus); domain->priv = rk_domain; + domain->pgsize_bitmap =RK_IOMMU_PGSIZE_BITMAP ;return 0 ; err_dt:
@@ -961,7 +962,6 @@ static const struct iommu_ops rk_iommu_ops = { .add_device = rk_iommu_add_device, .remove_device = rk_iommu_remove_device, .iova_to_phys = rk_iommu_iova_to_phys, - .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, };static int rk_iommu_probe (struct platform_device *pdev)
drivers/iommu/shmobile-iommu.c +1 -1
@@ -101,6 +101,7 @@ static int shmobile_iommu_domain_init(struct iommu_domain *domain)spin_lock_init (&sh_domain->attached_list_lock);INIT_LIST_HEAD (&sh_domain->attached_list); domain->priv = sh_domain; + domain->pgsize_bitmap =SZ_1M |SZ_64K |SZ_4K ;return 0 ; }
@@ -364,7 +365,6 @@ static const struct iommu_ops shmobile_iommu_ops = { .map_sg = default_iommu_map_sg, .iova_to_phys = shmobile_iommu_iova_to_phys, .add_device = shmobile_iommu_add_device, - .pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K, };int ipmmu_iommu_init (struct shmobile_ipmmu *ipmmu)
drivers/iommu/tegra-gart.c +1 -1
@@ -218,6 +218,7 @@ out:static int gart_iommu_domain_init (struct iommu_domain *domain) { + domain->pgsize_bitmap =GART_IOMMU_PGSIZES ;return 0 ; }
@@ -318,7 +319,6 @@ static const struct iommu_ops gart_iommu_ops = { .map_sg = default_iommu_map_sg, .unmap = gart_iommu_unmap, .iova_to_phys = gart_iommu_iova_to_phys, - .pgsize_bitmap = GART_IOMMU_PGSIZES, };static int tegra_gart_suspend (struct device *dev)
drivers/iommu/tegra-smmu.c +1 -2
@@ -265,6 +265,7 @@ static int tegra_smmu_domain_init(struct iommu_domain *domain) pd[i] =0 ; domain->priv = as; + domain->pgsize_bitmap =SZ_4K ;return 0 ; }
@@ -643,8 +644,6 @@ static const struct iommu_ops tegra_smmu_ops = { .unmap = tegra_smmu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = tegra_smmu_iova_to_phys, - - .pgsize_bitmap = SZ_4K, };static void tegra_smmu_ahb_enable (void )
drivers/vfio/vfio_iommu_type1.c +1 -1
@@ -407,7 +407,7 @@ static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)mutex_lock (&iommu->lock);list_for_each_entry (domain, &iommu->domain_list, next) - bitmap &= domain->domain->ops->pgsize_bitmap; + bitmap &= domain->domain->pgsize_bitmap;mutex_unlock (&iommu->lock);return bitmap;
include/linux/iommu.h +1 -5
@@ -53,6 +53,7 @@ struct iommu_domain_geometry {struct iommu_domain {const struct iommu_ops *ops; +unsigned long pgsize_bitmap;/* Bitmap of supported page sizes */ void *priv;iommu_fault_handler_t handler;void *handler_token;
@@ -108,8 +109,6 @@ enum iommu_attr {* @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping -* @pgsize_bitmap: bitmap of supported page sizes -* @priv: per-instance data private to the iommu driver */ struct iommu_ops {bool (*capable)(enum iommu_cap );
@@ -144,9 +143,6 @@ struct iommu_ops {#ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev,struct of_phandle_args *args);#endif - -unsigned long pgsize_bitmap; -void *priv; };#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1/* Device added */
Signature · 1 line
2.1.4
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
Hi Will,
Thank you for the patch.
Quoted 28 lines · On Friday 06 March 2015 11:34:47 Will Deacon wrote:
struct
iommu_opscontains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned longpgsize_bitmapfield, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.This patch moves the field from
iommu_opsinto theiommu_domainand updates all users accordingly.Signed-off-by Will Deacon <[email protected]>--- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/iommu.h | 6 +----- 14 files changed, 28 insertions(+), 32 deletions(-)
[snip]
drivers/iommu/ipmmu-vmsa.c static int ipmmu_domain_init(struct iommu_domain · line 473
Quoted 10 lines
drivers/iommu/ipmmu-vmsa.c +1
-0@@ -469,6 +469,7 @@ static int ipmmu_domain_init(struct iommu_domain *io_domain) io_domain->priv = domain; domain->io_domain = io_domain; + domain->pgsize_bitmap =SZ_2M |SZ_64K |SZ_4K ;
You're changing the bitmap, was it intended ?
Quoted 10 lines
drivers/iommu/ipmmu-vmsa.c +0
-1return 0 ; }@@ -747,7 +748,6 @@ static const struct iommu_ops ipmmu_ops = { .iova_to_phys = ipmmu_iova_to_phys, .add_device = ipmmu_add_device, .remove_device = ipmmu_remove_device, - .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K, };/* ------------------------------------------------------------------------
Signature · 3 lines
Regards, Laurent Pinchart
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
Quoted 1 line · Laurent Pinchart
Hi Will,
Hi Laurent,
Cheers for taking a look.
Quoted 8 lines · On Friday 06 March 2015 11:34:47 Will Deacon wrote:
Quoted 7 lines
drivers/iommu/ipmmu-vmsa.c +0
-0@@ -469,6 +469,7 @@ static int ipmmu_domain_init(struct iommu_domain *io_domain)
Quoted 5 lines
drivers/iommu/ipmmu-vmsa.c static int ipmmu_domain_init(struct iommu_domain *io_domain) · line 472
Quoted 3 lines
drivers/iommu/ipmmu-vmsa.c +1
-0io_domain->priv = domain; domain->io_domain = io_domain; + domain->pgsize_bitmap =SZ_2M |SZ_64K |SZ_4K ;You're changing the bitmap, was it intended ?
Yikes, no, sorry about that. It looks like this is due to a bad rebase (I build tested everything, but don't have an ipmmu-vmsa to run on). You changed the bitmap in f20ed39f531 when you moved to the generic allocator and I didn't pick up the change here. Will fix.
Will
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
In reply to Will DeaconHi Will,
Quoted 28 lines · On Friday 06 March 2015 11:34:47 Will Deacon wrote:
struct
iommu_opscontains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned longpgsize_bitmapfield, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.This patch moves the field from
iommu_opsinto theiommu_domainand updates all users accordingly.Signed-off-by Will Deacon <[email protected]>--- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/iommu.h | 6 +----- 14 files changed, 28 insertions(+), 32 deletions(-)
[snip]
Quoted 22 lines
include/linux/iommu.h +1
-2@@ -53,6 +53,7 @@ struct iommu_domain_geometry {struct iommu_domain {const struct iommu_ops *ops; +unsigned long pgsize_bitmap;/* Bitmap of supported page sizes */ void *priv;iommu_fault_handler_t handler;void *handler_token;@@ -108,8 +109,6 @@ enum iommu_attr {* @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping -* @pgsize_bitmap: bitmap of supported page sizes -* @priv: per-instance data private to the iommu driver */ struct iommu_ops {bool (*capable)(enum iommu_cap );
include/linux/iommu.h struct iommu_ops { · line 149
Quoted 6 lines
include/linux/iommu.h +0
-3@@ -144,9 +143,6 @@ struct iommu_ops {#ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev,struct of_phandle_args *args);#endif - -unsigned long pgsize_bitmap; -void *priv;
The commit message doesn't mention the removal of the priv field.
Quoted 3 lines
include/linux/iommu.h +0
-0};#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1/* Device added */
Signature · 3 lines
Regards, Laurent Pinchart
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
Quoted 11 lines · Laurent Pinchart
Quoted 10 lines · On Friday 06 March 2015 11:34:47 Will Deacon wrote:
include/linux/iommu.h +0
-2@@ -108,8 +109,6 @@ enum iommu_attr {* @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping -* @pgsize_bitmap: bitmap of supported page sizes -* @priv: per-instance data private to the iommu driver */ struct iommu_ops {bool (*capable)(enum iommu_cap );@@ -144,9 +143,6 @@ struct iommu_ops {
Quoted 8 lines
include/linux/iommu.h struct iommu_ops { · line 149
Quoted 6 lines
include/linux/iommu.h +0
-3#ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev,struct of_phandle_args *args);#endif - -unsigned long pgsize_bitmap; -void *priv;The commit message doesn't mention the removal of the priv field.
Yup, that's sloppy. I'll move it into a separate patch.
Will
Marek Szyprowski
maintainerPATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
In reply to Will DeaconHello,
Quoted 8 lines · Will Deacon
struct
iommu_opscontains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned longpgsize_bitmapfield, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.
Quoted 4 lines
This patch moves the field from
iommu_opsinto theiommu_domainand updates all users accordingly.Signed-off-by Will Deacon <[email protected]>
For the exynos iommu part:
Quoted 384 lines
--- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/iommu.h | 6 +----- 14 files changed, 28 insertions(+), 32 deletions(-)drivers/iommu/amd_iommu.c +1
-1@@ -3257,6 +3257,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) dom->geometry.aperture_end = ~0ULL ; dom->geometry.force_aperture = true; + dom->pgsize_bitmap =AMD_IOMMU_PGSIZES ;return 0 ; out_free:@@ -3428,7 +3429,6 @@ static const struct iommu_ops amd_iommu_ops = { .unmap = amd_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = amd_iommu_iova_to_phys, - .pgsize_bitmap = AMD_IOMMU_PGSIZES, };/***************************************************************************** drivers/iommu/arm-smmu.c +5
-7@@ -287,6 +287,7 @@ struct arm_smmu_device {void __iomem *base;unsigned long size;unsigned long pgshift; +unsigned long pgsize_bitmap;#define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0)#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)@@ -345,8 +346,6 @@ struct arm_smmu_domain {struct mutex init_mutex;/* Protects smmu pointer */ }; -static struct iommu_ops arm_smmu_ops; -static DEFINE_SPINLOCK (arm_smmu_devices_lock);static LIST_HEAD (arm_smmu_devices);@@ -911,7 +910,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, } pgtbl_cfg = (struct io_pgtable_cfg ) { - .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, + .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, .oas = oas, .tlb = &arm_smmu_gather_ops,@@ -925,7 +924,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, }/* Update our support page sizes to reflect the page table format */ - arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;/* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank (smmu_domain, &pgtbl_cfg);@@ -1430,7 +1429,7 @@ out_unlock:return ret; } -static struct iommu_ops arm_smmu_ops = { +static const struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_init = arm_smmu_domain_init, .domain_destroy = arm_smmu_domain_destroy,@@ -1444,7 +1443,6 @@ static struct iommu_ops arm_smmu_ops = { .remove_device = arm_smmu_remove_device, .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, - .pgsize_bitmap = -1UL, /* Restricted during device attach */ };static void arm_smmu_device_reset (struct arm_smmu_device *smmu)@@ -1648,7 +1646,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) size |=SZ_64K |SZ_512M ; } - arm_smmu_ops.pgsize_bitmap &= size; + smmu->pgsize_bitmap = size;dev_notice (smmu->dev,"\tSupported page sizes: 0x%08lx\n" , size);if (smmu->features &ARM_SMMU_FEAT_TRANS_S1 )drivers/iommu/exynos-iommu.c +2
-1@@ -735,6 +735,8 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = ~0UL ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =SECT_SIZE |LPAGE_SIZE |SPAGE_SIZE ; + domain->priv = priv;return 0 ;@@ -1181,7 +1183,6 @@ static const struct iommu_ops exynos_iommu_ops = { .iova_to_phys = exynos_iommu_iova_to_phys, .add_device = exynos_iommu_add_device, .remove_device = exynos_iommu_remove_device, - .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE, };static int __init exynos_iommu_init (void )drivers/iommu/intel-iommu.c +1
-1@@ -4363,6 +4363,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end =__DOMAIN_MAX_ADDR (dmar_domain->gaw); domain->geometry.force_aperture = true; + domain->pgsize_bitmap =INTEL_IOMMU_PGSIZES ;return 0 ; }@@ -4605,7 +4606,6 @@ static const struct iommu_ops intel_iommu_ops = { .iova_to_phys = intel_iommu_iova_to_phys, .add_device = intel_iommu_add_device, .remove_device = intel_iommu_remove_device, - .pgsize_bitmap = INTEL_IOMMU_PGSIZES, };static void quirk_iommu_g4x_gfx (struct pci_dev *dev)drivers/iommu/iommu.c +8
-8@@ -1025,7 +1025,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, pgsize = (1UL << (pgsize_idx +1 )) -1 ;/* throw away page sizes not supported by the hardware */ - pgsize &= domain->ops->pgsize_bitmap; + pgsize &= domain->pgsize_bitmap;/* make sure we're still sane */ BUG_ON (!pgsize);@@ -1046,11 +1046,11 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,int ret =0 ;if (unlikely (domain->ops->map ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * both the virtual address and the physical one, as well as @@ -1097,11 +1097,11 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)unsigned long orig_iova = iova;if (unlikely (domain->ops->unmap ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * The virtual address, as well as the size of the mapping, must be @@ -1147,10 +1147,10 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,unsigned int i, min_pagesz;int ret; -if (unlikely (domain->ops->pgsize_bitmap ==0UL )) +if (unlikely (domain->pgsize_bitmap ==0UL ))return 0 ; - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);for_each_sg (sg, s, nents, i) {phys_addr_t phys =page_to_phys (sg_page (s)) + s->offset;@@ -1231,7 +1231,7 @@ int iommu_domain_get_attr(struct iommu_domain *domain,break ;case DOMAIN_ATTR_PAGING : paging = data; - *paging = (domain->ops->pgsize_bitmap !=0UL ); + *paging = (domain->pgsize_bitmap !=0UL );break ;case DOMAIN_ATTR_WINDOWS : count = data;drivers/iommu/ipmmu-vmsa.c +1
-1@@ -469,6 +469,7 @@ static int ipmmu_domain_init(struct iommu_domain *io_domain) io_domain->priv = domain; domain->io_domain = io_domain; + domain->pgsize_bitmap =SZ_2M |SZ_64K |SZ_4K ;return 0 ; }@@ -747,7 +748,6 @@ static const struct iommu_ops ipmmu_ops = { .iova_to_phys = ipmmu_iova_to_phys, .add_device = ipmmu_add_device, .remove_device = ipmmu_remove_device, - .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K, };/* ----------------------------------------------------------------------------- drivers/iommu/msm_iommu.c +2
-1@@ -230,6 +230,8 @@ static int msm_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL <<32 ) -1 ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =MSM_IOMMU_PGSIZES ; +return 0 ; fail_nomem:@@ -682,7 +684,6 @@ static const struct iommu_ops msm_iommu_ops = { .unmap = msm_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = msm_iommu_iova_to_phys, - .pgsize_bitmap = MSM_IOMMU_PGSIZES, };static int __init get_tex_class (int icp,int ocp,int mt,int nos)drivers/iommu/omap-iommu.c +2
-1@@ -1250,6 +1250,8 @@ static int omap_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL <<32 ) -1 ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =OMAP_IOMMU_PGSIZES ; +return 0 ; fail_nomem:@@ -1368,7 +1370,6 @@ static const struct iommu_ops omap_iommu_ops = { .iova_to_phys = omap_iommu_iova_to_phys, .add_device = omap_iommu_add_device, .remove_device = omap_iommu_remove_device, - .pgsize_bitmap = OMAP_IOMMU_PGSIZES, };static int __init omap_iommu_init (void )drivers/iommu/rockchip-iommu.c +1
-1@@ -828,6 +828,7 @@ static int rk_iommu_domain_init(struct iommu_domain *domain)INIT_LIST_HEAD (&rk_domain->iommus); domain->priv = rk_domain; + domain->pgsize_bitmap =RK_IOMMU_PGSIZE_BITMAP ;return 0 ; err_dt:@@ -961,7 +962,6 @@ static const struct iommu_ops rk_iommu_ops = { .add_device = rk_iommu_add_device, .remove_device = rk_iommu_remove_device, .iova_to_phys = rk_iommu_iova_to_phys, - .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, };static int rk_iommu_probe (struct platform_device *pdev)drivers/iommu/shmobile-iommu.c +1
-1@@ -101,6 +101,7 @@ static int shmobile_iommu_domain_init(struct iommu_domain *domain)spin_lock_init (&sh_domain->attached_list_lock);INIT_LIST_HEAD (&sh_domain->attached_list); domain->priv = sh_domain; + domain->pgsize_bitmap =SZ_1M |SZ_64K |SZ_4K ;return 0 ; }@@ -364,7 +365,6 @@ static const struct iommu_ops shmobile_iommu_ops = { .map_sg = default_iommu_map_sg, .iova_to_phys = shmobile_iommu_iova_to_phys, .add_device = shmobile_iommu_add_device, - .pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K, };int ipmmu_iommu_init (struct shmobile_ipmmu *ipmmu)drivers/iommu/tegra-gart.c +1
-1@@ -218,6 +218,7 @@ out:static int gart_iommu_domain_init (struct iommu_domain *domain) { + domain->pgsize_bitmap =GART_IOMMU_PGSIZES ;return 0 ; }@@ -318,7 +319,6 @@ static const struct iommu_ops gart_iommu_ops = { .map_sg = default_iommu_map_sg, .unmap = gart_iommu_unmap, .iova_to_phys = gart_iommu_iova_to_phys, - .pgsize_bitmap = GART_IOMMU_PGSIZES, };static int tegra_gart_suspend (struct device *dev)drivers/iommu/tegra-smmu.c +1
-2@@ -265,6 +265,7 @@ static int tegra_smmu_domain_init(struct iommu_domain *domain) pd[i] =0 ; domain->priv = as; + domain->pgsize_bitmap =SZ_4K ;return 0 ; }@@ -643,8 +644,6 @@ static const struct iommu_ops tegra_smmu_ops = { .unmap = tegra_smmu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = tegra_smmu_iova_to_phys, - - .pgsize_bitmap = SZ_4K, };static void tegra_smmu_ahb_enable (void )drivers/vfio/vfio_iommu_type1.c +1
-1@@ -407,7 +407,7 @@ static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)mutex_lock (&iommu->lock);list_for_each_entry (domain, &iommu->domain_list, next) - bitmap &= domain->domain->ops->pgsize_bitmap; + bitmap &= domain->domain->pgsize_bitmap;mutex_unlock (&iommu->lock);return bitmap;include/linux/iommu.h +1
-2@@ -53,6 +53,7 @@ struct iommu_domain_geometry {struct iommu_domain {const struct iommu_ops *ops; +unsigned long pgsize_bitmap;/* Bitmap of supported page sizes */ void *priv;iommu_fault_handler_t handler;void *handler_token;@@ -108,8 +109,6 @@ enum iommu_attr {* @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping -* @pgsize_bitmap: bitmap of supported page sizes -* @priv: per-instance data private to the iommu driver */ struct iommu_ops {bool (*capable)(enum iommu_cap );
include/linux/iommu.h struct iommu_ops { · line 148
Quoted 9 lines
include/linux/iommu.h +0
-3@@ -144,9 +143,6 @@ struct iommu_ops {#ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev,struct of_phandle_args *args);#endif - -unsigned long pgsize_bitmap; -void *priv; };#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1/* Device added */
Best regards
Signature · 2 lines
Marek Szyprowski, PhD Samsung R&D Institute Poland
A message that is not in the archive (sent off-list or not yet received): 1425641688-26438-2-git-send-email-will.deacon-5wv7dgnIgG8@public.gmane.org
Daniel Kurtz
Acked-byRe: [PATCH 1/2] iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
Quoted 8 lines · Will Deacon
struct
iommu_opscontains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned longpgsize_bitmapfield, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.
Quoted 5 lines
This patch moves the field from
iommu_opsinto theiommu_domainand updates all users accordingly.Signed-off-by Will Deacon <[email protected]>
For the rockchip iommu part:
Quoted 430 lines
--- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/arm-smmu.c | 12 +++++------- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/intel-iommu.c | 2 +- drivers/iommu/iommu.c | 16 ++++++++-------- drivers/iommu/ipmmu-vmsa.c | 2 +- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 2 +- drivers/iommu/shmobile-iommu.c | 2 +- drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +-- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/iommu.h | 6 +----- 14 files changed, 28 insertions(+), 32 deletions(-)drivers/iommu/amd_iommu.c +1
-0@@ -3257,6 +3257,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) dom->geometry.aperture_end = ~0ULL ; dom->geometry.force_aperture = true; + dom->pgsize_bitmap =AMD_IOMMU_PGSIZES ;return 0 ;
out_free:drivers/iommu/amd_iommu.c +0
-1@@ -3428,7 +3429,6 @@ static const struct iommu_ops amd_iommu_ops = { .unmap = amd_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = amd_iommu_iova_to_phys, - .pgsize_bitmap = AMD_IOMMU_PGSIZES, };/*****************************************************************************
drivers/iommu/arm-smmu.c +1
-0@@ -287,6 +287,7 @@ struct arm_smmu_device {void __iomem *base;unsigned long size;unsigned long pgshift; +unsigned long pgsize_bitmap;#define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0)#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)@@ -345,8 +346,6 @@ struct arm_smmu_domain {struct mutex init_mutex;/* Protects smmu pointer */
};drivers/iommu/arm-smmu.c +1
-3-static struct iommu_ops arm_smmu_ops; -static DEFINE_SPINLOCK (arm_smmu_devices_lock);static LIST_HEAD (arm_smmu_devices);@@ -911,7 +910,7 @@ static int arm_smmu_init_domain_context(structiommu_domain *domain, } pgtbl_cfg = (struct io_pgtable_cfg ) { - .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, + .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, .oas = oas,.tlb =
&arm_smmu_gather_ops,drivers/iommu/arm-smmu.c +1
-1@@ -925,7 +924,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, }/* Update our support page sizes to reflect the page table format */ - arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;/* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg);drivers/iommu/arm-smmu.c +1
-2@@ -1430,7 +1429,7 @@ out_unlock:return ret; } -static struct iommu_ops arm_smmu_ops = { +static const struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_init = arm_smmu_domain_init, .domain_destroy = arm_smmu_domain_destroy,@@ -1444,7 +1443,6 @@ static struct iommu_ops arm_smmu_ops = {.remove_device = arm_smmu_remove_device, .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, - .pgsize_bitmap = -1UL, /* Restricted during device attach*/ };static void
arm_smmu_device_reset(struct arm_smmu_device *smmu)drivers/iommu/arm-smmu.c +1
-1@@ -1648,7 +1646,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) size |= SZ_64K | SZ_512M; } - arm_smmu_ops.pgsize_bitmap &= size; + smmu->pgsize_bitmap = size;dev_notice (smmu->dev,"\tSupported page sizes: 0x%08lx\n" , size);if (smmu->features & ARM_SMMU_FEAT_TRANS_S1)drivers/iommu/exynos-iommu.c +2
-1@@ -735,6 +735,8 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = ~0UL; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =SECT_SIZE |LPAGE_SIZE |SPAGE_SIZE ; + domain->priv = priv;return 0 ;@@ -1181,7 +1183,6 @@ static const struct iommu_ops exynos_iommu_ops = { .iova_to_phys = exynos_iommu_iova_to_phys, .add_device = exynos_iommu_add_device, .remove_device = exynos_iommu_remove_device, - .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE, };static int __init exynos_iommu_init (void )drivers/iommu/intel-iommu.c +1
-0@@ -4363,6 +4363,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end =__DOMAIN_MAX_ADDR (dmar_domain->gaw); domain->geometry.force_aperture = true; + domain->pgsize_bitmap =INTEL_IOMMU_PGSIZES ;return 0 ;}
drivers/iommu/intel-iommu.c +0
-1@@ -4605,7 +4606,6 @@ static const struct iommu_ops intel_iommu_ops = { .iova_to_phys = intel_iommu_iova_to_phys, .add_device = intel_iommu_add_device, .remove_device = intel_iommu_remove_device, - .pgsize_bitmap = INTEL_IOMMU_PGSIZES, };static void quirk_iommu_g4x_gfx (struct pci_dev *dev)drivers/iommu/iommu.c +1
-1@@ -1025,7 +1025,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, pgsize = (1UL << (pgsize_idx +1 )) -1 ;/* throw away page sizes not supported by the hardware */ - pgsize &= domain->ops->pgsize_bitmap; + pgsize &= domain->pgsize_bitmap;/* make sure we're still sane */ BUG_ON(!pgsize);drivers/iommu/iommu.c +2
-2@@ -1046,11 +1046,11 @@ int iommu_map(struct iommu_domain *domain,unsigned long iova, int ret = 0;if (unlikely (domain->ops->map ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * both the virtual address and the physical one, as well as
drivers/iommu/iommu.c +2
-2@@ -1097,11 +1097,11 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) unsigned long orig_iova = iova;if (unlikely (domain->ops->unmap ==NULL || - domain->ops->pgsize_bitmap ==0UL )) + domain->pgsize_bitmap ==0UL ))return -ENODEV ;/* find out the minimum page size supported */ - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);/* * The virtual address, as well as the size of the mapping, must be
drivers/iommu/iommu.c +2
-2@@ -1147,10 +1147,10 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova, unsigned int i, min_pagesz;int ret; -if (unlikely (domain->ops->pgsize_bitmap ==0UL )) +if (unlikely (domain->pgsize_bitmap ==0UL ))return 0 ; - min_pagesz =1 <<__ffs (domain->ops->pgsize_bitmap); + min_pagesz =1 <<__ffs (domain->pgsize_bitmap);for_each_sg (sg, s, nents, i) {phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;drivers/iommu/iommu.c +1
-1@@ -1231,7 +1231,7 @@ int iommu_domain_get_attr(struct iommu_domain *domain, break;case DOMAIN_ATTR_PAGING : paging = data; - *paging = (domain->ops->pgsize_bitmap !=0UL ); + *paging = (domain->pgsize_bitmap !=0UL );break ;case DOMAIN_ATTR_WINDOWS :count = data;drivers/iommu/ipmmu-vmsa.c +1
-0@@ -469,6 +469,7 @@ static int ipmmu_domain_init(struct iommu_domain *io_domain) io_domain->priv = domain; domain->io_domain = io_domain; + domain->pgsize_bitmap =SZ_2M |SZ_64K |SZ_4K ;return 0 ;}
drivers/iommu/ipmmu-vmsa.c +0
-2@@ -747,7 +748,6 @@ static const struct iommu_ops ipmmu_ops = { .iova_to_phys = ipmmu_iova_to_phys, .add_device = ipmmu_add_device, .remove_device = ipmmu_remove_device, - .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K, };/* ----------------------------------------------------------------------------- drivers/iommu/msm_iommu.c +2
-0@@ -230,6 +230,8 @@ static int msm_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL <<32 ) -1 ; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =MSM_IOMMU_PGSIZES ; +return 0 ;
fail_nomem:drivers/iommu/msm_iommu.c +0
-1@@ -682,7 +684,6 @@ static const struct iommu_ops msm_iommu_ops = { .unmap = msm_iommu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = msm_iommu_iova_to_phys, - .pgsize_bitmap = MSM_IOMMU_PGSIZES, };static int __init get_tex_class (int icp,int ocp,int mt,int nos)drivers/iommu/omap-iommu.c +2
-0@@ -1250,6 +1250,8 @@ static int omap_iommu_domain_init(struct iommu_domain *domain) domain->geometry.aperture_end = (1ULL << 32) - 1; domain->geometry.force_aperture = true; + domain->pgsize_bitmap =OMAP_IOMMU_PGSIZES ; +return 0 ;
fail_nomem:drivers/iommu/omap-iommu.c +0
-1@@ -1368,7 +1370,6 @@ static const struct iommu_ops omap_iommu_ops = { .iova_to_phys = omap_iommu_iova_to_phys, .add_device = omap_iommu_add_device, .remove_device = omap_iommu_remove_device, - .pgsize_bitmap = OMAP_IOMMU_PGSIZES, };static int __init omap_iommu_init (void )drivers/iommu/rockchip-iommu.c +1
-0@@ -828,6 +828,7 @@ static int rk_iommu_domain_init(struct iommu_domain *domain)INIT_LIST_HEAD (&rk_domain->iommus); domain->priv = rk_domain; + domain->pgsize_bitmap =RK_IOMMU_PGSIZE_BITMAP ;return 0 ;
err_dt:drivers/iommu/rockchip-iommu.c +0
-1@@ -961,7 +962,6 @@ static const struct iommu_ops rk_iommu_ops = { .add_device = rk_iommu_add_device, .remove_device = rk_iommu_remove_device, .iova_to_phys = rk_iommu_iova_to_phys, - .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, };static int rk_iommu_probe (struct platform_device *pdev)drivers/iommu/shmobile-iommu.c +1
-1@@ -101,6 +101,7 @@ static int shmobile_iommu_domain_init(struct iommu_domain *domain) spin_lock_init(&sh_domain->attached_list_lock);INIT_LIST_HEAD (&sh_domain->attached_list); domain->priv = sh_domain; + domain->pgsize_bitmap =SZ_1M |SZ_64K |SZ_4K ;return 0 ; }@@ -364,7 +365,6 @@ static const struct iommu_ops shmobile_iommu_ops = { .map_sg = default_iommu_map_sg, .iova_to_phys = shmobile_iommu_iova_to_phys, .add_device = shmobile_iommu_add_device, - .pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K, };int ipmmu_iommu_init (struct shmobile_ipmmu *ipmmu)drivers/iommu/tegra-gart.c +1
-1@@ -218,6 +218,7 @@ out:static int gart_iommu_domain_init (struct iommu_domain *domain) { + domain->pgsize_bitmap =GART_IOMMU_PGSIZES ;return 0 ; }@@ -318,7 +319,6 @@ static const struct iommu_ops gart_iommu_ops = { .map_sg = default_iommu_map_sg, .unmap = gart_iommu_unmap, .iova_to_phys = gart_iommu_iova_to_phys, - .pgsize_bitmap = GART_IOMMU_PGSIZES, };static int tegra_gart_suspend (struct device *dev)drivers/iommu/tegra-smmu.c +1
-0@@ -265,6 +265,7 @@ static int tegra_smmu_domain_init(struct iommu_domain *domain) pd[i] =0 ; domain->priv = as; + domain->pgsize_bitmap =SZ_4K ;return 0 ;}
drivers/iommu/tegra-smmu.c +0
-2@@ -643,8 +644,6 @@ static const struct iommu_ops tegra_smmu_ops = { .unmap = tegra_smmu_unmap, .map_sg = default_iommu_map_sg, .iova_to_phys = tegra_smmu_iova_to_phys, - - .pgsize_bitmap = SZ_4K, };static void tegra_smmu_ahb_enable (void )drivers/vfio/vfio_iommu_type1.c +1
-1@@ -407,7 +407,7 @@ static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu) mutex_lock(&iommu->lock);list_for_each_entry (domain, &iommu->domain_list, next) - bitmap &= domain->domain->ops->pgsize_bitmap; + bitmap &= domain->domain->pgsize_bitmap;mutex_unlock (&iommu->lock);return bitmap;include/linux/iommu.h +1
-0@@ -53,6 +53,7 @@ struct iommu_domain_geometry {struct iommu_domain {const struct iommu_ops *ops; +unsigned long pgsize_bitmap;/* Bitmap of supported page sizes */ void *priv;iommu_fault_handler_t handler;void *handler_token;include/linux/iommu.h +0
-6@@ -108,8 +109,6 @@ enum iommu_attr {* @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping -* @pgsize_bitmap: bitmap of supported page sizes -* @priv: per-instance data private to the iommu driver */ struct iommu_ops {bool (*capable)(enum iommu_cap );@@ -144,9 +143,6 @@ struct iommu_ops {#ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev,struct of_phandle_args *args);#endif - -unsigned long pgsize_bitmap; -void *priv; };#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1/* Device added */ --2.1.4
_______________________________________________
linux-arm-kernel mailing list linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 1/2 iommu: move pgsize_bitmap from struct iommu_ops to struct iommu_domain
In reply to Will DeaconQuoted 13 lines · Will Deacon
struct
iommu_opscontains function pointers for IOMMU driver callbacks in order to implement the core IOMMU API. Amongst these pointers is an unsigned longpgsize_bitmapfield, which is problematic because the set of supported page sizes is not necessarily the same across all instances of a given IOMMU type in the system. Furthermore, the set of supported page sizes may be restricted following domain initialisation when a particular page table format is chosen for the domain.This patch moves the field from
iommu_opsinto theiommu_domainand updates all users accordingly.Signed-off-by Will Deacon <[email protected]>---
[...]
Quoted 2 lines
drivers/iommu/tegra-gart.c | 2 +- drivers/iommu/tegra-smmu.c | 3 +--
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150311/55d9df1f/attachment.sig>
PATCH 2/2 iommu: of: enforce const-ness of struct iommu_ops
In reply to Will DeaconFrom: Robin Murphy <[email protected]>
With the pgsize_bitmap removed, there is no compelling reason for the remaining callbacks in struct iommu_ops to be mutable, so enforce const-ness throughout the core code.
--- arch/arm/include/asm/dma-mapping.h | 2 +- arch/arm/mm/dma-mapping.c | 6 +++--- arch/arm64/include/asm/dma-mapping.h | 3 ++- drivers/iommu/of_iommu.c | 12 ++++++------ drivers/of/platform.c | 2 +- include/linux/dma-mapping.h | 2 +- include/linux/of_iommu.h | 8 ++++---- 7 files changed, 18 insertions(+), 17 deletions(-)
arch/arm/include/asm/dma-mapping.h +1 -1
@@ -123,7 +123,7 @@ static inline unsigned long dma_max_pfn(struct device *dev)#define arch_setup_dma_ops arch_setup_dma_opsextern void arch_setup_dma_ops (struct device *dev,u64 dma_base,u64 size, -struct iommu_ops *iommu,bool coherent); +const struct iommu_ops *iommu,bool coherent);#define arch_teardown_dma_ops arch_teardown_dma_opsextern void arch_teardown_dma_ops (struct device *dev);
arch/arm/mm/dma-mapping.c +3 -3
@@ -2020,7 +2020,7 @@ static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent) }static bool arm_setup_iommu_dma_ops (struct device *dev,u64 dma_base,u64 size, -struct iommu_ops *iommu) +const struct iommu_ops *iommu) {struct dma_iommu_mapping *mapping;
@@ -2058,7 +2058,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)#else static bool arm_setup_iommu_dma_ops (struct device *dev,u64 dma_base,u64 size, -struct iommu_ops *iommu) +const struct iommu_ops *iommu) {return false; }
@@ -2075,7 +2075,7 @@ static struct dma_map_ops *arm_get_dma_map_ops(bool coherent) }void arch_setup_dma_ops (struct device *dev,u64 dma_base,u64 size, -struct iommu_ops *iommu,bool coherent) +const struct iommu_ops *iommu,bool coherent) {struct dma_map_ops *dma_ops;
arch/arm64/include/asm/dma-mapping.h +2 -1
@@ -46,7 +46,8 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) }static inline void arch_setup_dma_ops (struct device *dev,u64 dma_base,u64 size, -struct iommu_ops *iommu,bool coherent) +const struct iommu_ops *iommu, +bool coherent) { dev->archdata.dma_coherent = coherent; }
drivers/iommu/of_iommu.c +6 -6
@@ -98,12 +98,12 @@ EXPORT_SYMBOL_GPL(of_get_dma_window);struct of_iommu_node {struct list_head list;struct device_node *np; -struct iommu_ops *ops; +const struct iommu_ops *ops; };static LIST_HEAD (of_iommu_list);static DEFINE_SPINLOCK (of_iommu_lock); -void of_iommu_set_ops (struct device_node *np,struct iommu_ops *ops) +void of_iommu_set_ops (struct device_node *np,const struct iommu_ops *ops) {struct of_iommu_node *iommu =kzalloc (sizeof (*iommu),GFP_KERNEL );
@@ -118,10 +118,10 @@ void of_iommu_set_ops(struct device_node *np, struct iommu_ops *ops)spin_unlock (&of_iommu_lock); } -struct iommu_ops *of_iommu_get_ops (struct device_node *np) +const struct iommu_ops *of_iommu_get_ops (struct device_node *np) {struct of_iommu_node *node; -struct iommu_ops *ops =NULL ; +const struct iommu_ops *ops =NULL ;spin_lock (&of_iommu_lock);list_for_each_entry (node, &of_iommu_list, list)
@@ -133,11 +133,11 @@ struct iommu_ops *of_iommu_get_ops(struct device_node *np)return ops; } -struct iommu_ops *of_iommu_configure (struct device *dev) +const struct iommu_ops *of_iommu_configure (struct device *dev) {struct of_phandle_args iommu_spec;struct device_node *np; -struct iommu_ops *ops =NULL ; +const struct iommu_ops *ops =NULL ;int idx =0 ;/*
drivers/of/platform.c +1 -1
@@ -167,7 +167,7 @@ static void of_dma_configure(struct device *dev)int ret;bool coherent;unsigned long offset; -struct iommu_ops *iommu; +const struct iommu_ops *iommu;/* * Set default dma-mask to 32 bit. Drivers are expected to setup
include/linux/dma-mapping.h +1 -1
@@ -131,7 +131,7 @@ extern u64 dma_get_required_mask(struct device *dev);#ifndef arch_setup_dma_opsstatic inline void arch_setup_dma_ops (struct device *dev,u64 dma_base, -u64 size,struct iommu_ops *iommu, +u64 size,const struct iommu_ops *iommu,bool coherent) { }#endif
include/linux/of_iommu.h +4 -4
@@ -12,7 +12,7 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix, size_t *size);extern void of_iommu_init (void ); -extern struct iommu_ops *of_iommu_configure (struct device *dev); +extern const struct iommu_ops *of_iommu_configure (struct device *dev);#else
@@ -24,15 +24,15 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix, }static inline void of_iommu_init (void ) { } -static inline struct iommu_ops *of_iommu_configure (struct device *dev) +static inline const struct iommu_ops *of_iommu_configure (struct device *dev) {return NULL ; }#endif /* CONFIG_OF_IOMMU */ -void of_iommu_set_ops (struct device_node *np,struct iommu_ops *ops); -struct iommu_ops *of_iommu_get_ops (struct device_node *np); +void of_iommu_set_ops (struct device_node *np,const struct iommu_ops *ops); +const struct iommu_ops *of_iommu_get_ops (struct device_node *np);extern struct of_device_id __iommu_of_table;
Signature · 1 line
2.1.4
PATCH 2/2 iommu: of: enforce const-ness of struct iommu_ops
Quoted 8 lines · Will Deacon
From: Robin Murphy <[email protected]>
With the
pgsize_bitmapremoved, there is no compelling reason for the remaining callbacks in structiommu_opsto be mutable, so enforce const-ness throughout the core code.Signed-off-by Robin Murphy <[email protected]>Signed-off-by Will Deacon <[email protected]>
Quoted 9 lines
--- arch/arm/include/asm/dma-mapping.h | 2 +- arch/arm/mm/dma-mapping.c | 6 +++--- arch/arm64/include/asm/dma-mapping.h | 3 ++- drivers/iommu/of_iommu.c | 12 ++++++------ drivers/of/platform.c | 2 +- include/linux/dma-mapping.h | 2 +- include/linux/of_iommu.h | 8 ++++---- 7 files changed, 18 insertions(+), 17 deletions(-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150311/35ce187e/attachment.sig>