arm_iommu_create_mapping allocates the mapping object, its IOVA bitmap and the corresponding IOMMU domain together. Separate the complicated part of mapping initialization, the bitmap initialization, into a new function, __arm_iommu_init_mapping. This allows the default domain path added later in the series to initialize the mapping object before the bitmap address range is known and later call _init_mapping to initialize the bitmaps.
No functional change. Signed-off-by: Mikko Perttunen <[email protected]> --- arch/arm/mm/dma-mapping.c | 109 +++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 7761099dde9e..7ef7c268c583 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1470,6 +1470,57 @@ static const struct dma_map_ops iommu_ops = { .sync_sg_for_device = arm_iommu_sync_sg_for_device, }; +static int __arm_iommu_init_mapping(struct dma_iommu_mapping *mapping, + dma_addr_t base, u64 size) +{ + unsigned int bits, bitmap_size; + unsigned long **bitmaps; + int extensions = 1; + + /* currently only 32-bit DMA address space is supported */ + if (size > DMA_BIT_MASK(32) + 1) + return -ERANGE; + + bits = size >> PAGE_SHIFT; + bitmap_size = BITS_TO_LONGS(bits) * sizeof(long); + if (!bitmap_size) + return -EINVAL; + + if (bitmap_size > PAGE_SIZE) { + extensions = bitmap_size / PAGE_SIZE; + bitmap_size = PAGE_SIZE; + } + + bitmaps = kcalloc(extensions, sizeof(*bitmaps), GFP_KERNEL); + if (!bitmaps) + return -ENOMEM; + + bitmaps[0] = kzalloc(bitmap_size, GFP_KERNEL); + if (!bitmaps[0]) { + kfree(bitmaps); + return -ENOMEM; + } + + mapping->bitmap_size = bitmap_size; + mapping->nr_bitmaps = 1; + mapping->extensions = extensions; + mapping->base = base; + mapping->bits = BITS_PER_BYTE * bitmap_size; + mapping->bitmaps = bitmaps; + + return 0; +} + +static void __arm_iommu_free_mapping(struct dma_iommu_mapping *mapping) +{ + int i; + + for (i = 0; i < mapping->nr_bitmaps; i++) + kfree(mapping->bitmaps[i]); + kfree(mapping->bitmaps); + kfree(mapping); +} + /** * arm_iommu_create_mapping * @dev: pointer to the client device (for IOMMU calls) @@ -1486,75 +1537,41 @@ static const struct dma_map_ops iommu_ops = { struct dma_iommu_mapping * arm_iommu_create_mapping(struct device *dev, dma_addr_t base, u64 size) { - unsigned int bits = size >> PAGE_SHIFT; - unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long); struct dma_iommu_mapping *mapping; - int extensions = 1; - int err = -ENOMEM; - - /* currently only 32-bit DMA address space is supported */ - if (size > DMA_BIT_MASK(32) + 1) - return ERR_PTR(-ERANGE); - - if (!bitmap_size) - return ERR_PTR(-EINVAL); - - if (bitmap_size > PAGE_SIZE) { - extensions = bitmap_size / PAGE_SIZE; - bitmap_size = PAGE_SIZE; - } + int err; - mapping = kzalloc_obj(struct dma_iommu_mapping); + mapping = kzalloc_obj(*mapping); if (!mapping) - goto err; + return ERR_PTR(-ENOMEM); - mapping->bitmap_size = bitmap_size; - mapping->bitmaps = kcalloc(extensions, sizeof(unsigned long *), - GFP_KERNEL); - if (!mapping->bitmaps) - goto err2; - - mapping->bitmaps[0] = kzalloc(bitmap_size, GFP_KERNEL); - if (!mapping->bitmaps[0]) - goto err3; - - mapping->nr_bitmaps = 1; - mapping->extensions = extensions; - mapping->base = base; - mapping->bits = BITS_PER_BYTE * bitmap_size; + err = __arm_iommu_init_mapping(mapping, base, size); + if (err) { + kfree(mapping); + return ERR_PTR(err); + } spin_lock_init(&mapping->lock); mapping->domain = iommu_paging_domain_alloc(dev); if (IS_ERR(mapping->domain)) { err = PTR_ERR(mapping->domain); - goto err4; + + __arm_iommu_free_mapping(mapping); + return ERR_PTR(err); } kref_init(&mapping->kref); return mapping; -err4: - kfree(mapping->bitmaps[0]); -err3: - kfree(mapping->bitmaps); -err2: - kfree(mapping); -err: - return ERR_PTR(err); } EXPORT_SYMBOL_GPL(arm_iommu_create_mapping); static void release_iommu_mapping(struct kref *kref) { - int i; struct dma_iommu_mapping *mapping = container_of(kref, struct dma_iommu_mapping, kref); iommu_domain_free(mapping->domain); - for (i = 0; i < mapping->nr_bitmaps; i++) - kfree(mapping->bitmaps[i]); - kfree(mapping->bitmaps); - kfree(mapping); + __arm_iommu_free_mapping(mapping); } static int extend_iommu_mapping(struct dma_iommu_mapping *mapping) -- 2.55.0
