diff options
author | Gerd Hoffmann <kraxel@suse.de> | 2006-06-26 07:56:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 13:48:14 -0400 |
commit | d167a51877e94dda73dd656c51f363502309f713 (patch) | |
tree | eb02c2974b61777f575dfdc07d4c2adf83bde434 /arch/x86_64/mm | |
parent | 240cd6a80642da528bfa382ec2ae4e3cb8991ea7 (diff) |
[PATCH] x86_64: x86_64 version of the smp alternative patch.
Changes are largely identical to the i386 version:
* alternative #define are moved to the new alternative.h file.
* one new elf section with pointers to the lock prefixes which can be
nop'ed out for non-smp.
* two new elf sections simliar to the "classic" alternatives to
replace SMP code with simpler UP code.
* fixup headers to use alternative.h instead of defining their own
LOCK / LOCK_PREFIX macros.
The patch reuses the i386 version of the alternatives code to avoid code
duplication. The code in alternatives.c was shuffled around a bit to
reduce the number of #ifdefs needed. It also got some tweaks needed for
x86_64 (vsyscall page handling) and new features (noreplacement option
which was x86_64 only up to now). Debug printk's are changed from
compile-time to runtime.
Loosely based on a early version from Bastian Blank <waldi@debian.org>
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/mm')
-rw-r--r-- | arch/x86_64/mm/init.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4ba34e95d835..a70a8e3e312d 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -644,20 +644,29 @@ void __init mem_init(void) | |||
644 | #endif | 644 | #endif |
645 | } | 645 | } |
646 | 646 | ||
647 | void free_initmem(void) | 647 | void free_init_pages(char *what, unsigned long begin, unsigned long end) |
648 | { | 648 | { |
649 | unsigned long addr; | 649 | unsigned long addr; |
650 | 650 | ||
651 | addr = (unsigned long)(&__init_begin); | 651 | if (begin >= end) |
652 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | 652 | return; |
653 | |||
654 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
655 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
653 | ClearPageReserved(virt_to_page(addr)); | 656 | ClearPageReserved(virt_to_page(addr)); |
654 | init_page_count(virt_to_page(addr)); | 657 | init_page_count(virt_to_page(addr)); |
655 | memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); | 658 | memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); |
656 | free_page(addr); | 659 | free_page(addr); |
657 | totalram_pages++; | 660 | totalram_pages++; |
658 | } | 661 | } |
662 | } | ||
663 | |||
664 | void free_initmem(void) | ||
665 | { | ||
659 | memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); | 666 | memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); |
660 | printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); | 667 | free_init_pages("unused kernel memory", |
668 | (unsigned long)(&__init_begin), | ||
669 | (unsigned long)(&__init_end)); | ||
661 | } | 670 | } |
662 | 671 | ||
663 | #ifdef CONFIG_DEBUG_RODATA | 672 | #ifdef CONFIG_DEBUG_RODATA |
@@ -686,15 +695,7 @@ void mark_rodata_ro(void) | |||
686 | #ifdef CONFIG_BLK_DEV_INITRD | 695 | #ifdef CONFIG_BLK_DEV_INITRD |
687 | void free_initrd_mem(unsigned long start, unsigned long end) | 696 | void free_initrd_mem(unsigned long start, unsigned long end) |
688 | { | 697 | { |
689 | if (start >= end) | 698 | free_init_pages("initrd memory", start, end); |
690 | return; | ||
691 | printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
692 | for (; start < end; start += PAGE_SIZE) { | ||
693 | ClearPageReserved(virt_to_page(start)); | ||
694 | init_page_count(virt_to_page(start)); | ||
695 | free_page(start); | ||
696 | totalram_pages++; | ||
697 | } | ||
698 | } | 699 | } |
699 | #endif | 700 | #endif |
700 | 701 | ||