diff options
-rw-r--r-- | arch/x86/kernel/cpu/amd_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common_64.c | 3 | ||||
-rw-r--r-- | arch/x86/vdso/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 19 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32.S | 13 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 10 | ||||
-rw-r--r-- | include/asm-x86/vdso.h | 8 |
7 files changed, 35 insertions, 22 deletions
diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c index 7c36fb8a28d..d1692b2a41f 100644 --- a/arch/x86/kernel/cpu/amd_64.c +++ b/arch/x86/kernel/cpu/amd_64.c | |||
@@ -115,6 +115,8 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | |||
115 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ | 115 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ |
116 | if (c->x86_power & (1<<8)) | 116 | if (c->x86_power & (1<<8)) |
117 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 117 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
118 | |||
119 | set_cpu_cap(c, X86_FEATURE_SYSCALL32); | ||
118 | } | 120 | } |
119 | 121 | ||
120 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 122 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index 15419cd3c5a..736f50fa433 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c | |||
@@ -317,9 +317,6 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) | |||
317 | c->x86_phys_bits = eax & 0xff; | 317 | c->x86_phys_bits = eax & 0xff; |
318 | } | 318 | } |
319 | 319 | ||
320 | /* Assume all 64-bit CPUs support 32-bit syscall */ | ||
321 | set_cpu_cap(c, X86_FEATURE_SYSCALL32); | ||
322 | |||
323 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && | 320 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && |
324 | cpu_devs[c->x86_vendor]->c_early_init) | 321 | cpu_devs[c->x86_vendor]->c_early_init) |
325 | cpu_devs[c->x86_vendor]->c_early_init(c); | 322 | cpu_devs[c->x86_vendor]->c_early_init(c); |
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index b7ad9f89d21..4d6ef0a336d 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile | |||
@@ -62,7 +62,7 @@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE | |||
62 | # Build multiple 32-bit vDSO images to choose from at boot time. | 62 | # Build multiple 32-bit vDSO images to choose from at boot time. |
63 | # | 63 | # |
64 | obj-$(VDSO32-y) += vdso32-syms.lds | 64 | obj-$(VDSO32-y) += vdso32-syms.lds |
65 | vdso32.so-$(CONFIG_X86_32) += int80 | 65 | vdso32.so-$(VDSO32-y) += int80 |
66 | vdso32.so-$(CONFIG_COMPAT) += syscall | 66 | vdso32.so-$(CONFIG_COMPAT) += syscall |
67 | vdso32.so-$(VDSO32-y) += sysenter | 67 | vdso32.so-$(VDSO32-y) += sysenter |
68 | 68 | ||
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 0bce5429a51..513f330c583 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); |
diff --git a/arch/x86/vdso/vdso32.S b/arch/x86/vdso/vdso32.S index 1e36f72cab8..2ce5f82c333 100644 --- a/arch/x86/vdso/vdso32.S +++ b/arch/x86/vdso/vdso32.S | |||
@@ -2,14 +2,17 @@ | |||
2 | 2 | ||
3 | __INITDATA | 3 | __INITDATA |
4 | 4 | ||
5 | .globl vdso32_default_start, vdso32_default_end | 5 | .globl vdso32_int80_start, vdso32_int80_end |
6 | vdso32_default_start: | 6 | vdso32_int80_start: |
7 | #ifdef CONFIG_X86_32 | ||
8 | .incbin "arch/x86/vdso/vdso32-int80.so" | 7 | .incbin "arch/x86/vdso/vdso32-int80.so" |
9 | #else | 8 | vdso32_int80_end: |
9 | |||
10 | .globl vdso32_syscall_start, vdso32_syscall_end | ||
11 | vdso32_syscall_start: | ||
12 | #ifdef CONFIG_COMPAT | ||
10 | .incbin "arch/x86/vdso/vdso32-syscall.so" | 13 | .incbin "arch/x86/vdso/vdso32-syscall.so" |
11 | #endif | 14 | #endif |
12 | vdso32_default_end: | 15 | vdso32_syscall_end: |
13 | 16 | ||
14 | .globl vdso32_sysenter_start, vdso32_sysenter_end | 17 | .globl vdso32_sysenter_start, vdso32_sysenter_end |
15 | vdso32_sysenter_start: | 18 | vdso32_sysenter_start: |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 3e11779755c..e3648e64a63 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -83,12 +83,16 @@ static void xen_idle(void) | |||
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Set the bit indicating "nosegneg" library variants should be used. | 85 | * Set the bit indicating "nosegneg" library variants should be used. |
86 | * We only need to bother in pure 32-bit mode; compat 32-bit processes | ||
87 | * can have un-truncated segments, so wrapping around is allowed. | ||
86 | */ | 88 | */ |
87 | static void __init fiddle_vdso(void) | 89 | static void __init fiddle_vdso(void) |
88 | { | 90 | { |
89 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) | 91 | #ifdef CONFIG_X86_32 |
90 | extern const char vdso32_default_start; | 92 | u32 *mask; |
91 | u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK); | 93 | mask = VDSO32_SYMBOL(&vdso32_int80_start, NOTE_MASK); |
94 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; | ||
95 | mask = VDSO32_SYMBOL(&vdso32_sysenter_start, NOTE_MASK); | ||
92 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; | 96 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; |
93 | #endif | 97 | #endif |
94 | } | 98 | } |
diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h index 86e085e003d..8e18fb80f5e 100644 --- a/include/asm-x86/vdso.h +++ b/include/asm-x86/vdso.h | |||
@@ -36,4 +36,12 @@ extern const char VDSO32_PRELINK[]; | |||
36 | extern void __user __kernel_sigreturn; | 36 | extern void __user __kernel_sigreturn; |
37 | extern void __user __kernel_rt_sigreturn; | 37 | extern void __user __kernel_rt_sigreturn; |
38 | 38 | ||
39 | /* | ||
40 | * These symbols are defined by vdso32.S to mark the bounds | ||
41 | * of the ELF DSO images included therein. | ||
42 | */ | ||
43 | extern const char vdso32_int80_start, vdso32_int80_end; | ||
44 | extern const char vdso32_syscall_start, vdso32_syscall_end; | ||
45 | extern const char vdso32_sysenter_start, vdso32_sysenter_end; | ||
46 | |||
39 | #endif /* asm-x86/vdso.h */ | 47 | #endif /* asm-x86/vdso.h */ |