aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/mm/init.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2007-05-02 13:27:07 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:07 -0400
commit0dbf7028c0c1f266c9631139450a1502d3cd457e (patch)
tree2616edcd32d92b6539d2810fd3043b054baabb92 /arch/x86_64/mm/init.c
parent1b29c1643c0d82512477ccd97dc290198fe23e22 (diff)
[PATCH] x86: __pa and __pa_symbol address space separation
Currently __pa_symbol is for use with symbols in the kernel address map and __pa is for use with pointers into the physical memory map. But the code is implemented so you can usually interchange the two. __pa which is much more common can be implemented much more cheaply if it is it doesn't have to worry about any other kernel address spaces. This is especially true with a relocatable kernel as __pa_symbol needs to peform an extra variable read to resolve the address. There is a third macro that is added for the vsyscall data __pa_vsymbol for finding the physical addesses of vsyscall pages. Most of this patch is simply sorting through the references to __pa or __pa_symbol and using the proper one. A little of it is continuing to use a physical address when we have it instead of recalculating it several times. swapper_pgd is now NULL. leave_mm now uses init_mm.pgd and init_mm.pgd is initialized at boot (instead of compile time) to the physmem virtual mapping of init_level4_pgd. The physical address changed. Except for the for EMPTY_ZERO page all of the remaining references to __pa_symbol appear to be during kernel initialization. So this should reduce the cost of __pa in the common case, even on a relocated kernel. As this is technically a semantic change we need to be on the lookout for anything I missed. But it works for me (tm). Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r--arch/x86_64/mm/init.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index b0a607892183..69e22d3c9238 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -565,11 +565,11 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
565 565
566 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); 566 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
567 for (addr = begin; addr < end; addr += PAGE_SIZE) { 567 for (addr = begin; addr < end; addr += PAGE_SIZE) {
568 ClearPageReserved(virt_to_page(addr)); 568 struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
569 init_page_count(virt_to_page(addr)); 569 ClearPageReserved(page);
570 memset((void *)(addr & ~(PAGE_SIZE-1)), 570 init_page_count(page);
571 POISON_FREE_INITMEM, PAGE_SIZE); 571 memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
572 free_page(addr); 572 __free_page(page);
573 totalram_pages++; 573 totalram_pages++;
574 } 574 }
575} 575}
@@ -579,17 +579,18 @@ void free_initmem(void)
579 memset(__initdata_begin, POISON_FREE_INITDATA, 579 memset(__initdata_begin, POISON_FREE_INITDATA,
580 __initdata_end - __initdata_begin); 580 __initdata_end - __initdata_begin);
581 free_init_pages("unused kernel memory", 581 free_init_pages("unused kernel memory",
582 (unsigned long)(&__init_begin), 582 __pa_symbol(&__init_begin),
583 (unsigned long)(&__init_end)); 583 __pa_symbol(&__init_end));
584} 584}
585 585
586#ifdef CONFIG_DEBUG_RODATA 586#ifdef CONFIG_DEBUG_RODATA
587 587
588void mark_rodata_ro(void) 588void mark_rodata_ro(void)
589{ 589{
590 unsigned long addr = (unsigned long)__start_rodata; 590 unsigned long addr = (unsigned long)__va(__pa_symbol(&__start_rodata));
591 unsigned long end = (unsigned long)__va(__pa_symbol(&__end_rodata));
591 592
592 for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) 593 for (; addr < end; addr += PAGE_SIZE)
593 change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); 594 change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
594 595
595 printk ("Write protecting the kernel read-only data: %luk\n", 596 printk ("Write protecting the kernel read-only data: %luk\n",
@@ -608,7 +609,7 @@ void mark_rodata_ro(void)
608#ifdef CONFIG_BLK_DEV_INITRD 609#ifdef CONFIG_BLK_DEV_INITRD
609void free_initrd_mem(unsigned long start, unsigned long end) 610void free_initrd_mem(unsigned long start, unsigned long end)
610{ 611{
611 free_init_pages("initrd memory", start, end); 612 free_init_pages("initrd memory", __pa(start), __pa(end));
612} 613}
613#endif 614#endif
614 615