1 From 715bd9d12f84d8f5cc8ad21d888f9bc304a8eb0b Mon Sep 17 00:00:00 2001
2 From: Andy Lutomirski <luto@kernel.org>
3 Date: Mon, 1 Oct 2018 12:52:15 -0700
4 Subject: x86/vdso: Fix asm constraints on vDSO syscall fallbacks
6 From: Andy Lutomirski <luto@kernel.org>
8 commit 715bd9d12f84d8f5cc8ad21d888f9bc304a8eb0b upstream.
10 The syscall fallbacks in the vDSO have incorrect asm constraints.
11 They are not marked as writing to their outputs -- instead, they are
12 marked as clobbering "memory", which is useless. In particular, gcc
13 is smart enough to know that the timespec parameter hasn't escaped,
14 so a memory clobber doesn't clobber it. And passing a pointer as an
15 asm *input* does not tell gcc that the pointed-to value is changed.
17 Add in the fact that the asm instructions weren't volatile, and gcc
18 was free to omit them entirely unless their sole output (the return
19 value) is used. Which it is (phew!), but that stops happening with
20 some upcoming patches.
22 As a trivial example, the following code:
24 void test_fallback(struct timespec *ts)
26 vdso_fallback_gettime(CLOCK_MONOTONIC, ts);
31 00000000000000c0 <test_fallback>:
34 To add insult to injury, the RCX and R11 clobbers on 64-bit
37 The "memory" clobber is also unnecessary -- no ordering with respect to
38 other memory operations is needed, but that's going to be fixed in a
39 separate not-for-stable patch.
41 Fixes: 2aae950b21e4 ("x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu")
42 Signed-off-by: Andy Lutomirski <luto@kernel.org>
43 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
44 Cc: stable@vger.kernel.org
45 Link: https://lkml.kernel.org/r/2c0231690551989d2fafa60ed0e7b5cc8b403908.1538422295.git.luto@kernel.org
46 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
49 arch/x86/entry/vdso/vclock_gettime.c | 18 ++++++++++--------
50 1 file changed, 10 insertions(+), 8 deletions(-)
52 --- a/arch/x86/entry/vdso/vclock_gettime.c
53 +++ b/arch/x86/entry/vdso/vclock_gettime.c
54 @@ -43,8 +43,9 @@ extern u8 hvclock_page
55 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
58 - asm("syscall" : "=a" (ret) :
59 - "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory");
60 + asm ("syscall" : "=a" (ret), "=m" (*ts) :
61 + "0" (__NR_clock_gettime), "D" (clock), "S" (ts) :
62 + "memory", "rcx", "r11");
66 @@ -52,8 +53,9 @@ notrace static long vdso_fallback_gtod(s
70 - asm("syscall" : "=a" (ret) :
71 - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
72 + asm ("syscall" : "=a" (ret), "=m" (*tv), "=m" (*tz) :
73 + "0" (__NR_gettimeofday), "D" (tv), "S" (tz) :
74 + "memory", "rcx", "r11");
78 @@ -64,12 +66,12 @@ notrace static long vdso_fallback_gettim
86 "call __kernel_vsyscall \n"
89 + : "=a" (ret), "=m" (*ts)
90 : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
93 @@ -79,12 +81,12 @@ notrace static long vdso_fallback_gtod(s
101 "call __kernel_vsyscall \n"
102 "mov %%edx, %%ebx \n"
104 + : "=a" (ret), "=m" (*tv), "=m" (*tz)
105 : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)