From e22541ba69b4a2b1f5ea458a1fc7b5155f22c868 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 27 Aug 2009 14:50:00 +0100 Subject: [PATCH] --- yaml --- r: 157417 b: refs/heads/master c: 8e019366ba749a536131cde1947af6dcaccf8e8f h: refs/heads/master i: 157415: 8bc9db7241885040e74e16fa8083f4303f1fc182 v: v3 --- [refs] | 2 +- trunk/arch/x86/mm/kmemcheck/kmemcheck.c | 14 ++++++++++++++ trunk/include/linux/kmemcheck.h | 7 +++++++ trunk/mm/kmemleak.c | 12 ++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 73f21c80e200..1bde8dfc05b3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: acde31dc467797ccae3a55b791a77af446cce018 +refs/heads/master: 8e019366ba749a536131cde1947af6dcaccf8e8f diff --git a/trunk/arch/x86/mm/kmemcheck/kmemcheck.c b/trunk/arch/x86/mm/kmemcheck/kmemcheck.c index 2c55ed098654..528bf954eb74 100644 --- a/trunk/arch/x86/mm/kmemcheck/kmemcheck.c +++ b/trunk/arch/x86/mm/kmemcheck/kmemcheck.c @@ -331,6 +331,20 @@ static void kmemcheck_read_strict(struct pt_regs *regs, kmemcheck_shadow_set(shadow, size); } +bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size) +{ + enum kmemcheck_shadow status; + void *shadow; + + shadow = kmemcheck_shadow_lookup(addr); + if (!shadow) + return true; + + status = kmemcheck_shadow_test(shadow, size); + + return status == KMEMCHECK_SHADOW_INITIALIZED; +} + /* Access may cross page boundary */ static void kmemcheck_read(struct pt_regs *regs, unsigned long addr, unsigned int size) diff --git a/trunk/include/linux/kmemcheck.h b/trunk/include/linux/kmemcheck.h index 47b39b7c7e84..dc2fd545db00 100644 --- a/trunk/include/linux/kmemcheck.h +++ b/trunk/include/linux/kmemcheck.h @@ -34,6 +34,8 @@ void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n); int kmemcheck_show_addr(unsigned long address); int kmemcheck_hide_addr(unsigned long address); +bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size); + #else #define kmemcheck_enabled 0 @@ -99,6 +101,11 @@ static inline void kmemcheck_mark_initialized_pages(struct page *p, { } +static inline bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size) +{ + return true; +} + #endif /* CONFIG_KMEMCHECK */ /* diff --git a/trunk/mm/kmemleak.c b/trunk/mm/kmemleak.c index 1d7645b0a97c..c494fee7a2b5 100644 --- a/trunk/mm/kmemleak.c +++ b/trunk/mm/kmemleak.c @@ -97,6 +97,7 @@ #include #include +#include #include /* @@ -967,15 +968,22 @@ static void scan_block(void *_start, void *_end, unsigned long *end = _end - (BYTES_PER_POINTER - 1); for (ptr = start; ptr < end; ptr++) { - unsigned long flags; - unsigned long pointer = *ptr; struct kmemleak_object *object; + unsigned long flags; + unsigned long pointer; if (allow_resched) cond_resched(); if (scan_should_stop()) break; + /* don't scan uninitialized memory */ + if (!kmemcheck_is_obj_initialized((unsigned long)ptr, + BYTES_PER_POINTER)) + continue; + + pointer = *ptr; + object = find_and_get_object(pointer, 1); if (!object) continue;