Commit 715bd9d1 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Thomas Gleixner

x86/vdso: Fix asm constraints on vDSO syscall fallbacks

The syscall fallbacks in the vDSO have incorrect asm constraints.
They are not marked as writing to their outputs -- instead, they are
marked as clobbering "memory", which is useless.  In particular, gcc
is smart enough to know that the timespec parameter hasn't escaped,
so a memory clobber doesn't clobber it.  And passing a pointer as an
asm *input* does not tell gcc that the pointed-to value is changed.

Add in the fact that the asm instructions weren't volatile, and gcc
was free to omit them entirely unless their sole output (the return
value) is used.  Which it is (phew!), but that stops happening with
some upcoming patches.

As a trivial example, the following code:

void test_fallback(struct timespec *ts)
{
	vdso_fallback_gettime(CLOCK_MONOTONIC, ts);
}

compiles to:

00000000000000c0 <test_fallback>:
  c0:   c3                      retq

To add insult to injury, the RCX and R11 clobbers on 64-bit
builds were missing.

The "memory" clobber is also unnecessary -- no ordering with respect to
other memory operations is needed, but that's going to be fixed in a
separate not-for-stable patch.

Fixes: 2aae950b ("x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu")
Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/2c0231690551989d2fafa60ed0e7b5cc8b403908.1538422295.git.luto@kernel.org
parent 17b57b18
...@@ -43,8 +43,9 @@ extern u8 hvclock_page ...@@ -43,8 +43,9 @@ extern u8 hvclock_page
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;
asm("syscall" : "=a" (ret) : asm ("syscall" : "=a" (ret), "=m" (*ts) :
"0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); "0" (__NR_clock_gettime), "D" (clock), "S" (ts) :
"memory", "rcx", "r11");
return ret; return ret;
} }
...@@ -52,8 +53,9 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) ...@@ -52,8 +53,9 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
{ {
long ret; long ret;
asm("syscall" : "=a" (ret) : asm ("syscall" : "=a" (ret), "=m" (*tv), "=m" (*tz) :
"0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); "0" (__NR_gettimeofday), "D" (tv), "S" (tz) :
"memory", "rcx", "r11");
return ret; return ret;
} }
...@@ -64,12 +66,12 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) ...@@ -64,12 +66,12 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{ {
long ret; long ret;
asm( asm (
"mov %%ebx, %%edx \n" "mov %%ebx, %%edx \n"
"mov %2, %%ebx \n" "mov %2, %%ebx \n"
"call __kernel_vsyscall \n" "call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n" "mov %%edx, %%ebx \n"
: "=a" (ret) : "=a" (ret), "=m" (*ts)
: "0" (__NR_clock_gettime), "g" (clock), "c" (ts) : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
: "memory", "edx"); : "memory", "edx");
return ret; return ret;
...@@ -79,12 +81,12 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) ...@@ -79,12 +81,12 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
{ {
long ret; long ret;
asm( asm (
"mov %%ebx, %%edx \n" "mov %%ebx, %%edx \n"
"mov %2, %%ebx \n" "mov %2, %%ebx \n"
"call __kernel_vsyscall \n" "call __kernel_vsyscall \n"
"mov %%edx, %%ebx \n" "mov %%edx, %%ebx \n"
: "=a" (ret) : "=a" (ret), "=m" (*tv), "=m" (*tz)
: "0" (__NR_gettimeofday), "g" (tv), "c" (tz) : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
: "memory", "edx"); : "memory", "edx");
return ret; return ret;
......
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