Commit 76480a6a authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Ingo Molnar

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: default avatarAndy Lutomirski <luto@kernel.org>
Reviewed-by: default avatarPaolo 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.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent cc1e24fd
...@@ -17,8 +17,10 @@ ...@@ -17,8 +17,10 @@
#include <asm/vvar.h> #include <asm/vvar.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/pvclock.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/kernel.h>
#define gtod (&VVAR(vsyscall_gtod_data)) #define gtod (&VVAR(vsyscall_gtod_data))
...@@ -43,10 +45,6 @@ extern u8 pvclock_page ...@@ -43,10 +45,6 @@ extern u8 pvclock_page
#ifndef BUILD_VDSO32 #ifndef BUILD_VDSO32
#include <linux/kernel.h>
#include <asm/vsyscall.h>
#include <asm/pvclock.h>
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{ {
long ret; long ret;
...@@ -64,8 +62,42 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) ...@@ -64,8 +62,42 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
return ret; return ret;
} }
#ifdef CONFIG_PARAVIRT_CLOCK
#else
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{
long ret;
asm(
"mov %%ebx, %%edx \n"
"mov %2, %%ebx \n"
"call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n"
: "=a" (ret)
: "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
: "memory", "edx");
return ret;
}
notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
{
long ret;
asm(
"mov %%ebx, %%edx \n"
"mov %2, %%ebx \n"
"call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n"
: "=a" (ret)
: "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
: "memory", "edx");
return ret;
}
#endif
#ifdef CONFIG_PARAVIRT_CLOCK
static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void) static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void)
{ {
return (const struct pvclock_vsyscall_time_info *)&pvclock_page; return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
...@@ -109,9 +141,9 @@ static notrace cycle_t vread_pvclock(int *mode) ...@@ -109,9 +141,9 @@ static notrace cycle_t vread_pvclock(int *mode)
do { do {
version = pvti->version; version = pvti->version;
/* This is also a read barrier, so we'll read version first. */ smp_rmb();
tsc = rdtsc_ordered();
tsc = rdtsc_ordered();
pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; pvti_tsc_to_system_mul = pvti->tsc_to_system_mul;
pvti_tsc_shift = pvti->tsc_shift; pvti_tsc_shift = pvti->tsc_shift;
pvti_system_time = pvti->system_time; pvti_system_time = pvti->system_time;
...@@ -126,7 +158,7 @@ static notrace cycle_t vread_pvclock(int *mode) ...@@ -126,7 +158,7 @@ static notrace cycle_t vread_pvclock(int *mode)
pvclock_scale_delta(delta, pvti_tsc_to_system_mul, pvclock_scale_delta(delta, pvti_tsc_to_system_mul,
pvti_tsc_shift); pvti_tsc_shift);
/* refer to tsc.c read_tsc() comment for rationale */ /* refer to vread_tsc() comment for rationale */
last = gtod->cycle_last; last = gtod->cycle_last;
if (likely(ret >= last)) if (likely(ret >= last))
...@@ -136,49 +168,6 @@ static notrace cycle_t vread_pvclock(int *mode) ...@@ -136,49 +168,6 @@ static notrace cycle_t vread_pvclock(int *mode)
} }
#endif #endif
#else
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{
long ret;
asm(
"mov %%ebx, %%edx \n"
"mov %2, %%ebx \n"
"call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n"
: "=a" (ret)
: "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
: "memory", "edx");
return ret;
}
notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
{
long ret;
asm(
"mov %%ebx, %%edx \n"
"mov %2, %%ebx \n"
"call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n"
: "=a" (ret)
: "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
: "memory", "edx");
return ret;
}
#ifdef CONFIG_PARAVIRT_CLOCK
static notrace cycle_t vread_pvclock(int *mode)
{
*mode = VCLOCK_NONE;
return 0;
}
#endif
#endif
notrace static cycle_t vread_tsc(void) notrace static cycle_t vread_tsc(void)
{ {
cycle_t ret = (cycle_t)rdtsc_ordered(); cycle_t ret = (cycle_t)rdtsc_ordered();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment