diff options
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r-- | arch/x86_64/mm/init.c | 31 |
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) | |||
588 | void free_initmem(void) | 588 | void 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 | ||
597 | void mark_rodata_ro(void) | 597 | void 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 |
623 | void free_initrd_mem(unsigned long start, unsigned long end) | 628 | void 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 | ||