diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-05-02 13:27:12 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:12 -0400 |
commit | d4f7a2c18e59e0304a1c733589ce14fc02fec1bd (patch) | |
tree | 99c64275f7eb50925aad71a74ae083ececdbb795 /arch/i386/mm | |
parent | a6c4e076ee4c1ea670e4faa55814e63dd08e3f29 (diff) |
[PATCH] i386: Relocate VDSO ELF headers to match mapped location with COMPAT_VDSO
Some versions of libc can't deal with a VDSO which doesn't have its
ELF headers matching its mapped address. COMPAT_VDSO maps the VDSO at
a specific system-wide fixed address. Previously this was all done at
build time, on the grounds that the fixed VDSO address is always at
the top of the address space. However, a hypervisor may reserve some
of that address space, pushing the fixmap address down.
This patch does the adjustment dynamically at runtime, depending on
the runtime location of the VDSO fixmap.
[ Patch has been through several hands: Jan Beulich wrote the orignal
version; Zach reworked it, and Jeremy converted it to relocate phdrs
as well as sections. ]
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Zachary Amsden <zach@vmware.com>
Cc: "Jan Beulich" <JBeulich@novell.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland McGrath <roland@redhat.com>
Diffstat (limited to 'arch/i386/mm')
-rw-r--r-- | arch/i386/mm/pgtable.c | 6 |
1 files changed, 0 insertions, 6 deletions
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index fa0cfbd551e1..99c09edc3dbb 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -144,10 +144,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | static int fixmaps; | 146 | static int fixmaps; |
147 | #ifndef CONFIG_COMPAT_VDSO | ||
148 | unsigned long __FIXADDR_TOP = 0xfffff000; | 147 | unsigned long __FIXADDR_TOP = 0xfffff000; |
149 | EXPORT_SYMBOL(__FIXADDR_TOP); | 148 | EXPORT_SYMBOL(__FIXADDR_TOP); |
150 | #endif | ||
151 | 149 | ||
152 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | 150 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) |
153 | { | 151 | { |
@@ -173,12 +171,8 @@ void reserve_top_address(unsigned long reserve) | |||
173 | BUG_ON(fixmaps > 0); | 171 | BUG_ON(fixmaps > 0); |
174 | printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", | 172 | printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", |
175 | (int)-reserve); | 173 | (int)-reserve); |
176 | #ifdef CONFIG_COMPAT_VDSO | ||
177 | BUG_ON(reserve != 0); | ||
178 | #else | ||
179 | __FIXADDR_TOP = -reserve - PAGE_SIZE; | 174 | __FIXADDR_TOP = -reserve - PAGE_SIZE; |
180 | __VMALLOC_RESERVE += reserve; | 175 | __VMALLOC_RESERVE += reserve; |
181 | #endif | ||
182 | } | 176 | } |
183 | 177 | ||
184 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 178 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |