diff options
-rw-r--r-- | arch/i386/Kconfig.debug | 10 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 24 | ||||
-rw-r--r-- | include/asm-i386/cacheflush.h | 4 |
3 files changed, 38 insertions, 0 deletions
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index c48b424dd640..bf32ecc9ad04 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug | |||
@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC | |||
42 | This results in a large slowdown, but helps to find certain types | 42 | This results in a large slowdown, but helps to find certain types |
43 | of memory corruptions. | 43 | of memory corruptions. |
44 | 44 | ||
45 | config DEBUG_RODATA | ||
46 | bool "Write protect kernel read-only data structures" | ||
47 | depends on DEBUG_KERNEL | ||
48 | help | ||
49 | Mark the kernel read-only data as write-protected in the pagetables, | ||
50 | in order to catch accidental (and incorrect) writes to such const | ||
51 | data. This option may have a slight performance impact because a | ||
52 | portion of the kernel code won't be covered by a 2MB TLB anymore. | ||
53 | If in doubt, say "N". | ||
54 | |||
45 | config 4KSTACKS | 55 | config 4KSTACKS |
46 | bool "Use 4Kb for kernel stacks instead of 8Kb" | 56 | bool "Use 4Kb for kernel stacks instead of 8Kb" |
47 | depends on DEBUG_KERNEL | 57 | depends on DEBUG_KERNEL |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 06e26f006238..7df494b51a5b 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -735,6 +735,30 @@ void free_initmem(void) | |||
735 | printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10); | 735 | printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10); |
736 | } | 736 | } |
737 | 737 | ||
738 | #ifdef CONFIG_DEBUG_RODATA | ||
739 | |||
740 | extern char __start_rodata, __end_rodata; | ||
741 | void mark_rodata_ro(void) | ||
742 | { | ||
743 | unsigned long addr = (unsigned long)&__start_rodata; | ||
744 | |||
745 | for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE) | ||
746 | change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO); | ||
747 | |||
748 | printk ("Write protecting the kernel read-only data: %luk\n", | ||
749 | (unsigned long)(&__end_rodata - &__start_rodata) >> 10); | ||
750 | |||
751 | /* | ||
752 | * change_page_attr() requires a global_flush_tlb() call after it. | ||
753 | * We do this after the printk so that if something went wrong in the | ||
754 | * change, the printk gets out at least to give a better debug hint | ||
755 | * of who is the culprit. | ||
756 | */ | ||
757 | global_flush_tlb(); | ||
758 | } | ||
759 | #endif | ||
760 | |||
761 | |||
738 | #ifdef CONFIG_BLK_DEV_INITRD | 762 | #ifdef CONFIG_BLK_DEV_INITRD |
739 | void free_initrd_mem(unsigned long start, unsigned long end) | 763 | void free_initrd_mem(unsigned long start, unsigned long end) |
740 | { | 764 | { |
diff --git a/include/asm-i386/cacheflush.h b/include/asm-i386/cacheflush.h index 2ea36dea37d9..7199f7b326f1 100644 --- a/include/asm-i386/cacheflush.h +++ b/include/asm-i386/cacheflush.h | |||
@@ -31,4 +31,8 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot); | |||
31 | void kernel_map_pages(struct page *page, int numpages, int enable); | 31 | void kernel_map_pages(struct page *page, int numpages, int enable); |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #ifdef CONFIG_DEBUG_RODATA | ||
35 | void mark_rodata_ro(void); | ||
36 | #endif | ||
37 | |||
34 | #endif /* _I386_CACHEFLUSH_H */ | 38 | #endif /* _I386_CACHEFLUSH_H */ |