diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2011-07-07 13:43:36 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-08 05:28:50 -0400 |
commit | 54d525735140e930d87c5afd1b0b3393ffdac021 (patch) | |
tree | ea40e1c00f5ca916ca8cc13c8b4adb91334dac29 /arch/arm/mm/init.c | |
parent | 7fa22bd5460bb2021729fa5a1012c60b9b3a56e2 (diff) |
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.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/init.c')
-rw-r--r-- | arch/arm/mm/init.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 2c2cce9cd8c8..fdc87f9bda55 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -416,6 +416,17 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) | |||
416 | return pages; | 416 | return pages; |
417 | } | 417 | } |
418 | 418 | ||
419 | /* | ||
420 | * Poison init memory with an undefined instruction (ARM) or a branch to an | ||
421 | * undefined instruction (Thumb). | ||
422 | */ | ||
423 | static inline void poison_init_mem(void *s, size_t count) | ||
424 | { | ||
425 | u32 *p = (u32 *)s; | ||
426 | while ((count = count - 4)) | ||
427 | *p++ = 0xe7fddef0; | ||
428 | } | ||
429 | |||
419 | static inline void | 430 | static inline void |
420 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) | 431 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) |
421 | { | 432 | { |
@@ -696,11 +707,13 @@ void free_initmem(void) | |||
696 | #ifdef CONFIG_HAVE_TCM | 707 | #ifdef CONFIG_HAVE_TCM |
697 | extern char __tcm_start, __tcm_end; | 708 | extern char __tcm_start, __tcm_end; |
698 | 709 | ||
710 | poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); | ||
699 | totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), | 711 | totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), |
700 | __phys_to_pfn(__pa(&__tcm_end)), | 712 | __phys_to_pfn(__pa(&__tcm_end)), |
701 | "TCM link"); | 713 | "TCM link"); |
702 | #endif | 714 | #endif |
703 | 715 | ||
716 | poison_init_mem(__init_begin, __init_end - __init_begin); | ||
704 | if (!machine_is_integrator() && !machine_is_cintegrator()) | 717 | if (!machine_is_integrator() && !machine_is_cintegrator()) |
705 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), | 718 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), |
706 | __phys_to_pfn(__pa(__init_end)), | 719 | __phys_to_pfn(__pa(__init_end)), |
@@ -713,10 +726,12 @@ static int keep_initrd; | |||
713 | 726 | ||
714 | void free_initrd_mem(unsigned long start, unsigned long end) | 727 | void free_initrd_mem(unsigned long start, unsigned long end) |
715 | { | 728 | { |
716 | if (!keep_initrd) | 729 | if (!keep_initrd) { |
730 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); | ||
717 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), | 731 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), |
718 | __phys_to_pfn(__pa(end)), | 732 | __phys_to_pfn(__pa(end)), |
719 | "initrd"); | 733 | "initrd"); |
734 | } | ||
720 | } | 735 | } |
721 | 736 | ||
722 | static int __init keepinitrd_setup(char *__unused) | 737 | static int __init keepinitrd_setup(char *__unused) |