aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r--arch/x86_64/mm/init.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 282b0a8f00ad..c0822683b916 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -572,13 +572,13 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
572 572
573 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); 573 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
574 for (addr = begin; addr < end; addr += PAGE_SIZE) { 574 for (addr = begin; addr < end; addr += PAGE_SIZE) {
575 struct page *page = pfn_to_page(addr >> PAGE_SHIFT); 575 ClearPageReserved(virt_to_page(addr));
576 ClearPageReserved(page); 576 init_page_count(virt_to_page(addr));
577 init_page_count(page); 577 memset((void *)(addr & ~(PAGE_SIZE-1)),
578 memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); 578 POISON_FREE_INITMEM, PAGE_SIZE);
579 if (addr >= __START_KERNEL_map) 579 if (addr >= __START_KERNEL_map)
580 change_page_attr_addr(addr, 1, __pgprot(0)); 580 change_page_attr_addr(addr, 1, __pgprot(0));
581 __free_page(page); 581 free_page(addr);
582 totalram_pages++; 582 totalram_pages++;
583 } 583 }
584 if (addr > __START_KERNEL_map) 584 if (addr > __START_KERNEL_map)
@@ -588,26 +588,31 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
588void free_initmem(void) 588void free_initmem(void)
589{ 589{
590 free_init_pages("unused kernel memory", 590 free_init_pages("unused kernel memory",
591 __pa_symbol(&__init_begin), 591 (unsigned long)(&__init_begin),
592 __pa_symbol(&__init_end)); 592 (unsigned long)(&__init_end));
593} 593}
594 594
595#ifdef CONFIG_DEBUG_RODATA 595#ifdef CONFIG_DEBUG_RODATA
596 596
597void mark_rodata_ro(void) 597void mark_rodata_ro(void)
598{ 598{
599 unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size; 599 unsigned long start = (unsigned long)_stext, end;
600 600
601#ifdef CONFIG_HOTPLUG_CPU 601#ifdef CONFIG_HOTPLUG_CPU
602 /* It must still be possible to apply SMP alternatives. */ 602 /* It must still be possible to apply SMP alternatives. */
603 if (num_possible_cpus() > 1) 603 if (num_possible_cpus() > 1)
604 start = PFN_ALIGN(__va(__pa_symbol(&_etext))); 604 start = (unsigned long)_etext;
605#endif 605#endif
606 size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start; 606 end = (unsigned long)__end_rodata;
607 change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO); 607 start = (start + PAGE_SIZE - 1) & PAGE_MASK;
608 end &= PAGE_MASK;
609 if (end <= start)
610 return;
611
612 change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO);
608 613
609 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", 614 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
610 size >> 10); 615 (end - start) >> 10);
611 616
612 /* 617 /*
613 * change_page_attr_addr() requires a global_flush_tlb() call after it. 618 * change_page_attr_addr() requires a global_flush_tlb() call after it.
@@ -622,7 +627,7 @@ void mark_rodata_ro(void)
622#ifdef CONFIG_BLK_DEV_INITRD 627#ifdef CONFIG_BLK_DEV_INITRD
623void free_initrd_mem(unsigned long start, unsigned long end) 628void free_initrd_mem(unsigned long start, unsigned long end)
624{ 629{
625 free_init_pages("initrd memory", __pa(start), __pa(end)); 630 free_init_pages("initrd memory", start, end);
626} 631}
627#endif 632#endif
628 633