Skip to content

Commit 30500cc

Browse files
amlutogregkh
authored andcommitted
x86/vdso: Fix asm constraints on vDSO syscall fallbacks
commit 715bd9d upstream. 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: 2aae950 ("x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu") Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/2c0231690551989d2fafa60ed0e7b5cc8b403908.1538422295.git.luto@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 71a0556 commit 30500cc

1 file changed

Lines changed: 10 additions & 8 deletions

File tree

arch/x86/entry/vdso/vclock_gettime.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,19 @@ extern u8 hvclock_page
4343
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
4444
{
4545
long ret;
46-
asm("syscall" : "=a" (ret) :
47-
"0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory");
46+
asm ("syscall" : "=a" (ret), "=m" (*ts) :
47+
"0" (__NR_clock_gettime), "D" (clock), "S" (ts) :
48+
"memory", "rcx", "r11");
4849
return ret;
4950
}
5051

5152
notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
5253
{
5354
long ret;
5455

55-
asm("syscall" : "=a" (ret) :
56-
"0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
56+
asm ("syscall" : "=a" (ret), "=m" (*tv), "=m" (*tz) :
57+
"0" (__NR_gettimeofday), "D" (tv), "S" (tz) :
58+
"memory", "rcx", "r11");
5759
return ret;
5860
}
5961

@@ -64,12 +66,12 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
6466
{
6567
long ret;
6668

67-
asm(
69+
asm (
6870
"mov %%ebx, %%edx \n"
6971
"mov %2, %%ebx \n"
7072
"call __kernel_vsyscall \n"
7173
"mov %%edx, %%ebx \n"
72-
: "=a" (ret)
74+
: "=a" (ret), "=m" (*ts)
7375
: "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
7476
: "memory", "edx");
7577
return ret;
@@ -79,12 +81,12 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
7981
{
8082
long ret;
8183

82-
asm(
84+
asm (
8385
"mov %%ebx, %%edx \n"
8486
"mov %2, %%ebx \n"
8587
"call __kernel_vsyscall \n"
8688
"mov %%edx, %%ebx \n"
87-
: "=a" (ret)
89+
: "=a" (ret), "=m" (*tv), "=m" (*tz)
8890
: "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
8991
: "memory", "edx");
9092
return ret;

0 commit comments

Comments
 (0)