mm: kmemleak: avoid using __va() on addresses that don't have a lowmem mapping
Some of the kmemleak_*() callbacks in memblock, bootmem, CMA convert a physical address to a virtual one using __va(). However, such physical addresses may sometimes be located in highmem and using __va() is incorrect, leading to inconsistent object tracking in kmemleak. The following functions have been added to the kmemleak API and they take a physical address as the object pointer. They only perform the corresponding action if the address has a lowmem mapping: kmemleak_alloc_phys kmemleak_free_part_phys kmemleak_not_leak_phys kmemleak_ignore_phys The affected calling places have been updated to use the new kmemleak API. Link: http://lkml.kernel.org/r/1471531432-16503-1-git-send-email-catalin.marinas@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Reported-by: Vignesh R <vigneshr@ti.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
0549a3c02e
commit
9099daed9c
@@ -723,7 +723,7 @@ int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
|
||||
(unsigned long long)base + size - 1,
|
||||
(void *)_RET_IP_);
|
||||
|
||||
kmemleak_free_part(__va(base), size);
|
||||
kmemleak_free_part_phys(base, size);
|
||||
return memblock_remove_range(&memblock.reserved, base, size);
|
||||
}
|
||||
|
||||
@@ -1152,7 +1152,7 @@ static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
|
||||
* The min_count is set to 0 so that memblock allocations are
|
||||
* never reported as leaks.
|
||||
*/
|
||||
kmemleak_alloc(__va(found), size, 0, 0);
|
||||
kmemleak_alloc_phys(found, size, 0, 0);
|
||||
return found;
|
||||
}
|
||||
return 0;
|
||||
@@ -1399,7 +1399,7 @@ void __init __memblock_free_early(phys_addr_t base, phys_addr_t size)
|
||||
memblock_dbg("%s: [%#016llx-%#016llx] %pF\n",
|
||||
__func__, (u64)base, (u64)base + size - 1,
|
||||
(void *)_RET_IP_);
|
||||
kmemleak_free_part(__va(base), size);
|
||||
kmemleak_free_part_phys(base, size);
|
||||
memblock_remove_range(&memblock.reserved, base, size);
|
||||
}
|
||||
|
||||
@@ -1419,7 +1419,7 @@ void __init __memblock_free_late(phys_addr_t base, phys_addr_t size)
|
||||
memblock_dbg("%s: [%#016llx-%#016llx] %pF\n",
|
||||
__func__, (u64)base, (u64)base + size - 1,
|
||||
(void *)_RET_IP_);
|
||||
kmemleak_free_part(__va(base), size);
|
||||
kmemleak_free_part_phys(base, size);
|
||||
cursor = PFN_UP(base);
|
||||
end = PFN_DOWN(base + size);
|
||||
|
||||
|
Reference in New Issue
Block a user