From 3ceed597e9afa38f1de1aba57605bb2b2dee21b7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 7 Jul 2011 18:43:36 +0100 Subject: [PATCH] ARM: 6996/1: mm: Poison freed init memory Poisoning __init marked memory can be useful when tracking down obscure memory corruption bugs. Therefore, poison init memory with 0xe7fddef0 to catch bugs earlier. The poison value is an undefined instruction in ARM mode and branch to an undefined instruction in Thumb mode. Change-Id: Ibb91bee46b829b0deac9f4e592040a0054968998 Signed-off-by: Stephen Boyd Acked-by: Nicolas Pitre Signed-off-by: Russell King [sboyd@codeaurora.org: Fix conflicts from total_unmovable_pages] Signed-off-by: Stephen Boyd ARM: 7010/1: mm: fix invalid loop for poison_init_mem poison_init_mem() used a loop of: while ((count = count - 4)) which has 2 problems - an off by one error so that we do one less word than we should, and the other is that if count == 0 then we loop forever and poison too much. On a platform with HAVE_TCM=y but nothing in the TCM's, this caused corruption and the platform failed to boot. Acked-by: Stephen Boyd Acked-by: Nicolas Pitre Signed-off-by: Jamie Iles Signed-off-by: Russell King Signed-off-by: Stephen Boyd --- arch/arm/mm/init.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index e5e34864c38..db80bd3dfaa 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -491,6 +491,17 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) return pages; } +/* + * Poison init memory with an undefined instruction (ARM) or a branch to an + * undefined instruction (Thumb). + */ +static inline void poison_init_mem(void *s, size_t count) +{ + u32 *p = (u32 *)s; + for (; count != 0; count -= 4) + *p++ = 0xe7fddef0; +} + static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn) { @@ -799,12 +810,14 @@ void free_initmem(void) #ifdef CONFIG_HAVE_TCM extern char __tcm_start, __tcm_end; + poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), __phys_to_pfn(__pa(&__tcm_end)), "TCM link"); #endif if (!machine_is_integrator() && !machine_is_cintegrator()) { + poison_init_mem(__init_begin, __init_end - __init_begin); reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)), __phys_to_pfn(__pa(__init_end)), "init"); @@ -850,6 +863,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) { unsigned long reclaimed_initrd_mem; if (!keep_initrd) { + poison_init_mem((void *)start, PAGE_ALIGN(end) - start); reclaimed_initrd_mem = free_area(__phys_to_pfn(__pa(start)), __phys_to_pfn(__pa(end)), "initrd");