Skip to content

Commit

Permalink
dma-iommu: implement ->alloc_noncontiguous
Browse files Browse the repository at this point in the history
Implement support for allocating a non-contiguous DMA region.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Tested-by: Ricardo Ribalda <ribalda@chromium.org>
  • Loading branch information
Christoph Hellwig committed Mar 15, 2021
1 parent 8230ce9 commit e817ee5
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions drivers/iommu/dma-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev,
goto out_free_sg;

sgt->sgl->dma_address = iova;
sgt->sgl->dma_length = size;
return pages;

out_free_sg:
Expand Down Expand Up @@ -745,6 +746,37 @@ static void *iommu_dma_alloc_remap(struct device *dev, size_t size,
return NULL;
}

#ifdef CONFIG_DMA_REMAP
static struct sg_table *iommu_dma_alloc_noncontiguous(struct device *dev,
size_t size, enum dma_data_direction dir, gfp_t gfp,
unsigned long attrs)
{
struct dma_sgt_handle *sh;

sh = kmalloc(sizeof(*sh), gfp);
if (!sh)
return NULL;

sh->pages = __iommu_dma_alloc_noncontiguous(dev, size, &sh->sgt, gfp,
PAGE_KERNEL, attrs);
if (!sh->pages) {
kfree(sh);
return NULL;
}
return &sh->sgt;
}

static void iommu_dma_free_noncontiguous(struct device *dev, size_t size,
struct sg_table *sgt, enum dma_data_direction dir)
{
struct dma_sgt_handle *sh = sgt_handle(sgt);

__iommu_dma_unmap(dev, sgt->sgl->dma_address, size);
__iommu_dma_free_pages(sh->pages, PAGE_ALIGN(size) >> PAGE_SHIFT);
sg_free_table(&sh->sgt);
}
#endif /* CONFIG_DMA_REMAP */

static void iommu_dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
{
Expand Down Expand Up @@ -1261,6 +1293,10 @@ static const struct dma_map_ops iommu_dma_ops = {
.free = iommu_dma_free,
.alloc_pages = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
#ifdef CONFIG_DMA_REMAP
.alloc_noncontiguous = iommu_dma_alloc_noncontiguous,
.free_noncontiguous = iommu_dma_free_noncontiguous,
#endif
.mmap = iommu_dma_mmap,
.get_sgtable = iommu_dma_get_sgtable,
.map_page = iommu_dma_map_page,
Expand Down

0 comments on commit e817ee5

Please sign in to comment.