diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-07-12 05:22:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-16 05:08:27 -0400 |
commit | 6a52e4b1cddd90fbfde8fb67021657936ee74b07 (patch) | |
tree | c876e1fafe89169f373f6b04739242b5d646fcf7 /arch/x86/vdso/vdso32-setup.c | |
parent | 71415c6a0877d5944d5dc3060f3b03513746158d (diff) |
x86_64: further cleanup of 32-bit compat syscall mechanisms
AMD only supports "syscall" from 32-bit compat usermode.
Intel and Centaur(?) only support "sysenter" from 32-bit compat usermode.
Set the X86 feature bits accordingly, and set up the vdso in
accordance with those bits. On the offchance we run on in a 64-bit
environment which supports neither syscall nor sysenter from 32-bit
mode, then fall back to the int $0x80 vdso.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/vdso/vdso32-setup.c')
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 0bce5429a515..513f330c5832 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c | |||
@@ -193,17 +193,12 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr) | |||
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | /* | ||
197 | * These symbols are defined by vdso32.S to mark the bounds | ||
198 | * of the ELF DSO images included therein. | ||
199 | */ | ||
200 | extern const char vdso32_default_start, vdso32_default_end; | ||
201 | extern const char vdso32_sysenter_start, vdso32_sysenter_end; | ||
202 | static struct page *vdso32_pages[1]; | 196 | static struct page *vdso32_pages[1]; |
203 | 197 | ||
204 | #ifdef CONFIG_X86_64 | 198 | #ifdef CONFIG_X86_64 |
205 | 199 | ||
206 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32)) | 200 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32)) |
201 | #define vdso32_syscall() (boot_cpu_has(X86_FEATURE_SYSCALL32)) | ||
207 | 202 | ||
208 | /* May not be __init: called during resume */ | 203 | /* May not be __init: called during resume */ |
209 | void syscall32_cpu_init(void) | 204 | void syscall32_cpu_init(void) |
@@ -226,6 +221,7 @@ static inline void map_compat_vdso(int map) | |||
226 | #else /* CONFIG_X86_32 */ | 221 | #else /* CONFIG_X86_32 */ |
227 | 222 | ||
228 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP)) | 223 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP)) |
224 | #define vdso32_syscall() (0) | ||
229 | 225 | ||
230 | void enable_sep_cpu(void) | 226 | void enable_sep_cpu(void) |
231 | { | 227 | { |
@@ -296,12 +292,15 @@ int __init sysenter_setup(void) | |||
296 | gate_vma_init(); | 292 | gate_vma_init(); |
297 | #endif | 293 | #endif |
298 | 294 | ||
299 | if (!vdso32_sysenter()) { | 295 | if (vdso32_syscall()) { |
300 | vsyscall = &vdso32_default_start; | 296 | vsyscall = &vdso32_syscall_start; |
301 | vsyscall_len = &vdso32_default_end - &vdso32_default_start; | 297 | vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start; |
302 | } else { | 298 | } else if (vdso32_sysenter()){ |
303 | vsyscall = &vdso32_sysenter_start; | 299 | vsyscall = &vdso32_sysenter_start; |
304 | vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start; | 300 | vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start; |
301 | } else { | ||
302 | vsyscall = &vdso32_int80_start; | ||
303 | vsyscall_len = &vdso32_int80_end - &vdso32_int80_start; | ||
305 | } | 304 | } |
306 | 305 | ||
307 | memcpy(syscall_page, vsyscall, vsyscall_len); | 306 | memcpy(syscall_page, vsyscall, vsyscall_len); |