1. should use _brk_end instead of &end, as we only use partial of brk. 2. [_brk_end, pm_end) page range is already converted. aka is not wasted. --- arch/x86/mm/init_64.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: linux-2.6/arch/x86/mm/init_64.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_64.c +++ linux-2.6/arch/x86/mm/init_64.c @@ -1124,7 +1124,8 @@ void mark_rodata_ro(void) unsigned long end = (unsigned long) &__end_rodata_hpage_align; unsigned long text_end = PFN_ALIGN(&__stop___ex_table); unsigned long rodata_end = PFN_ALIGN(&__end_rodata); - unsigned long all_end = PFN_ALIGN(&_end); + unsigned long all_end = PFN_ALIGN(_brk_end); + unsigned long pmd_end = roundup(all_end, PMD_SIZE); printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); @@ -1136,7 +1137,7 @@ void mark_rodata_ro(void) * The rodata/data/bss/brk section (but not the kernel text!) * should also be not-executable. */ - set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT); + set_memory_nx(rodata_start, (pmd_end - rodata_start) >> PAGE_SHIFT); rodata_test(); @@ -1148,6 +1149,7 @@ void mark_rodata_ro(void) set_memory_ro(start, (end-start) >> PAGE_SHIFT); #endif + /* all_end to pmd_end is handled via free_all_bootmem() */ free_init_pages("unused kernel", (unsigned long) __va(__pa_symbol(text_end)), (unsigned long) __va(__pa_symbol(rodata_start)));