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

Configure Feed

Select the types of activity you want to include in your feed.

dma-mapping: implement DMA_ATTR_MMIO for dma_(un)map_page_attrs()

Make dma_map_page_attrs() and dma_map_page_attrs() respect
DMA_ATTR_MMIO.

DMA_ATR_MMIO makes the functions behave the same as
dma_(un)map_resource():
- No swiotlb is possible
- Legacy dma_ops arches use ops->map_resource()
- No kmsan
- No arch_dma_map_phys_direct()

The prior patches have made the internal functions called here
support DMA_ATTR_MMIO.

This is also preparation for turning dma_map_resource() into an inline
calling dma_map_phys(DMA_ATTR_MMIO) to consolidate the flows.

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/3660e2c78ea409d6c483a215858fb3af52cd0ed3.1757423202.git.leonro@nvidia.com

authored by

Leon Romanovsky and committed by
Marek Szyprowski
18c9cbb0 6eb1e769

+22 -6
+22 -6
kernel/dma/mapping.c
··· 158 158 { 159 159 const struct dma_map_ops *ops = get_dma_ops(dev); 160 160 phys_addr_t phys = page_to_phys(page) + offset; 161 + bool is_mmio = attrs & DMA_ATTR_MMIO; 161 162 dma_addr_t addr; 162 163 163 164 BUG_ON(!valid_dma_direction(dir)); ··· 167 166 return DMA_MAPPING_ERROR; 168 167 169 168 if (dma_map_direct(dev, ops) || 170 - arch_dma_map_phys_direct(dev, phys + size)) 169 + (!is_mmio && arch_dma_map_phys_direct(dev, phys + size))) 171 170 addr = dma_direct_map_phys(dev, phys, size, dir, attrs); 172 171 else if (use_dma_iommu(dev)) 173 172 addr = iommu_dma_map_phys(dev, phys, size, dir, attrs); 174 - else 175 - addr = ops->map_page(dev, page, offset, size, dir, attrs); 173 + else if (is_mmio) { 174 + if (!ops->map_resource) 175 + return DMA_MAPPING_ERROR; 176 176 177 - kmsan_handle_dma(phys, size, dir); 177 + addr = ops->map_resource(dev, phys, size, dir, attrs); 178 + } else { 179 + /* 180 + * The dma_ops API contract for ops->map_page() requires 181 + * kmappable memory, while ops->map_resource() does not. 182 + */ 183 + addr = ops->map_page(dev, page, offset, size, dir, attrs); 184 + } 185 + 186 + if (!is_mmio) 187 + kmsan_handle_dma(phys, size, dir); 178 188 trace_dma_map_phys(dev, phys, addr, size, dir, attrs); 179 189 debug_dma_map_phys(dev, phys, size, dir, addr, attrs); 180 190 ··· 197 185 enum dma_data_direction dir, unsigned long attrs) 198 186 { 199 187 const struct dma_map_ops *ops = get_dma_ops(dev); 188 + bool is_mmio = attrs & DMA_ATTR_MMIO; 200 189 201 190 BUG_ON(!valid_dma_direction(dir)); 202 191 if (dma_map_direct(dev, ops) || 203 - arch_dma_unmap_phys_direct(dev, addr + size)) 192 + (!is_mmio && arch_dma_unmap_phys_direct(dev, addr + size))) 204 193 dma_direct_unmap_phys(dev, addr, size, dir, attrs); 205 194 else if (use_dma_iommu(dev)) 206 195 iommu_dma_unmap_phys(dev, addr, size, dir, attrs); 207 - else 196 + else if (is_mmio) { 197 + if (ops->unmap_resource) 198 + ops->unmap_resource(dev, addr, size, dir, attrs); 199 + } else 208 200 ops->unmap_page(dev, addr, size, dir, attrs); 209 201 trace_dma_unmap_phys(dev, addr, size, dir, attrs); 210 202 debug_dma_unmap_phys(dev, addr, size, dir);