aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init_64.c
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2009-10-14 17:46:56 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-10-20 01:46:00 -0400
commit74e081797bd9d2a7d8005fe519e719df343a2ba8 (patch)
treef210cca2002f87bf4cb17c20b853c129ce1df8f9 /arch/x86/mm/init_64.c
parentb9af7c0d44b8bb71e3af5e94688d076414aa8c87 (diff)
x86-64: align RODATA kernel section to 2MB with CONFIG_DEBUG_RODATA
CONFIG_DEBUG_RODATA chops the large pages spanning boundaries of kernel text/rodata/data to small 4KB pages as they are mapped with different attributes (text as RO, RODATA as RO and NX etc). On x86_64, preserve the large page mappings for kernel text/rodata/data boundaries when CONFIG_DEBUG_RODATA is enabled. This is done by allowing the RODATA section to be hugepage aligned and having same RWX attributes for the 2MB page boundaries Extra Memory pages padding the sections will be freed during the end of the boot and the kernel identity mappings will have different RWX permissions compared to the kernel text mappings. Kernel identity mappings to these physical pages will be mapped with smaller pages but large page mappings are still retained for kernel text,rodata,data mappings. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> LKML-Reference: <20091014220254.190119924@sbs-t61.sc.intel.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r--arch/x86/mm/init_64.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 7dafd4159ad..0ed09fad6aa 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -727,9 +727,13 @@ void set_kernel_text_ro(void)
727 727
728void mark_rodata_ro(void) 728void mark_rodata_ro(void)
729{ 729{
730 unsigned long start = PFN_ALIGN(_text), end = PFN_ALIGN(__end_rodata); 730 unsigned long start = PFN_ALIGN(_text);
731 unsigned long rodata_start = 731 unsigned long rodata_start =
732 ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; 732 ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
733 unsigned long end = (unsigned long) &__end_rodata_hpage_align;
734 unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table);
735 unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata);
736 unsigned long data_start = (unsigned long) &_sdata;
733 737
734 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", 738 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
735 (end - start) >> 10); 739 (end - start) >> 10);
@@ -752,6 +756,14 @@ void mark_rodata_ro(void)
752 printk(KERN_INFO "Testing CPA: again\n"); 756 printk(KERN_INFO "Testing CPA: again\n");
753 set_memory_ro(start, (end-start) >> PAGE_SHIFT); 757 set_memory_ro(start, (end-start) >> PAGE_SHIFT);
754#endif 758#endif
759
760 free_init_pages("unused kernel memory",
761 (unsigned long) page_address(virt_to_page(text_end)),
762 (unsigned long)
763 page_address(virt_to_page(rodata_start)));
764 free_init_pages("unused kernel memory",
765 (unsigned long) page_address(virt_to_page(rodata_end)),
766 (unsigned long) page_address(virt_to_page(data_start)));
755} 767}
756 768
757#endif 769#endif