Skip to content

Commit f5ebf24

Browse files
rleonmszyprow
authored andcommitted
mm/hmm: Indicate that HMM requires DMA coherency
HMM is fundamentally about allowing a sophisticated device to perform DMA directly to a process’s memory while the CPU accesses that same memory at the same time. It is similar to SVA but does not rely on IOMMU support. Because the entire model depends on concurrent access to shared memory, it fails as a uAPI if SWIOTLB substitutes the memory or if the CPU caches are not coherent with DMA. Until now, there has been no reliable way to report this, and various approximations have been used: int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map, size_t nr_entries, size_t dma_entry_size) { <...> /* * The HMM API violates our normal DMA buffer ownership rules and can't * transfer buffer ownership. The dma_addressing_limited() check is a * best approximation to ensure no swiotlb buffering happens. */ dma_need_sync = !dev->dma_skip_sync; if (dma_need_sync || dma_addressing_limited(dev)) return -EOPNOTSUPP; So let's mark mapped buffers with DMA_ATTR_REQUIRE_COHERENT attribute to prevent silent data corruption if someone tries to use hmm in a system with swiotlb or incoherent DMA 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/[email protected]
1 parent d9d43a3 commit f5ebf24

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

mm/hmm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ dma_addr_t hmm_dma_map_pfn(struct device *dev, struct hmm_dma_map *map,
778778
struct page *page = hmm_pfn_to_page(pfns[idx]);
779779
phys_addr_t paddr = hmm_pfn_to_phys(pfns[idx]);
780780
size_t offset = idx * map->dma_entry_size;
781-
unsigned long attrs = 0;
781+
unsigned long attrs = DMA_ATTR_REQUIRE_COHERENT;
782782
dma_addr_t dma_addr;
783783
int ret;
784784

@@ -871,7 +871,7 @@ bool hmm_dma_unmap_pfn(struct device *dev, struct hmm_dma_map *map, size_t idx)
871871
struct dma_iova_state *state = &map->state;
872872
dma_addr_t *dma_addrs = map->dma_list;
873873
unsigned long *pfns = map->pfn_list;
874-
unsigned long attrs = 0;
874+
unsigned long attrs = DMA_ATTR_REQUIRE_COHERENT;
875875

876876
if ((pfns[idx] & valid_dma) != valid_dma)
877877
return false;

0 commit comments

Comments
 (0)