Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <jgg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/17ba63991aeaf8a80d5aca9ba5d028f1daa58f62.1757423202.git.leonro@nvidia.com

authored by

Leon Romanovsky and committed by
Marek Szyprowski
c288d657 eadaa8b2

+14 -4
+14 -4
drivers/iommu/dma-iommu.c
··· 724 724 static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, 725 725 unsigned long attrs) 726 726 { 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; 728 733 729 734 if (attrs & DMA_ATTR_PRIVILEGED) 730 735 prot |= IOMMU_PRIV; ··· 1843 1838 unsigned long attrs) 1844 1839 { 1845 1840 bool coherent = dev_is_dma_coherent(dev); 1841 + int prot = dma_info_to_prot(dir, coherent, attrs); 1846 1842 1847 - if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) 1843 + if (!coherent && !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) 1848 1844 arch_sync_dma_for_device(phys, size, dir); 1849 1845 1850 1846 return iommu_map_nosync(iommu_get_dma_domain(dev), addr, phys, size, 1851 - dma_info_to_prot(dir, coherent, attrs), GFP_ATOMIC); 1847 + prot, GFP_ATOMIC); 1852 1848 } 1853 1849 1854 1850 static int iommu_dma_iova_bounce_and_link(struct device *dev, dma_addr_t addr, ··· 1955 1949 return -EIO; 1956 1950 1957 1951 if (dev_use_swiotlb(dev, size, dir) && 1958 - iova_unaligned(iovad, phys, size)) 1952 + iova_unaligned(iovad, phys, size)) { 1953 + if (attrs & DMA_ATTR_MMIO) 1954 + return -EPERM; 1955 + 1959 1956 return iommu_dma_iova_link_swiotlb(dev, state, phys, offset, 1960 1957 size, dir, attrs); 1958 + } 1961 1959 1962 1960 return __dma_iova_link(dev, state->addr + offset - iova_start_pad, 1963 1961 phys - iova_start_pad,