diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/vdso/vclock_gettime.c | 35 | ||||
-rw-r--r-- | arch/x86/vdso/vdso.lds.S | 2 |
2 files changed, 36 insertions, 1 deletions
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index 28b2c00bd1be..e6e9f90a8cd7 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Copyright 2006 Andi Kleen, SUSE Labs. | 2 | * Copyright 2006 Andi Kleen, SUSE Labs. |
3 | * Subject to the GNU Public License, v.2 | 3 | * Subject to the GNU Public License, v.2 |
4 | * | 4 | * |
5 | * Fast user context implementation of clock_gettime and gettimeofday. | 5 | * Fast user context implementation of clock_gettime, gettimeofday, and time. |
6 | * | 6 | * |
7 | * The code should have no internal unresolved relocations. | 7 | * The code should have no internal unresolved relocations. |
8 | * Check with readelf after changing. | 8 | * Check with readelf after changing. |
@@ -160,3 +160,36 @@ notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) | |||
160 | } | 160 | } |
161 | int gettimeofday(struct timeval *, struct timezone *) | 161 | int gettimeofday(struct timeval *, struct timezone *) |
162 | __attribute__((weak, alias("__vdso_gettimeofday"))); | 162 | __attribute__((weak, alias("__vdso_gettimeofday"))); |
163 | |||
164 | /* This will break when the xtime seconds get inaccurate, but that is | ||
165 | * unlikely */ | ||
166 | |||
167 | static __always_inline long time_syscall(long *t) | ||
168 | { | ||
169 | long secs; | ||
170 | asm volatile("syscall" | ||
171 | : "=a" (secs) | ||
172 | : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); | ||
173 | return secs; | ||
174 | } | ||
175 | |||
176 | notrace time_t __vdso_time(time_t *t) | ||
177 | { | ||
178 | unsigned seq; | ||
179 | time_t result; | ||
180 | if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled)) | ||
181 | return time_syscall(t); | ||
182 | |||
183 | do { | ||
184 | seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock); | ||
185 | |||
186 | result = VVAR(vsyscall_gtod_data).wall_time_sec; | ||
187 | |||
188 | } while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq)); | ||
189 | |||
190 | if (t) | ||
191 | *t = result; | ||
192 | return result; | ||
193 | } | ||
194 | int time(time_t *t) | ||
195 | __attribute__((weak, alias("__vdso_time"))); | ||
diff --git a/arch/x86/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S index 81f250011f71..b96b2677cad8 100644 --- a/arch/x86/vdso/vdso.lds.S +++ b/arch/x86/vdso/vdso.lds.S | |||
@@ -23,6 +23,8 @@ VERSION { | |||
23 | __vdso_gettimeofday; | 23 | __vdso_gettimeofday; |
24 | getcpu; | 24 | getcpu; |
25 | __vdso_getcpu; | 25 | __vdso_getcpu; |
26 | time; | ||
27 | __vdso_time; | ||
26 | local: *; | 28 | local: *; |
27 | }; | 29 | }; |
28 | } | 30 | } |