Skip to content

Commit c288d65

Browse files
rleonmszyprow
authored andcommitted
iommu/dma: implement DMA_ATTR_MMIO for dma_iova_link().
This will replace the hacky use of DMA_ATTR_SKIP_CPU_SYNC to avoid touching the possibly non-KVA MMIO memory. Also correct the incorrect caching attribute for the IOMMU, MMIO memory should not be cachable inside the IOMMU mapping or it can possibly create system problems. Set IOMMU_MMIO for DMA_ATTR_MMIO. Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Marek Szyprowski <[email protected]> Link: https://lore.kernel.org/r/17ba63991aeaf8a80d5aca9ba5d028f1daa58f62.1757423202.git.leonro@nvidia.com
1 parent eadaa8b commit c288d65

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

drivers/iommu/dma-iommu.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,12 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, struct device *dev
724724
static int dma_info_to_prot(enum dma_data_direction dir, bool coherent,
725725
unsigned long attrs)
726726
{
727-
int prot = coherent ? IOMMU_CACHE : 0;
727+
int prot;
728+
729+
if (attrs & DMA_ATTR_MMIO)
730+
prot = IOMMU_MMIO;
731+
else
732+
prot = coherent ? IOMMU_CACHE : 0;
728733

729734
if (attrs & DMA_ATTR_PRIVILEGED)
730735
prot |= IOMMU_PRIV;
@@ -1838,12 +1843,13 @@ static int __dma_iova_link(struct device *dev, dma_addr_t addr,
18381843
unsigned long attrs)
18391844
{
18401845
bool coherent = dev_is_dma_coherent(dev);
1846+
int prot = dma_info_to_prot(dir, coherent, attrs);
18411847

1842-
if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
1848+
if (!coherent && !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO)))
18431849
arch_sync_dma_for_device(phys, size, dir);
18441850

18451851
return iommu_map_nosync(iommu_get_dma_domain(dev), addr, phys, size,
1846-
dma_info_to_prot(dir, coherent, attrs), GFP_ATOMIC);
1852+
prot, GFP_ATOMIC);
18471853
}
18481854

18491855
static int iommu_dma_iova_bounce_and_link(struct device *dev, dma_addr_t addr,
@@ -1949,9 +1955,13 @@ int dma_iova_link(struct device *dev, struct dma_iova_state *state,
19491955
return -EIO;
19501956

19511957
if (dev_use_swiotlb(dev, size, dir) &&
1952-
iova_unaligned(iovad, phys, size))
1958+
iova_unaligned(iovad, phys, size)) {
1959+
if (attrs & DMA_ATTR_MMIO)
1960+
return -EPERM;
1961+
19531962
return iommu_dma_iova_link_swiotlb(dev, state, phys, offset,
19541963
size, dir, attrs);
1964+
}
19551965

19561966
return __dma_iova_link(dev, state->addr + offset - iova_start_pad,
19571967
phys - iova_start_pad,

0 commit comments

Comments
 (0)