aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2017-09-20 17:24:33 -0400
committerIngo Molnar <mingo@kernel.org>2017-09-23 09:06:20 -0400
commitf5caf621ee357279e759c0911daf6d55c7d36f03 (patch)
tree429270fc4ccb2c9fe7881229640858c53dfca5e2
parent0d0970eef3b03ef08b19da5bc3044410731cf38f (diff)
x86/asm: Fix inline asm call constraints for Clang
For inline asm statements which have a CALL instruction, we list the stack pointer as a constraint to convince GCC to ensure the frame pointer is set up first: static inline void foo() { register void *__sp asm(_ASM_SP); asm("call bar" : "+r" (__sp)) } Unfortunately, that pattern causes Clang to corrupt the stack pointer. The fix is easy: convert the stack pointer register variable to a global variable. It should be noted that the end result is different based on the GCC version. With GCC 6.4, this patch has exactly the same result as before: defconfig defconfig-nofp distro distro-nofp before 9820389 9491555 8816046 8516940 after 9820389 9491555 8816046 8516940 With GCC 7.2, however, GCC's behavior has changed. It now changes its behavior based on the conversion of the register variable to a global. That somehow convinces it to *always* set up the frame pointer before inserting *any* inline asm. (Therefore, listing the variable as an output constraint is a no-op and is no longer necessary.) It's a bit overkill, but the performance impact should be negligible. And in fact, there's a nice improvement with frame pointers disabled: defconfig defconfig-nofp distro distro-nofp before 9796316 9468236 9076191 8790305 after 9796957 9464267 9076381 8785949 So in summary, while listing the stack pointer as an output constraint is no longer necessary for newer versions of GCC, it's still needed for older versions. Suggested-by: Andrey Ryabinin <aryabinin@virtuozzo.com> Reported-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Miguel Bernal Marin <miguel.bernal.marin@linux.intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/3db862e970c432ae823cf515c52b54fec8270e0e.1505942196.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/alternative.h3
-rw-r--r--arch/x86/include/asm/asm.h11
-rw-r--r--arch/x86/include/asm/mshyperv.h10
-rw-r--r--arch/x86/include/asm/paravirt_types.h14
-rw-r--r--arch/x86/include/asm/preempt.h15
-rw-r--r--arch/x86/include/asm/processor.h6
-rw-r--r--arch/x86/include/asm/rwsem.h4
-rw-r--r--arch/x86/include/asm/uaccess.h4
-rw-r--r--arch/x86/include/asm/xen/hypercall.h5
-rw-r--r--arch/x86/kvm/emulate.c3
-rw-r--r--arch/x86/kvm/vmx.c3
-rw-r--r--arch/x86/mm/fault.c3
-rw-r--r--tools/objtool/Documentation/stack-validation.txt6
13 files changed, 42 insertions, 45 deletions
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 1b020381ab38..c096624137ae 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -218,10 +218,9 @@ static inline int alternatives_text_reserved(void *start, void *end)
218#define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ 218#define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \
219 output, input...) \ 219 output, input...) \
220{ \ 220{ \
221 register void *__sp asm(_ASM_SP); \
222 asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ 221 asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\
223 "call %P[new2]", feature2) \ 222 "call %P[new2]", feature2) \
224 : output, "+r" (__sp) \ 223 : output, ASM_CALL_CONSTRAINT \
225 : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ 224 : [old] "i" (oldfunc), [new1] "i" (newfunc1), \
226 [new2] "i" (newfunc2), ## input); \ 225 [new2] "i" (newfunc2), ## input); \
227} 226}
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 676ee5807d86..c1eadbaf1115 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -132,4 +132,15 @@
132/* For C file, we already have NOKPROBE_SYMBOL macro */ 132/* For C file, we already have NOKPROBE_SYMBOL macro */
133#endif 133#endif
134 134
135#ifndef __ASSEMBLY__
136/*
137 * This output constraint should be used for any inline asm which has a "call"
138 * instruction. Otherwise the asm may be inserted before the frame pointer
139 * gets set up by the containing function. If you forget to do this, objtool
140 * may print a "call without frame pointer save/setup" warning.
141 */
142register unsigned int __asm_call_sp asm("esp");
143#define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp)
144#endif
145
135#endif /* _ASM_X86_ASM_H */ 146#endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 63cc96f064dc..738503e1f80c 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -179,7 +179,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
179 u64 input_address = input ? virt_to_phys(input) : 0; 179 u64 input_address = input ? virt_to_phys(input) : 0;
180 u64 output_address = output ? virt_to_phys(output) : 0; 180 u64 output_address = output ? virt_to_phys(output) : 0;
181 u64 hv_status; 181 u64 hv_status;
182 register void *__sp asm(_ASM_SP);
183 182
184#ifdef CONFIG_X86_64 183#ifdef CONFIG_X86_64
185 if (!hv_hypercall_pg) 184 if (!hv_hypercall_pg)
@@ -187,7 +186,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
187 186
188 __asm__ __volatile__("mov %4, %%r8\n" 187 __asm__ __volatile__("mov %4, %%r8\n"
189 "call *%5" 188 "call *%5"
190 : "=a" (hv_status), "+r" (__sp), 189 : "=a" (hv_status), ASM_CALL_CONSTRAINT,
191 "+c" (control), "+d" (input_address) 190 "+c" (control), "+d" (input_address)
192 : "r" (output_address), "m" (hv_hypercall_pg) 191 : "r" (output_address), "m" (hv_hypercall_pg)
193 : "cc", "memory", "r8", "r9", "r10", "r11"); 192 : "cc", "memory", "r8", "r9", "r10", "r11");
@@ -202,7 +201,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
202 201
203 __asm__ __volatile__("call *%7" 202 __asm__ __volatile__("call *%7"
204 : "=A" (hv_status), 203 : "=A" (hv_status),
205 "+c" (input_address_lo), "+r" (__sp) 204 "+c" (input_address_lo), ASM_CALL_CONSTRAINT
206 : "A" (control), 205 : "A" (control),
207 "b" (input_address_hi), 206 "b" (input_address_hi),
208 "D"(output_address_hi), "S"(output_address_lo), 207 "D"(output_address_hi), "S"(output_address_lo),
@@ -224,12 +223,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
224static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) 223static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
225{ 224{
226 u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; 225 u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
227 register void *__sp asm(_ASM_SP);
228 226
229#ifdef CONFIG_X86_64 227#ifdef CONFIG_X86_64
230 { 228 {
231 __asm__ __volatile__("call *%4" 229 __asm__ __volatile__("call *%4"
232 : "=a" (hv_status), "+r" (__sp), 230 : "=a" (hv_status), ASM_CALL_CONSTRAINT,
233 "+c" (control), "+d" (input1) 231 "+c" (control), "+d" (input1)
234 : "m" (hv_hypercall_pg) 232 : "m" (hv_hypercall_pg)
235 : "cc", "r8", "r9", "r10", "r11"); 233 : "cc", "r8", "r9", "r10", "r11");
@@ -242,7 +240,7 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
242 __asm__ __volatile__ ("call *%5" 240 __asm__ __volatile__ ("call *%5"
243 : "=A"(hv_status), 241 : "=A"(hv_status),
244 "+c"(input1_lo), 242 "+c"(input1_lo),
245 "+r"(__sp) 243 ASM_CALL_CONSTRAINT
246 : "A" (control), 244 : "A" (control),
247 "b" (input1_hi), 245 "b" (input1_hi),
248 "m" (hv_hypercall_pg) 246 "m" (hv_hypercall_pg)
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 42873edd9f9d..280d94c36dad 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -459,8 +459,8 @@ int paravirt_disable_iospace(void);
459 */ 459 */
460#ifdef CONFIG_X86_32 460#ifdef CONFIG_X86_32
461#define PVOP_VCALL_ARGS \ 461#define PVOP_VCALL_ARGS \
462 unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ 462 unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx;
463 register void *__sp asm("esp") 463
464#define PVOP_CALL_ARGS PVOP_VCALL_ARGS 464#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
465 465
466#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) 466#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x))
@@ -480,8 +480,8 @@ int paravirt_disable_iospace(void);
480/* [re]ax isn't an arg, but the return val */ 480/* [re]ax isn't an arg, but the return val */
481#define PVOP_VCALL_ARGS \ 481#define PVOP_VCALL_ARGS \
482 unsigned long __edi = __edi, __esi = __esi, \ 482 unsigned long __edi = __edi, __esi = __esi, \
483 __edx = __edx, __ecx = __ecx, __eax = __eax; \ 483 __edx = __edx, __ecx = __ecx, __eax = __eax;
484 register void *__sp asm("rsp") 484
485#define PVOP_CALL_ARGS PVOP_VCALL_ARGS 485#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
486 486
487#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) 487#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
@@ -532,7 +532,7 @@ int paravirt_disable_iospace(void);
532 asm volatile(pre \ 532 asm volatile(pre \
533 paravirt_alt(PARAVIRT_CALL) \ 533 paravirt_alt(PARAVIRT_CALL) \
534 post \ 534 post \
535 : call_clbr, "+r" (__sp) \ 535 : call_clbr, ASM_CALL_CONSTRAINT \
536 : paravirt_type(op), \ 536 : paravirt_type(op), \
537 paravirt_clobber(clbr), \ 537 paravirt_clobber(clbr), \
538 ##__VA_ARGS__ \ 538 ##__VA_ARGS__ \
@@ -542,7 +542,7 @@ int paravirt_disable_iospace(void);
542 asm volatile(pre \ 542 asm volatile(pre \
543 paravirt_alt(PARAVIRT_CALL) \ 543 paravirt_alt(PARAVIRT_CALL) \
544 post \ 544 post \
545 : call_clbr, "+r" (__sp) \ 545 : call_clbr, ASM_CALL_CONSTRAINT \
546 : paravirt_type(op), \ 546 : paravirt_type(op), \
547 paravirt_clobber(clbr), \ 547 paravirt_clobber(clbr), \
548 ##__VA_ARGS__ \ 548 ##__VA_ARGS__ \
@@ -569,7 +569,7 @@ int paravirt_disable_iospace(void);
569 asm volatile(pre \ 569 asm volatile(pre \
570 paravirt_alt(PARAVIRT_CALL) \ 570 paravirt_alt(PARAVIRT_CALL) \
571 post \ 571 post \
572 : call_clbr, "+r" (__sp) \ 572 : call_clbr, ASM_CALL_CONSTRAINT \
573 : paravirt_type(op), \ 573 : paravirt_type(op), \
574 paravirt_clobber(clbr), \ 574 paravirt_clobber(clbr), \
575 ##__VA_ARGS__ \ 575 ##__VA_ARGS__ \
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index ec1f3c651150..4f44505dbf87 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -100,19 +100,14 @@ static __always_inline bool should_resched(int preempt_offset)
100 100
101#ifdef CONFIG_PREEMPT 101#ifdef CONFIG_PREEMPT
102 extern asmlinkage void ___preempt_schedule(void); 102 extern asmlinkage void ___preempt_schedule(void);
103# define __preempt_schedule() \ 103# define __preempt_schedule() \
104({ \ 104 asm volatile ("call ___preempt_schedule" : ASM_CALL_CONSTRAINT)
105 register void *__sp asm(_ASM_SP); \
106 asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \
107})
108 105
109 extern asmlinkage void preempt_schedule(void); 106 extern asmlinkage void preempt_schedule(void);
110 extern asmlinkage void ___preempt_schedule_notrace(void); 107 extern asmlinkage void ___preempt_schedule_notrace(void);
111# define __preempt_schedule_notrace() \ 108# define __preempt_schedule_notrace() \
112({ \ 109 asm volatile ("call ___preempt_schedule_notrace" : ASM_CALL_CONSTRAINT)
113 register void *__sp asm(_ASM_SP); \ 110
114 asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \
115})
116 extern asmlinkage void preempt_schedule_notrace(void); 111 extern asmlinkage void preempt_schedule_notrace(void);
117#endif 112#endif
118 113
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 3fa26a61eabc..b390ff76e58f 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -677,8 +677,6 @@ static inline void sync_core(void)
677 * Like all of Linux's memory ordering operations, this is a 677 * Like all of Linux's memory ordering operations, this is a
678 * compiler barrier as well. 678 * compiler barrier as well.
679 */ 679 */
680 register void *__sp asm(_ASM_SP);
681
682#ifdef CONFIG_X86_32 680#ifdef CONFIG_X86_32
683 asm volatile ( 681 asm volatile (
684 "pushfl\n\t" 682 "pushfl\n\t"
@@ -686,7 +684,7 @@ static inline void sync_core(void)
686 "pushl $1f\n\t" 684 "pushl $1f\n\t"
687 "iret\n\t" 685 "iret\n\t"
688 "1:" 686 "1:"
689 : "+r" (__sp) : : "memory"); 687 : ASM_CALL_CONSTRAINT : : "memory");
690#else 688#else
691 unsigned int tmp; 689 unsigned int tmp;
692 690
@@ -703,7 +701,7 @@ static inline void sync_core(void)
703 "iretq\n\t" 701 "iretq\n\t"
704 UNWIND_HINT_RESTORE 702 UNWIND_HINT_RESTORE
705 "1:" 703 "1:"
706 : "=&r" (tmp), "+r" (__sp) : : "cc", "memory"); 704 : "=&r" (tmp), ASM_CALL_CONSTRAINT : : "cc", "memory");
707#endif 705#endif
708} 706}
709 707
diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h
index a34e0d4b957d..7116b7931c7b 100644
--- a/arch/x86/include/asm/rwsem.h
+++ b/arch/x86/include/asm/rwsem.h
@@ -103,7 +103,6 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem)
103({ \ 103({ \
104 long tmp; \ 104 long tmp; \
105 struct rw_semaphore* ret; \ 105 struct rw_semaphore* ret; \
106 register void *__sp asm(_ASM_SP); \
107 \ 106 \
108 asm volatile("# beginning down_write\n\t" \ 107 asm volatile("# beginning down_write\n\t" \
109 LOCK_PREFIX " xadd %1,(%4)\n\t" \ 108 LOCK_PREFIX " xadd %1,(%4)\n\t" \
@@ -114,7 +113,8 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem)
114 " call " slow_path "\n" \ 113 " call " slow_path "\n" \
115 "1:\n" \ 114 "1:\n" \
116 "# ending down_write" \ 115 "# ending down_write" \
117 : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ 116 : "+m" (sem->count), "=d" (tmp), \
117 "=a" (ret), ASM_CALL_CONSTRAINT \
118 : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ 118 : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \
119 : "memory", "cc"); \ 119 : "memory", "cc"); \
120 ret; \ 120 ret; \
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 184eb9894dae..78e8fcc87d4c 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -166,11 +166,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
166({ \ 166({ \
167 int __ret_gu; \ 167 int __ret_gu; \
168 register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ 168 register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \
169 register void *__sp asm(_ASM_SP); \
170 __chk_user_ptr(ptr); \ 169 __chk_user_ptr(ptr); \
171 might_fault(); \ 170 might_fault(); \
172 asm volatile("call __get_user_%P4" \ 171 asm volatile("call __get_user_%P4" \
173 : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ 172 : "=a" (__ret_gu), "=r" (__val_gu), \
173 ASM_CALL_CONSTRAINT \
174 : "0" (ptr), "i" (sizeof(*(ptr)))); \ 174 : "0" (ptr), "i" (sizeof(*(ptr)))); \
175 (x) = (__force __typeof__(*(ptr))) __val_gu; \ 175 (x) = (__force __typeof__(*(ptr))) __val_gu; \
176 __builtin_expect(__ret_gu, 0); \ 176 __builtin_expect(__ret_gu, 0); \
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 9606688caa4b..128a1a0b1450 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -113,10 +113,9 @@ extern struct { char _entry[32]; } hypercall_page[];
113 register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ 113 register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \
114 register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ 114 register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \
115 register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ 115 register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \
116 register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ 116 register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5;
117 register void *__sp asm(_ASM_SP);
118 117
119#define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) 118#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT
120#define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) 119#define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1)
121#define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) 120#define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2)
122#define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) 121#define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 16bf6655aa85..f23f13403f33 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -5296,7 +5296,6 @@ static void fetch_possible_mmx_operand(struct x86_emulate_ctxt *ctxt,
5296 5296
5297static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)) 5297static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *))
5298{ 5298{
5299 register void *__sp asm(_ASM_SP);
5300 ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; 5299 ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF;
5301 5300
5302 if (!(ctxt->d & ByteOp)) 5301 if (!(ctxt->d & ByteOp))
@@ -5304,7 +5303,7 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *))
5304 5303
5305 asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n" 5304 asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n"
5306 : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags), 5305 : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags),
5307 [fastop]"+S"(fop), "+r"(__sp) 5306 [fastop]"+S"(fop), ASM_CALL_CONSTRAINT
5308 : "c"(ctxt->src2.val)); 5307 : "c"(ctxt->src2.val));
5309 5308
5310 ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); 5309 ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 06c0c6d0541e..6ee237f509dc 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -9036,7 +9036,6 @@ static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx)
9036static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) 9036static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
9037{ 9037{
9038 u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); 9038 u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
9039 register void *__sp asm(_ASM_SP);
9040 9039
9041 if ((exit_intr_info & (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK)) 9040 if ((exit_intr_info & (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK))
9042 == (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) { 9041 == (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) {
@@ -9065,7 +9064,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
9065#ifdef CONFIG_X86_64 9064#ifdef CONFIG_X86_64
9066 [sp]"=&r"(tmp), 9065 [sp]"=&r"(tmp),
9067#endif 9066#endif
9068 "+r"(__sp) 9067 ASM_CALL_CONSTRAINT
9069 : 9068 :
9070 [entry]"r"(entry), 9069 [entry]"r"(entry),
9071 [ss]"i"(__KERNEL_DS), 9070 [ss]"i"(__KERNEL_DS),
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index b836a7274e12..39567b5c33da 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -806,7 +806,6 @@ no_context(struct pt_regs *regs, unsigned long error_code,
806 if (is_vmalloc_addr((void *)address) && 806 if (is_vmalloc_addr((void *)address) &&
807 (((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) || 807 (((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) ||
808 address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) { 808 address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) {
809 register void *__sp asm("rsp");
810 unsigned long stack = this_cpu_read(orig_ist.ist[DOUBLEFAULT_STACK]) - sizeof(void *); 809 unsigned long stack = this_cpu_read(orig_ist.ist[DOUBLEFAULT_STACK]) - sizeof(void *);
811 /* 810 /*
812 * We're likely to be running with very little stack space 811 * We're likely to be running with very little stack space
@@ -821,7 +820,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
821 asm volatile ("movq %[stack], %%rsp\n\t" 820 asm volatile ("movq %[stack], %%rsp\n\t"
822 "call handle_stack_overflow\n\t" 821 "call handle_stack_overflow\n\t"
823 "1: jmp 1b" 822 "1: jmp 1b"
824 : "+r" (__sp) 823 : ASM_CALL_CONSTRAINT
825 : "D" ("kernel stack overflow (page fault)"), 824 : "D" ("kernel stack overflow (page fault)"),
826 "S" (regs), "d" (address), 825 "S" (regs), "d" (address),
827 [stack] "rm" (stack)); 826 [stack] "rm" (stack));
diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt
index 6a1af43862df..3995735a878f 100644
--- a/tools/objtool/Documentation/stack-validation.txt
+++ b/tools/objtool/Documentation/stack-validation.txt
@@ -194,10 +194,10 @@ they mean, and suggestions for how to fix them.
194 If it's a GCC-compiled .c file, the error may be because the function 194 If it's a GCC-compiled .c file, the error may be because the function
195 uses an inline asm() statement which has a "call" instruction. An 195 uses an inline asm() statement which has a "call" instruction. An
196 asm() statement with a call instruction must declare the use of the 196 asm() statement with a call instruction must declare the use of the
197 stack pointer in its output operand. For example, on x86_64: 197 stack pointer in its output operand. On x86_64, this means adding
198 the ASM_CALL_CONSTRAINT as an output constraint:
198 199
199 register void *__sp asm("rsp"); 200 asm volatile("call func" : ASM_CALL_CONSTRAINT);
200 asm volatile("call func" : "+r" (__sp));
201 201
202 Otherwise the stack frame may not get created before the call. 202 Otherwise the stack frame may not get created before the call.
203 203