diff options
-rw-r--r-- | arch/x86/entry/vdso/vclock_gettime.c | 91 |
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 | |||
50 | notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) | 48 | notrace 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 | |||
68 | notrace 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 | |||
83 | notrace 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 | ||
69 | static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void) | 101 | static 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 | |||
141 | notrace 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 | |||
156 | notrace 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 | |||
173 | static notrace cycle_t vread_pvclock(int *mode) | ||
174 | { | ||
175 | *mode = VCLOCK_NONE; | ||
176 | return 0; | ||
177 | } | ||
178 | #endif | ||
179 | |||
180 | #endif | ||
181 | |||
182 | notrace static cycle_t vread_tsc(void) | 171 | notrace static cycle_t vread_tsc(void) |
183 | { | 172 | { |
184 | cycle_t ret = (cycle_t)rdtsc_ordered(); | 173 | cycle_t ret = (cycle_t)rdtsc_ordered(); |