From ea0a281d7a7e2595cb3dd13ccff7005ad9f00b44 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Mon, 23 May 2011 09:31:30 -0400 Subject: [PATCH] --- yaml --- r: 251984 b: refs/heads/master c: f144a6b4d1688675d88990e29567b2335b48205e h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/x86/vdso/vclock_gettime.c | 35 +++++++++++++++++++++++++++- trunk/arch/x86/vdso/vdso.lds.S | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 5bb20412fbfa..ae7554b1cfbd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6447facba36e3fff77ab4c68f46297a5dab024c8 +refs/heads/master: f144a6b4d1688675d88990e29567b2335b48205e diff --git a/trunk/arch/x86/vdso/vclock_gettime.c b/trunk/arch/x86/vdso/vclock_gettime.c index 28b2c00bd1be..e6e9f90a8cd7 100644 --- a/trunk/arch/x86/vdso/vclock_gettime.c +++ b/trunk/arch/x86/vdso/vclock_gettime.c @@ -2,7 +2,7 @@ * Copyright 2006 Andi Kleen, SUSE Labs. * Subject to the GNU Public License, v.2 * - * Fast user context implementation of clock_gettime and gettimeofday. + * Fast user context implementation of clock_gettime, gettimeofday, and time. * * The code should have no internal unresolved relocations. * Check with readelf after changing. @@ -160,3 +160,36 @@ notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) } int gettimeofday(struct timeval *, struct timezone *) __attribute__((weak, alias("__vdso_gettimeofday"))); + +/* This will break when the xtime seconds get inaccurate, but that is + * unlikely */ + +static __always_inline long time_syscall(long *t) +{ + long secs; + asm volatile("syscall" + : "=a" (secs) + : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); + return secs; +} + +notrace time_t __vdso_time(time_t *t) +{ + unsigned seq; + time_t result; + if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled)) + return time_syscall(t); + + do { + seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock); + + result = VVAR(vsyscall_gtod_data).wall_time_sec; + + } while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq)); + + if (t) + *t = result; + return result; +} +int time(time_t *t) + __attribute__((weak, alias("__vdso_time"))); diff --git a/trunk/arch/x86/vdso/vdso.lds.S b/trunk/arch/x86/vdso/vdso.lds.S index 81f250011f71..b96b2677cad8 100644 --- a/trunk/arch/x86/vdso/vdso.lds.S +++ b/trunk/arch/x86/vdso/vdso.lds.S @@ -23,6 +23,8 @@ VERSION { __vdso_gettimeofday; getcpu; __vdso_getcpu; + time; + __vdso_time; local: *; }; }