Skip to content

Commit fa3c109

Browse files
yosrym93Christoph Hellwig
authored andcommitted
dma-mapping: use bit masking to check VM_DMA_COHERENT
In dma_common_find_pages(), area->flags are compared directly with VM_DMA_COHERENT. This works because VM_DMA_COHERENT is the only set flag. During development of a new feature (ASI [1]), a new VM flag is introduced, and that flag can be injected into VM_DMA_COHERENT mappings (among others). The presence of that flag caused dma_common_find_pages() to return NULL for VM_DMA_COHERENT addresses, leading to a lot of problems ending in crashing during boot. It took a bit of time to figure this problem out. It was a mistake to inject a VM flag to begin with, but it took a significant amount of debugging to figure out the problem. Most users of area->flags use bitmasking rather than equivalency to check for flags. Update dma_common_find_pages() and dma_common_free_remap() to do the same, which would have avoided the boot crashing. Instead, add a warning in dma_common_find_pages() if any extra VM flags are set to catch such problems more easily during development. No functional change intended. [1]https://lore.kernel.org/lkml/[email protected]/ Signed-off-by: Yosry Ahmed <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 47ac09b commit fa3c109

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

kernel/dma/remap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ struct page **dma_common_find_pages(void *cpu_addr)
1010
{
1111
struct vm_struct *area = find_vm_area(cpu_addr);
1212

13-
if (!area || area->flags != VM_DMA_COHERENT)
13+
if (!area || !(area->flags & VM_DMA_COHERENT))
1414
return NULL;
15+
WARN(area->flags != VM_DMA_COHERENT,
16+
"unexpected flags in area: %p\n", cpu_addr);
1517
return area->pages;
1618
}
1719

@@ -61,7 +63,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size)
6163
{
6264
struct vm_struct *area = find_vm_area(cpu_addr);
6365

64-
if (!area || area->flags != VM_DMA_COHERENT) {
66+
if (!area || !(area->flags & VM_DMA_COHERENT)) {
6567
WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
6668
return;
6769
}

0 commit comments

Comments
 (0)