diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2016-10-11 16:55:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 18:06:33 -0400 |
commit | 9099daed9c6991a512c1f74b92ec49daf9408cda (patch) | |
tree | 9ebac94f168a0d5d843b715c1d19708d12a1c8c0 /mm/bootmem.c | |
parent | 0549a3c02efb350776bc869685a361045efd3a29 (diff) |
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>
Diffstat (limited to 'mm/bootmem.c')
-rw-r--r-- | mm/bootmem.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index a869f84f44d3..e8a55a3c9feb 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -155,7 +155,7 @@ void __init free_bootmem_late(unsigned long physaddr, unsigned long size) | |||
155 | { | 155 | { |
156 | unsigned long cursor, end; | 156 | unsigned long cursor, end; |
157 | 157 | ||
158 | kmemleak_free_part(__va(physaddr), size); | 158 | kmemleak_free_part_phys(physaddr, size); |
159 | 159 | ||
160 | cursor = PFN_UP(physaddr); | 160 | cursor = PFN_UP(physaddr); |
161 | end = PFN_DOWN(physaddr + size); | 161 | end = PFN_DOWN(physaddr + size); |
@@ -399,7 +399,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | |||
399 | { | 399 | { |
400 | unsigned long start, end; | 400 | unsigned long start, end; |
401 | 401 | ||
402 | kmemleak_free_part(__va(physaddr), size); | 402 | kmemleak_free_part_phys(physaddr, size); |
403 | 403 | ||
404 | start = PFN_UP(physaddr); | 404 | start = PFN_UP(physaddr); |
405 | end = PFN_DOWN(physaddr + size); | 405 | end = PFN_DOWN(physaddr + size); |
@@ -420,7 +420,7 @@ void __init free_bootmem(unsigned long physaddr, unsigned long size) | |||
420 | { | 420 | { |
421 | unsigned long start, end; | 421 | unsigned long start, end; |
422 | 422 | ||
423 | kmemleak_free_part(__va(physaddr), size); | 423 | kmemleak_free_part_phys(physaddr, size); |
424 | 424 | ||
425 | start = PFN_UP(physaddr); | 425 | start = PFN_UP(physaddr); |
426 | end = PFN_DOWN(physaddr + size); | 426 | end = PFN_DOWN(physaddr + size); |