diff options
author | Jeremy Fitzhardinge <jeremy@xensource.com> | 2006-09-26 02:32:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:55 -0400 |
commit | 052e79941a042e5be4feffa03b1fd60d93fb9e9a (patch) | |
tree | fd3ac24a05029b50a6c6ddfa486ea441b4091806 | |
parent | 9f093394d75cd9c5df82c7a99c5eb5d7ce7ba199 (diff) |
[PATCH] x86: make __FIXADDR_TOP variable to allow it to make space for a hypervisor
Make __FIXADDR_TOP a variable, so that it can be set to not get in the way of
address space a hypervisor may want to reserve.
Original patch by Gerd Hoffmann <kraxel@suse.de>
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Cc: Gerd Hoffmann <kraxel@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/i386/Kconfig | 1 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 42 | ||||
-rw-r--r-- | arch/i386/mm/pgtable.c | 26 | ||||
-rw-r--r-- | include/asm-i386/fixmap.h | 7 |
4 files changed, 75 insertions, 1 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index b2751eadbc56..1f83efb7a60e 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -794,6 +794,7 @@ config HOTPLUG_CPU | |||
794 | config COMPAT_VDSO | 794 | config COMPAT_VDSO |
795 | bool "Compat VDSO support" | 795 | bool "Compat VDSO support" |
796 | default y | 796 | default y |
797 | depends on !PARAVIRT | ||
797 | help | 798 | help |
798 | Map the VDSO to the predictable old-style address too. | 799 | Map the VDSO to the predictable old-style address too. |
799 | ---help--- | 800 | ---help--- |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 353453d550a4..efd0bcdac65d 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -629,6 +629,48 @@ void __init mem_init(void) | |||
629 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) | 629 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) |
630 | ); | 630 | ); |
631 | 631 | ||
632 | #if 1 /* double-sanity-check paranoia */ | ||
633 | printk("virtual kernel memory layout:\n" | ||
634 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
635 | #ifdef CONFIG_HIGHMEM | ||
636 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
637 | #endif | ||
638 | " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" | ||
639 | " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" | ||
640 | " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
641 | " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
642 | " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", | ||
643 | FIXADDR_START, FIXADDR_TOP, | ||
644 | (FIXADDR_TOP - FIXADDR_START) >> 10, | ||
645 | |||
646 | #ifdef CONFIG_HIGHMEM | ||
647 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, | ||
648 | (LAST_PKMAP*PAGE_SIZE) >> 10, | ||
649 | #endif | ||
650 | |||
651 | VMALLOC_START, VMALLOC_END, | ||
652 | (VMALLOC_END - VMALLOC_START) >> 20, | ||
653 | |||
654 | (unsigned long)__va(0), (unsigned long)high_memory, | ||
655 | ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20, | ||
656 | |||
657 | (unsigned long)&__init_begin, (unsigned long)&__init_end, | ||
658 | ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, | ||
659 | |||
660 | (unsigned long)&_etext, (unsigned long)&_edata, | ||
661 | ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, | ||
662 | |||
663 | (unsigned long)&_text, (unsigned long)&_etext, | ||
664 | ((unsigned long)&_etext - (unsigned long)&_text) >> 10); | ||
665 | |||
666 | #ifdef CONFIG_HIGHMEM | ||
667 | BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START); | ||
668 | BUG_ON(VMALLOC_END > PKMAP_BASE); | ||
669 | #endif | ||
670 | BUG_ON(VMALLOC_START > VMALLOC_END); | ||
671 | BUG_ON((unsigned long)high_memory > VMALLOC_START); | ||
672 | #endif /* double-sanity-check paranoia */ | ||
673 | |||
632 | #ifdef CONFIG_X86_PAE | 674 | #ifdef CONFIG_X86_PAE |
633 | if (!cpu_has_pae) | 675 | if (!cpu_has_pae) |
634 | panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); | 676 | panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); |
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index a9f4910a22f8..10126e3f8174 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/module.h> | ||
15 | 16 | ||
16 | #include <asm/system.h> | 17 | #include <asm/system.h> |
17 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
@@ -139,6 +140,12 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) | |||
139 | __flush_tlb_one(vaddr); | 140 | __flush_tlb_one(vaddr); |
140 | } | 141 | } |
141 | 142 | ||
143 | static int fixmaps; | ||
144 | #ifndef CONFIG_COMPAT_VDSO | ||
145 | unsigned long __FIXADDR_TOP = 0xfffff000; | ||
146 | EXPORT_SYMBOL(__FIXADDR_TOP); | ||
147 | #endif | ||
148 | |||
142 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | 149 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) |
143 | { | 150 | { |
144 | unsigned long address = __fix_to_virt(idx); | 151 | unsigned long address = __fix_to_virt(idx); |
@@ -148,6 +155,25 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | |||
148 | return; | 155 | return; |
149 | } | 156 | } |
150 | set_pte_pfn(address, phys >> PAGE_SHIFT, flags); | 157 | set_pte_pfn(address, phys >> PAGE_SHIFT, flags); |
158 | fixmaps++; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * reserve_top_address - reserves a hole in the top of kernel address space | ||
163 | * @reserve - size of hole to reserve | ||
164 | * | ||
165 | * Can be used to relocate the fixmap area and poke a hole in the top | ||
166 | * of kernel address space to make room for a hypervisor. | ||
167 | */ | ||
168 | void reserve_top_address(unsigned long reserve) | ||
169 | { | ||
170 | BUG_ON(fixmaps > 0); | ||
171 | #ifdef CONFIG_COMPAT_VDSO | ||
172 | BUG_ON(reserve != 0); | ||
173 | #else | ||
174 | __FIXADDR_TOP = -reserve - PAGE_SIZE; | ||
175 | __VMALLOC_RESERVE += reserve; | ||
176 | #endif | ||
151 | } | 177 | } |
152 | 178 | ||
153 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 179 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h index a48cc3f7ccc6..02428cb36621 100644 --- a/include/asm-i386/fixmap.h +++ b/include/asm-i386/fixmap.h | |||
@@ -19,7 +19,11 @@ | |||
19 | * Leave one empty page between vmalloc'ed areas and | 19 | * Leave one empty page between vmalloc'ed areas and |
20 | * the start of the fixmap. | 20 | * the start of the fixmap. |
21 | */ | 21 | */ |
22 | #define __FIXADDR_TOP 0xfffff000 | 22 | #ifndef CONFIG_COMPAT_VDSO |
23 | extern unsigned long __FIXADDR_TOP; | ||
24 | #else | ||
25 | #define __FIXADDR_TOP 0xfffff000 | ||
26 | #endif | ||
23 | 27 | ||
24 | #ifndef __ASSEMBLY__ | 28 | #ifndef __ASSEMBLY__ |
25 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
@@ -93,6 +97,7 @@ enum fixed_addresses { | |||
93 | 97 | ||
94 | extern void __set_fixmap (enum fixed_addresses idx, | 98 | extern void __set_fixmap (enum fixed_addresses idx, |
95 | unsigned long phys, pgprot_t flags); | 99 | unsigned long phys, pgprot_t flags); |
100 | extern void reserve_top_address(unsigned long reserve); | ||
96 | 101 | ||
97 | #define set_fixmap(idx, phys) \ | 102 | #define set_fixmap(idx, phys) \ |
98 | __set_fixmap(idx, phys, PAGE_KERNEL) | 103 | __set_fixmap(idx, phys, PAGE_KERNEL) |