arm64/dma-mapping: Implement DMA_ATTR_PRIVILEGED

The newly added DMA_ATTR_PRIVILEGED is useful for creating mappings that
are only accessible to privileged DMA engines.  Implement it in
dma-iommu.c so that the ARM64 DMA IOMMU mapper can make use of it.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Tested-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
Mitchel Humpherys
2017-01-06 18:58:12 +05:30
committed by Will Deacon
parent b2fb366425
commit 737c85ca1c
3 changed files with 14 additions and 7 deletions

View File

@@ -558,7 +558,7 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
unsigned long attrs) unsigned long attrs)
{ {
bool coherent = is_device_dma_coherent(dev); bool coherent = is_device_dma_coherent(dev);
int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent); int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs);
size_t iosize = size; size_t iosize = size;
void *addr; void *addr;
@@ -712,7 +712,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
unsigned long attrs) unsigned long attrs)
{ {
bool coherent = is_device_dma_coherent(dev); bool coherent = is_device_dma_coherent(dev);
int prot = dma_direction_to_prot(dir, coherent); int prot = dma_info_to_prot(dir, coherent, attrs);
dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot); dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot);
if (!iommu_dma_mapping_error(dev, dev_addr) && if (!iommu_dma_mapping_error(dev, dev_addr) &&
@@ -770,7 +770,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
__iommu_sync_sg_for_device(dev, sgl, nelems, dir); __iommu_sync_sg_for_device(dev, sgl, nelems, dir);
return iommu_dma_map_sg(dev, sgl, nelems, return iommu_dma_map_sg(dev, sgl, nelems,
dma_direction_to_prot(dir, coherent)); dma_info_to_prot(dir, coherent, attrs));
} }
static void __iommu_unmap_sg_attrs(struct device *dev, static void __iommu_unmap_sg_attrs(struct device *dev,

View File

@@ -181,16 +181,22 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
EXPORT_SYMBOL(iommu_dma_init_domain); EXPORT_SYMBOL(iommu_dma_init_domain);
/** /**
* dma_direction_to_prot - Translate DMA API directions to IOMMU API page flags * dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
* page flags.
* @dir: Direction of DMA transfer * @dir: Direction of DMA transfer
* @coherent: Is the DMA master cache-coherent? * @coherent: Is the DMA master cache-coherent?
* @attrs: DMA attributes for the mapping
* *
* Return: corresponding IOMMU API page protection flags * Return: corresponding IOMMU API page protection flags
*/ */
int dma_direction_to_prot(enum dma_data_direction dir, bool coherent) int dma_info_to_prot(enum dma_data_direction dir, bool coherent,
unsigned long attrs)
{ {
int prot = coherent ? IOMMU_CACHE : 0; int prot = coherent ? IOMMU_CACHE : 0;
if (attrs & DMA_ATTR_PRIVILEGED)
prot |= IOMMU_PRIV;
switch (dir) { switch (dir) {
case DMA_BIDIRECTIONAL: case DMA_BIDIRECTIONAL:
return prot | IOMMU_READ | IOMMU_WRITE; return prot | IOMMU_READ | IOMMU_WRITE;
@@ -633,7 +639,7 @@ 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) size_t size, enum dma_data_direction dir, unsigned long attrs)
{ {
return __iommu_dma_map(dev, phys, size, return __iommu_dma_map(dev, phys, size,
dma_direction_to_prot(dir, false) | IOMMU_MMIO); dma_info_to_prot(dir, false, attrs) | IOMMU_MMIO);
} }
void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle, void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle,

View File

@@ -34,7 +34,8 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
u64 size, struct device *dev); u64 size, struct device *dev);
/* General helpers for DMA-API <-> IOMMU-API interaction */ /* General helpers for DMA-API <-> IOMMU-API interaction */
int dma_direction_to_prot(enum dma_data_direction dir, bool coherent); int dma_info_to_prot(enum dma_data_direction dir, bool coherent,
unsigned long attrs);
/* /*
* These implement the bulk of the relevant DMA mapping callbacks, but require * These implement the bulk of the relevant DMA mapping callbacks, but require