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>
This commit is contained in:
committed by
H. Peter Anvin
parent
b9af7c0d44
commit
74e081797b
@@ -727,9 +727,13 @@ void set_kernel_text_ro(void)
|
||||
|
||||
void mark_rodata_ro(void)
|
||||
{
|
||||
unsigned long start = PFN_ALIGN(_text), end = PFN_ALIGN(__end_rodata);
|
||||
unsigned long start = PFN_ALIGN(_text);
|
||||
unsigned long rodata_start =
|
||||
((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
unsigned long end = (unsigned long) &__end_rodata_hpage_align;
|
||||
unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table);
|
||||
unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata);
|
||||
unsigned long data_start = (unsigned long) &_sdata;
|
||||
|
||||
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
|
||||
(end - start) >> 10);
|
||||
@@ -752,6 +756,14 @@ void mark_rodata_ro(void)
|
||||
printk(KERN_INFO "Testing CPA: again\n");
|
||||
set_memory_ro(start, (end-start) >> PAGE_SHIFT);
|
||||
#endif
|
||||
|
||||
free_init_pages("unused kernel memory",
|
||||
(unsigned long) page_address(virt_to_page(text_end)),
|
||||
(unsigned long)
|
||||
page_address(virt_to_page(rodata_start)));
|
||||
free_init_pages("unused kernel memory",
|
||||
(unsigned long) page_address(virt_to_page(rodata_end)),
|
||||
(unsigned long) page_address(virt_to_page(data_start)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user