diff options
Diffstat (limited to 'arch/x86/vdso/vdso32-setup.c')
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index cf058fecfcee..513f330c5832 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c | |||
@@ -193,30 +193,16 @@ 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 | static int use_sysenter __read_mostly = -1; | 200 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32)) |
207 | 201 | #define vdso32_syscall() (boot_cpu_has(X86_FEATURE_SYSCALL32)) | |
208 | #define vdso32_sysenter() (use_sysenter > 0) | ||
209 | 202 | ||
210 | /* May not be __init: called during resume */ | 203 | /* May not be __init: called during resume */ |
211 | void syscall32_cpu_init(void) | 204 | void syscall32_cpu_init(void) |
212 | { | 205 | { |
213 | if (use_sysenter < 0) { | ||
214 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
215 | use_sysenter = 1; | ||
216 | if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) | ||
217 | use_sysenter = 1; | ||
218 | } | ||
219 | |||
220 | /* Load these always in case some future AMD CPU supports | 206 | /* Load these always in case some future AMD CPU supports |
221 | SYSENTER from compat mode too. */ | 207 | SYSENTER from compat mode too. */ |
222 | checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); | 208 | checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
@@ -235,6 +221,7 @@ static inline void map_compat_vdso(int map) | |||
235 | #else /* CONFIG_X86_32 */ | 221 | #else /* CONFIG_X86_32 */ |
236 | 222 | ||
237 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP)) | 223 | #define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP)) |
224 | #define vdso32_syscall() (0) | ||
238 | 225 | ||
239 | void enable_sep_cpu(void) | 226 | void enable_sep_cpu(void) |
240 | { | 227 | { |
@@ -305,12 +292,15 @@ int __init sysenter_setup(void) | |||
305 | gate_vma_init(); | 292 | gate_vma_init(); |
306 | #endif | 293 | #endif |
307 | 294 | ||
308 | if (!vdso32_sysenter()) { | 295 | if (vdso32_syscall()) { |
309 | vsyscall = &vdso32_default_start; | 296 | vsyscall = &vdso32_syscall_start; |
310 | vsyscall_len = &vdso32_default_end - &vdso32_default_start; | 297 | vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start; |
311 | } else { | 298 | } else if (vdso32_sysenter()){ |
312 | vsyscall = &vdso32_sysenter_start; | 299 | vsyscall = &vdso32_sysenter_start; |
313 | 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; | ||
314 | } | 304 | } |
315 | 305 | ||
316 | memcpy(syscall_page, vsyscall, vsyscall_len); | 306 | memcpy(syscall_page, vsyscall, vsyscall_len); |