aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/vdso/vdso32-setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/vdso/vdso32-setup.c')
-rw-r--r--arch/x86/vdso/vdso32-setup.c30
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 */
200extern const char vdso32_default_start, vdso32_default_end;
201extern const char vdso32_sysenter_start, vdso32_sysenter_end;
202static struct page *vdso32_pages[1]; 196static struct page *vdso32_pages[1];
203 197
204#ifdef CONFIG_X86_64 198#ifdef CONFIG_X86_64
205 199
206static 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 */
211void syscall32_cpu_init(void) 204void 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
239void enable_sep_cpu(void) 226void 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);