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.

kmsan: convert kmsan_handle_dma to use physical addresses

Convert the KMSAN DMA handling function from page-based to physical
address-based interface.

The refactoring renames kmsan_handle_dma() parameters from accepting
(struct page *page, size_t offset, size_t size) to (phys_addr_t phys,
size_t size). The existing semantics where callers are expected to
provide only kmap memory is continued here.

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

authored by

Leon Romanovsky and committed by
Marek Szyprowski
6eb1e769 e53d29f9

+15 -13
+2 -2
drivers/virtio/virtio_ring.c
··· 378 378 * is initialized by the hardware. Explicitly check/unpoison it 379 379 * depending on the direction. 380 380 */ 381 - kmsan_handle_dma(sg_page(sg), sg->offset, sg->length, direction); 381 + kmsan_handle_dma(sg_phys(sg), sg->length, direction); 382 382 *addr = (dma_addr_t)sg_phys(sg); 383 383 return 0; 384 384 } ··· 3157 3157 struct vring_virtqueue *vq = to_vvq(_vq); 3158 3158 3159 3159 if (!vq->use_dma_api) { 3160 - kmsan_handle_dma(virt_to_page(ptr), offset_in_page(ptr), size, dir); 3160 + kmsan_handle_dma(virt_to_phys(ptr), size, dir); 3161 3161 return (dma_addr_t)virt_to_phys(ptr); 3162 3162 } 3163 3163
+4 -5
include/linux/kmsan.h
··· 182 182 183 183 /** 184 184 * kmsan_handle_dma() - Handle a DMA data transfer. 185 - * @page: first page of the buffer. 186 - * @offset: offset of the buffer within the first page. 185 + * @phys: physical address of the buffer. 187 186 * @size: buffer size. 188 187 * @dir: one of possible dma_data_direction values. 189 188 * ··· 191 192 * * initializes the buffer, if it is copied from device; 192 193 * * does both, if this is a DMA_BIDIRECTIONAL transfer. 193 194 */ 194 - void kmsan_handle_dma(struct page *page, size_t offset, size_t size, 195 + void kmsan_handle_dma(phys_addr_t phys, size_t size, 195 196 enum dma_data_direction dir); 196 197 197 198 /** ··· 371 372 { 372 373 } 373 374 374 - static inline void kmsan_handle_dma(struct page *page, size_t offset, 375 - size_t size, enum dma_data_direction dir) 375 + static inline void kmsan_handle_dma(phys_addr_t phys, size_t size, 376 + enum dma_data_direction dir) 376 377 { 377 378 } 378 379
+2 -1
kernel/dma/mapping.c
··· 172 172 addr = iommu_dma_map_phys(dev, phys, size, dir, attrs); 173 173 else 174 174 addr = ops->map_page(dev, page, offset, size, dir, attrs); 175 - kmsan_handle_dma(page, offset, size, dir); 175 + 176 + kmsan_handle_dma(phys, size, dir); 176 177 trace_dma_map_phys(dev, phys, addr, size, dir, attrs); 177 178 debug_dma_map_phys(dev, phys, size, dir, addr, attrs); 178 179
+6 -4
mm/kmsan/hooks.c
··· 336 336 } 337 337 338 338 /* Helper function to handle DMA data transfers. */ 339 - void kmsan_handle_dma(struct page *page, size_t offset, size_t size, 339 + void kmsan_handle_dma(phys_addr_t phys, size_t size, 340 340 enum dma_data_direction dir) 341 341 { 342 - u64 page_offset, to_go, addr; 342 + struct page *page = phys_to_page(phys); 343 + u64 page_offset, to_go; 344 + void *addr; 343 345 344 - if (PageHighMem(page)) 346 + if (PhysHighMem(phys)) 345 347 return; 346 - addr = (u64)page_address(page) + offset; 348 + addr = page_to_virt(page); 347 349 /* 348 350 * The kernel may occasionally give us adjacent DMA pages not belonging 349 351 * to the same allocation. Process them separately to avoid triggering
+1 -1
tools/virtio/linux/kmsan.h
··· 4 4 5 5 #include <linux/gfp.h> 6 6 7 - inline void kmsan_handle_dma(struct page *page, size_t offset, size_t size, 7 + inline void kmsan_handle_dma(phys_addr_t phys, size_t size, 8 8 enum dma_data_direction dir) 9 9 { 10 10 }