Name: Poison __init regions Author: Rusty Russell Status: Experimental Adds a CONFIG_POISON_INIT and an arch-specific "poison_code()" function. Index: linux-2.6.10-rc2-bk9-Misc/arch/i386/mm/init.c =================================================================== --- linux-2.6.10-rc2-bk9-Misc.orig/arch/i386/mm/init.c 2004-11-16 15:29:03.000000000 +1100 +++ linux-2.6.10-rc2-bk9-Misc/arch/i386/mm/init.c 2004-11-27 14:46:00.940942776 +1100 @@ -696,6 +696,20 @@ return flag; } +#ifdef CONFIG_POISON_INIT +void poison_mem(void *start, void *end) +{ + unsigned short bug_opcode = 0x0b0f, *mem; + + for (mem = start; (void *)mem < end; mem++) + *mem = bug_opcode; +} + +void free_initmem(void) +{ + poison_mem(&__init_begin, &__init_end); +} +#else void free_initmem(void) { unsigned long addr; @@ -710,6 +724,7 @@ } printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10); } +#endif /* CONFIG_POISON_INIT */ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) Index: linux-2.6.10-rc2-bk9-Misc/arch/i386/kernel/module.c =================================================================== --- linux-2.6.10-rc2-bk9-Misc.orig/arch/i386/kernel/module.c 2004-09-28 16:22:02.000000000 +1000 +++ linux-2.6.10-rc2-bk9-Misc/arch/i386/kernel/module.c 2004-11-27 14:46:00.940942776 +1100 @@ -35,12 +35,17 @@ return vmalloc_exec(size); } - /* Free memory returned from module_alloc */ void module_free(struct module *mod, void *module_region) { +#ifdef CONFIG_POISON_INIT + extern void poison_mem(void *start, void *end); + if (module_region == mod->module_init) + poison_mem(mod->module_init, mod->module_init+mod->init_size); + else +#endif vfree(module_region); - /* FIXME: If module_region == mod->init_region, trim exception + /* FIXME: If module_region == mod->module_init, trim exception table entries. */ } Index: linux-2.6.10-rc2-bk9-Misc/arch/i386/Kconfig =================================================================== --- linux-2.6.10-rc2-bk9-Misc.orig/arch/i386/Kconfig 2004-11-16 15:29:02.000000000 +1100 +++ linux-2.6.10-rc2-bk9-Misc/arch/i386/Kconfig 2004-11-27 14:47:29.556471168 +1100 @@ -35,6 +35,13 @@ source "init/Kconfig" +config DEBUG_POISON_INIT + bool "Poison init regions" + depends on DEBUG_KERNEL + help + Say Y here to have the kernel poison, rather than discard, + init sections in the kernel and modules. + menu "Processor type and features" choice Index: linux-2.6.10-rc2-bk9-Misc/include/asm-ppc64/bug.h =================================================================== --- linux-2.6.10-rc2-bk9-Misc.orig/include/asm-ppc64/bug.h 2004-10-19 14:34:20.000000000 +1000 +++ linux-2.6.10-rc2-bk9-Misc/include/asm-ppc64/bug.h 2004-11-27 14:46:00.941942624 +1100 @@ -1,13 +1,15 @@ #ifndef _PPC64_BUG_H #define _PPC64_BUG_H +#include /* * Define an illegal instr to trap on the bug. * We don't use 0 because that marks the end of a function * in the ELF ABI. That's "Boo Boo" in case you wonder... */ -#define BUG_OPCODE .long 0x00b00b00 /* For asm */ -#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ +#define BUG_WORD 0x00b00b00 +#define BUG_OPCODE .long BUG_WORD /* For asm */ +#define BUG_ILLEGAL_INSTR __stringify(BUG_WORD) /* For BUG macro */ #ifndef __ASSEMBLY__ Index: linux-2.6.10-rc2-bk9-Misc/arch/ppc64/mm/init.c =================================================================== --- linux-2.6.10-rc2-bk9-Misc.orig/arch/ppc64/mm/init.c 2004-11-16 15:29:12.000000000 +1100 +++ linux-2.6.10-rc2-bk9-Misc/arch/ppc64/mm/init.c 2004-11-27 14:46:00.941942624 +1100 @@ -441,6 +441,27 @@ #endif +#ifdef CONFIG_POISON_INIT +void poison_mem(void *start, void *end) +{ + unsigned long *mem; + + for (mem = start; (void *)mem < end; mem++) + *mem = BUG_WORD; +} + +void free_initmem(void) +{ + poison_mem(&__init_begin, &__init_end); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + poison_mem((void *)start, (void *)end); +} +#endif +#else void free_initmem(void) { unsigned long addr; @@ -469,6 +490,7 @@ } } #endif +#endif /* CONFIG_POISON_INIT */ static spinlock_t mmu_context_lock = SPIN_LOCK_UNLOCKED; static DEFINE_IDR(mmu_context_idr);