diff options
Diffstat (limited to 'arch/x86/vdso')
-rw-r--r-- | arch/x86/vdso/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/vdso/vclock_gettime.c | 15 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 19 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32.S | 13 | ||||
-rw-r--r-- | arch/x86/vdso/vgetcpu.c | 3 | ||||
-rw-r--r-- | arch/x86/vdso/vma.c | 11 |
6 files changed, 34 insertions, 29 deletions
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index b7ad9f89d21f..4d6ef0a336d6 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/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index efa2ba7c6005..1ef0f90813d6 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #define gtod vdso_vsyscall_gtod_data | 24 | #define gtod vdso_vsyscall_gtod_data |
25 | 25 | ||
26 | static long vdso_fallback_gettime(long clock, struct timespec *ts) | 26 | notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) |
27 | { | 27 | { |
28 | long ret; | 28 | long ret; |
29 | asm("syscall" : "=a" (ret) : | 29 | asm("syscall" : "=a" (ret) : |
@@ -31,7 +31,7 @@ static long vdso_fallback_gettime(long clock, struct timespec *ts) | |||
31 | return ret; | 31 | return ret; |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline long vgetns(void) | 34 | notrace static inline long vgetns(void) |
35 | { | 35 | { |
36 | long v; | 36 | long v; |
37 | cycles_t (*vread)(void); | 37 | cycles_t (*vread)(void); |
@@ -40,7 +40,7 @@ static inline long vgetns(void) | |||
40 | return (v * gtod->clock.mult) >> gtod->clock.shift; | 40 | return (v * gtod->clock.mult) >> gtod->clock.shift; |
41 | } | 41 | } |
42 | 42 | ||
43 | static noinline int do_realtime(struct timespec *ts) | 43 | notrace static noinline int do_realtime(struct timespec *ts) |
44 | { | 44 | { |
45 | unsigned long seq, ns; | 45 | unsigned long seq, ns; |
46 | do { | 46 | do { |
@@ -54,7 +54,8 @@ static noinline int do_realtime(struct timespec *ts) | |||
54 | } | 54 | } |
55 | 55 | ||
56 | /* Copy of the version in kernel/time.c which we cannot directly access */ | 56 | /* Copy of the version in kernel/time.c which we cannot directly access */ |
57 | static void vset_normalized_timespec(struct timespec *ts, long sec, long nsec) | 57 | notrace static void |
58 | vset_normalized_timespec(struct timespec *ts, long sec, long nsec) | ||
58 | { | 59 | { |
59 | while (nsec >= NSEC_PER_SEC) { | 60 | while (nsec >= NSEC_PER_SEC) { |
60 | nsec -= NSEC_PER_SEC; | 61 | nsec -= NSEC_PER_SEC; |
@@ -68,7 +69,7 @@ static void vset_normalized_timespec(struct timespec *ts, long sec, long nsec) | |||
68 | ts->tv_nsec = nsec; | 69 | ts->tv_nsec = nsec; |
69 | } | 70 | } |
70 | 71 | ||
71 | static noinline int do_monotonic(struct timespec *ts) | 72 | notrace static noinline int do_monotonic(struct timespec *ts) |
72 | { | 73 | { |
73 | unsigned long seq, ns, secs; | 74 | unsigned long seq, ns, secs; |
74 | do { | 75 | do { |
@@ -82,7 +83,7 @@ static noinline int do_monotonic(struct timespec *ts) | |||
82 | return 0; | 83 | return 0; |
83 | } | 84 | } |
84 | 85 | ||
85 | int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) | 86 | notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) |
86 | { | 87 | { |
87 | if (likely(gtod->sysctl_enabled && gtod->clock.vread)) | 88 | if (likely(gtod->sysctl_enabled && gtod->clock.vread)) |
88 | switch (clock) { | 89 | switch (clock) { |
@@ -96,7 +97,7 @@ int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) | |||
96 | int clock_gettime(clockid_t, struct timespec *) | 97 | int clock_gettime(clockid_t, struct timespec *) |
97 | __attribute__((weak, alias("__vdso_clock_gettime"))); | 98 | __attribute__((weak, alias("__vdso_clock_gettime"))); |
98 | 99 | ||
99 | int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) | 100 | notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) |
100 | { | 101 | { |
101 | long ret; | 102 | long ret; |
102 | if (likely(gtod->sysctl_enabled && gtod->clock.vread)) { | 103 | if (likely(gtod->sysctl_enabled && gtod->clock.vread)) { |
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); |
diff --git a/arch/x86/vdso/vdso32.S b/arch/x86/vdso/vdso32.S index 1e36f72cab86..2ce5f82c333b 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/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c index c8097f17f8a9..9fbc6b20026b 100644 --- a/arch/x86/vdso/vgetcpu.c +++ b/arch/x86/vdso/vgetcpu.c | |||
@@ -13,7 +13,8 @@ | |||
13 | #include <asm/vgtod.h> | 13 | #include <asm/vgtod.h> |
14 | #include "vextern.h" | 14 | #include "vextern.h" |
15 | 15 | ||
16 | long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) | 16 | notrace long |
17 | __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) | ||
17 | { | 18 | { |
18 | unsigned int p; | 19 | unsigned int p; |
19 | 20 | ||
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c index 19a6cfaf5db9..257ba4a10abf 100644 --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c | |||
@@ -21,7 +21,8 @@ unsigned int __read_mostly vdso_enabled = 1; | |||
21 | extern char vdso_start[], vdso_end[]; | 21 | extern char vdso_start[], vdso_end[]; |
22 | extern unsigned short vdso_sync_cpuid; | 22 | extern unsigned short vdso_sync_cpuid; |
23 | 23 | ||
24 | struct page **vdso_pages; | 24 | static struct page **vdso_pages; |
25 | static unsigned vdso_size; | ||
25 | 26 | ||
26 | static inline void *var_ref(void *p, char *name) | 27 | static inline void *var_ref(void *p, char *name) |
27 | { | 28 | { |
@@ -38,6 +39,7 @@ static int __init init_vdso_vars(void) | |||
38 | int i; | 39 | int i; |
39 | char *vbase; | 40 | char *vbase; |
40 | 41 | ||
42 | vdso_size = npages << PAGE_SHIFT; | ||
41 | vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL); | 43 | vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL); |
42 | if (!vdso_pages) | 44 | if (!vdso_pages) |
43 | goto oom; | 45 | goto oom; |
@@ -101,20 +103,19 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) | |||
101 | struct mm_struct *mm = current->mm; | 103 | struct mm_struct *mm = current->mm; |
102 | unsigned long addr; | 104 | unsigned long addr; |
103 | int ret; | 105 | int ret; |
104 | unsigned len = round_up(vdso_end - vdso_start, PAGE_SIZE); | ||
105 | 106 | ||
106 | if (!vdso_enabled) | 107 | if (!vdso_enabled) |
107 | return 0; | 108 | return 0; |
108 | 109 | ||
109 | down_write(&mm->mmap_sem); | 110 | down_write(&mm->mmap_sem); |
110 | addr = vdso_addr(mm->start_stack, len); | 111 | addr = vdso_addr(mm->start_stack, vdso_size); |
111 | addr = get_unmapped_area(NULL, addr, len, 0, 0); | 112 | addr = get_unmapped_area(NULL, addr, vdso_size, 0, 0); |
112 | if (IS_ERR_VALUE(addr)) { | 113 | if (IS_ERR_VALUE(addr)) { |
113 | ret = addr; | 114 | ret = addr; |
114 | goto up_fail; | 115 | goto up_fail; |
115 | } | 116 | } |
116 | 117 | ||
117 | ret = install_special_mapping(mm, addr, len, | 118 | ret = install_special_mapping(mm, addr, vdso_size, |
118 | VM_READ|VM_EXEC| | 119 | VM_READ|VM_EXEC| |
119 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| | 120 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| |
120 | VM_ALWAYSDUMP, | 121 | VM_ALWAYSDUMP, |