aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2015-12-10 22:20:22 -0500
committerIngo Molnar <mingo@kernel.org>2015-12-11 02:56:03 -0500
commit76480a6a55a03d0fe5dd6290ccde7f78678ab85e (patch)
tree6b6c906a163801f306beb9cadb71c3a28bda61a9
parentcc1e24fdb064d3126a494716f22ad4fc39306742 (diff)
x86/vdso: Enable vdso pvclock access on all vdso variants
Now that pvclock doesn't require access to the fixmap, all vdso variants can use it. The kernel side isn't wired up for 32-bit kernels yet, but this covers 32-bit and x32 userspace on 64-bit kernels. Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/a7ef693b7a4c88dd2173dc1d4bf6bc27023626eb.1449702533.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c91
1 files changed, 40 insertions, 51 deletions
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index 59a98c25bde7..8602f06c759f 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -17,8 +17,10 @@
17#include <asm/vvar.h> 17#include <asm/vvar.h>
18#include <asm/unistd.h> 18#include <asm/unistd.h>
19#include <asm/msr.h> 19#include <asm/msr.h>
20#include <asm/pvclock.h>
20#include <linux/math64.h> 21#include <linux/math64.h>
21#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/kernel.h>
22 24
23#define gtod (&VVAR(vsyscall_gtod_data)) 25#define gtod (&VVAR(vsyscall_gtod_data))
24 26
@@ -43,10 +45,6 @@ extern u8 pvclock_page
43 45
44#ifndef BUILD_VDSO32 46#ifndef BUILD_VDSO32
45 47
46#include <linux/kernel.h>
47#include <asm/vsyscall.h>
48#include <asm/pvclock.h>
49
50notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) 48notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
51{ 49{
52 long ret; 50 long ret;
@@ -64,8 +62,42 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
64 return ret; 62 return ret;
65} 63}
66 64
67#ifdef CONFIG_PARAVIRT_CLOCK
68 65
66#else
67
68notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
69{
70 long ret;
71
72 asm(
73 "mov %%ebx, %%edx \n"
74 "mov %2, %%ebx \n"
75 "call __kernel_vsyscall \n"
76 "mov %%edx, %%ebx \n"
77 : "=a" (ret)
78 : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
79 : "memory", "edx");
80 return ret;
81}
82
83notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
84{
85 long ret;
86
87 asm(
88 "mov %%ebx, %%edx \n"
89 "mov %2, %%ebx \n"
90 "call __kernel_vsyscall \n"
91 "mov %%edx, %%ebx \n"
92 : "=a" (ret)
93 : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
94 : "memory", "edx");
95 return ret;
96}
97
98#endif
99
100#ifdef CONFIG_PARAVIRT_CLOCK
69static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void) 101static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void)
70{ 102{
71 return (const struct pvclock_vsyscall_time_info *)&pvclock_page; 103 return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
@@ -109,9 +141,9 @@ static notrace cycle_t vread_pvclock(int *mode)
109 do { 141 do {
110 version = pvti->version; 142 version = pvti->version;
111 143
112 /* This is also a read barrier, so we'll read version first. */ 144 smp_rmb();
113 tsc = rdtsc_ordered();
114 145
146 tsc = rdtsc_ordered();
115 pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; 147 pvti_tsc_to_system_mul = pvti->tsc_to_system_mul;
116 pvti_tsc_shift = pvti->tsc_shift; 148 pvti_tsc_shift = pvti->tsc_shift;
117 pvti_system_time = pvti->system_time; 149 pvti_system_time = pvti->system_time;
@@ -126,7 +158,7 @@ static notrace cycle_t vread_pvclock(int *mode)
126 pvclock_scale_delta(delta, pvti_tsc_to_system_mul, 158 pvclock_scale_delta(delta, pvti_tsc_to_system_mul,
127 pvti_tsc_shift); 159 pvti_tsc_shift);
128 160
129 /* refer to tsc.c read_tsc() comment for rationale */ 161 /* refer to vread_tsc() comment for rationale */
130 last = gtod->cycle_last; 162 last = gtod->cycle_last;
131 163
132 if (likely(ret >= last)) 164 if (likely(ret >= last))
@@ -136,49 +168,6 @@ static notrace cycle_t vread_pvclock(int *mode)
136} 168}
137#endif 169#endif
138 170
139#else
140
141notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
142{
143 long ret;
144
145 asm(
146 "mov %%ebx, %%edx \n"
147 "mov %2, %%ebx \n"
148 "call __kernel_vsyscall \n"
149 "mov %%edx, %%ebx \n"
150 : "=a" (ret)
151 : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
152 : "memory", "edx");
153 return ret;
154}
155
156notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
157{
158 long ret;
159
160 asm(
161 "mov %%ebx, %%edx \n"
162 "mov %2, %%ebx \n"
163 "call __kernel_vsyscall \n"
164 "mov %%edx, %%ebx \n"
165 : "=a" (ret)
166 : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
167 : "memory", "edx");
168 return ret;
169}
170
171#ifdef CONFIG_PARAVIRT_CLOCK
172
173static notrace cycle_t vread_pvclock(int *mode)
174{
175 *mode = VCLOCK_NONE;
176 return 0;
177}
178#endif
179
180#endif
181
182notrace static cycle_t vread_tsc(void) 171notrace static cycle_t vread_tsc(void)
183{ 172{
184 cycle_t ret = (cycle_t)rdtsc_ordered(); 173 cycle_t ret = (cycle_t)rdtsc_ordered();