The following commit has been merged into the x86/asm branch of tip: Commit-ID: 96092b7552d96f841c94265920c922da72ab46e3 Gitweb: https://git.kernel.org/tip/96092b7552d96f841c94265920c922da72ab46e3 Author: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> AuthorDate: Sun, 02 Mar 2025 17:21:02 -08:00 Committer: Ingo Molnar <mingo@xxxxxxxxxx> CommitterDate: Mon, 03 Mar 2025 11:39:54 +01:00 x86/asm: Fix ASM_CALL_CONSTRAINT for Clang 19 + KCOV + KMSAN With CONFIG_KCOV and CONFIG_KMSAN enabled, a case was found with Clang 19 where it takes the ASM_CALL_CONSTRAINT output constraint quite literally by saving and restoring %rsp around the inline asm. Not only is that completely unecessary, it confuses objtool and results in the following warning on Clang 19: arch/x86/kvm/cpuid.o: warning: objtool: do_cpuid_func+0x2428: undefined stack state After some experimentation it was discovered that an input constraint of __builtin_frame_address(0) generates better code for such cases and still achieves the desired result of forcing the frame pointer to get set up for both compilers. Change ASM_CALL_CONSTRAINT to do that. Fixes: f5caf621ee35 ("x86/asm: Fix inline asm call constraints for Clang") Reported-by: kernel test robot <lkp@xxxxxxxxx> Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx> Acked-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: Brian Gerst <brgerst@xxxxxxxxx> Cc: H. Peter Anvin <hpa@xxxxxxxxx> Cc: linux-kernel@xxxxxxxxxxxxxxx Closes: https://lore.kernel.org/oe-kbuild-all/202502150634.qjxwSeJR-lkp@xxxxxxxxx/ --- arch/x86/include/asm/alternative.h | 8 ++-- arch/x86/include/asm/asm.h | 8 ++-- arch/x86/include/asm/atomic64_32.h | 3 +- arch/x86/include/asm/cmpxchg_32.h | 13 ++---- arch/x86/include/asm/irq_stack.h | 3 +- arch/x86/include/asm/mshyperv.h | 55 +++++++++++++------------- arch/x86/include/asm/paravirt_types.h | 6 ++- arch/x86/include/asm/percpu.h | 34 +++++++--------- arch/x86/include/asm/preempt.h | 22 +++++----- arch/x86/include/asm/sync_core.h | 6 ++- arch/x86/include/asm/uaccess.h | 12 +++--- arch/x86/include/asm/uaccess_64.h | 10 +++-- arch/x86/include/asm/xen/hypercall.h | 4 +- arch/x86/kernel/alternative.c | 8 ++-- arch/x86/kvm/emulate.c | 11 +++-- arch/x86/kvm/vmx/vmx_ops.h | 3 +- 16 files changed, 111 insertions(+), 95 deletions(-) diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 52626a7..5fcfe96 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -239,9 +239,10 @@ static inline int alternatives_text_reserved(void *start, void *end) */ #define alternative_call(oldfunc, newfunc, ft_flags, output, input, clobbers...) \ asm_inline volatile(ALTERNATIVE("call %c[old]", "call %c[new]", ft_flags) \ - : ALT_OUTPUT_SP(output) \ + : output \ : [old] "i" (oldfunc), [new] "i" (newfunc) \ COMMA(input) \ + COMMA(ASM_CALL_CONSTRAINT) \ : clobbers) /* @@ -254,14 +255,13 @@ static inline int alternatives_text_reserved(void *start, void *end) output, input, clobbers...) \ asm_inline volatile(ALTERNATIVE_2("call %c[old]", "call %c[new1]", ft_flags1, \ "call %c[new2]", ft_flags2) \ - : ALT_OUTPUT_SP(output) \ + : output \ : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ [new2] "i" (newfunc2) \ COMMA(input) \ + COMMA(ASM_CALL_CONSTRAINT) \ : clobbers) -#define ALT_OUTPUT_SP(...) ASM_CALL_CONSTRAINT, ## __VA_ARGS__ - /* Macro for creating assembler functions avoiding any C magic. */ #define DEFINE_ASM_FUNC(func, instr, sec) \ asm (".pushsection " #sec ", \"ax\"\n" \ diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 975ae7a..0d268e6 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -213,6 +213,8 @@ static __always_inline __pure void *rip_rel_ptr(void *p) /* For C file, we already have NOKPROBE_SYMBOL macro */ +register unsigned long current_stack_pointer asm(_ASM_SP); + /* Insert a comma if args are non-empty */ #define COMMA(x...) __COMMA(x) #define __COMMA(...) , ##__VA_ARGS__ @@ -225,13 +227,13 @@ static __always_inline __pure void *rip_rel_ptr(void *p) #define ASM_INPUT(x...) x /* - * This output constraint should be used for any inline asm which has a "call" + * This input constraint should be used for any inline asm which has a "call" * instruction. Otherwise the asm may be inserted before the frame pointer * gets set up by the containing function. If you forget to do this, objtool * may print a "call without frame pointer save/setup" warning. */ -register unsigned long current_stack_pointer asm(_ASM_SP); -#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) +#define ASM_CALL_CONSTRAINT "r" (__builtin_frame_address(0)) + #endif /* __ASSEMBLY__ */ #define _ASM_EXTABLE(from, to) \ diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index ab83820..8efb4f2 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -51,9 +51,10 @@ static __always_inline s64 arch_atomic64_read_nonatomic(const atomic64_t *v) #ifdef CONFIG_X86_CX8 #define __alternative_atomic64(f, g, out, in, clobbers...) \ asm volatile("call %c[func]" \ - : ALT_OUTPUT_SP(out) \ + : out \ : [func] "i" (atomic64_##g##_cx8) \ COMMA(in) \ + COMMA(ASM_CALL_CONSTRAINT) \ : clobbers) #define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8) diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index ee89fbc..3ae0352 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h @@ -95,9 +95,9 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp, ALTERNATIVE(_lock_loc \ "call cmpxchg8b_emu", \ _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \ - : ALT_OUTPUT_SP("+a" (o.low), "+d" (o.high)) \ - : "b" (n.low), "c" (n.high), \ - [ptr] "S" (_ptr) \ + : "+a" (o.low), "+d" (o.high) \ + : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ \ o.full; \ @@ -126,10 +126,9 @@ static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64 "call cmpxchg8b_emu", \ _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \ CC_SET(e) \ - : ALT_OUTPUT_SP(CC_OUT(e) (ret), \ - "+a" (o.low), "+d" (o.high)) \ - : "b" (n.low), "c" (n.high), \ - [ptr] "S" (_ptr) \ + : CC_OUT(e) (ret), "+a" (o.low), "+d" (o.high) \ + : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ \ if (unlikely(!ret)) \ diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 562a547..8e56a07 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -92,8 +92,9 @@ \ "popq %%rsp \n" \ \ - : "+r" (tos), ASM_CALL_CONSTRAINT \ + : "+r" (tos) \ : [__func] "i" (func), [tos] "r" (tos) argconstr \ + COMMA(ASM_CALL_CONSTRAINT) \ : "cc", "rax", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", \ "memory" \ ); \ diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 5e6193d..791a9b2 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -79,9 +79,10 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) if (hv_isolation_type_snp() && !hyperv_paravisor_present) { __asm__ __volatile__("mov %[output_address], %%r8\n" "vmmcall" - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input_address) + : "=a" (hv_status), "+c" (control), + "+d" (input_address) : [output_address] "r" (output_address) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "memory", "r8", "r9", "r10", "r11"); return hv_status; } @@ -91,10 +92,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) __asm__ __volatile__("mov %[output_address], %%r8\n" CALL_NOSPEC - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input_address) + : "=a" (hv_status), "+c" (control), + "+d" (input_address) : [output_address] "r" (output_address), THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "memory", "r8", "r9", "r10", "r11"); #else u32 input_address_hi = upper_32_bits(input_address); @@ -106,12 +108,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) return U64_MAX; __asm__ __volatile__(CALL_NOSPEC - : "=A" (hv_status), - "+c" (input_address_lo), ASM_CALL_CONSTRAINT - : "A" (control), - "b" (input_address_hi), - "D"(output_address_hi), "S"(output_address_lo), + : "=A" (hv_status), "+c" (input_address_lo) + : "A" (control), "b" (input_address_hi), + "D" (output_address_hi), "S"(output_address_lo), THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "memory"); #endif /* !x86_64 */ return hv_status; @@ -135,14 +136,16 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1) if (hv_isolation_type_snp() && !hyperv_paravisor_present) { __asm__ __volatile__( "vmmcall" - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input1) - :: "cc", "r8", "r9", "r10", "r11"); + : "=a" (hv_status), "+c" (control), + "+d" (input1) + : ASM_CALL_CONSTRAINT + : "cc", "r8", "r9", "r10", "r11"); } else { __asm__ __volatile__(CALL_NOSPEC - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input1) + : "=a" (hv_status), "+c" (control), + "+d" (input1) : THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "r8", "r9", "r10", "r11"); } #else @@ -151,12 +154,10 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1) u32 input1_lo = lower_32_bits(input1); __asm__ __volatile__ (CALL_NOSPEC - : "=A"(hv_status), - "+c"(input1_lo), - ASM_CALL_CONSTRAINT - : "A" (control), - "b" (input1_hi), + : "=A"(hv_status), "+c"(input1_lo) + : "A" (control), "b" (input1_hi), THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "edi", "esi"); } #endif @@ -189,17 +190,19 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2) if (hv_isolation_type_snp() && !hyperv_paravisor_present) { __asm__ __volatile__("mov %[input2], %%r8\n" "vmmcall" - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input1) + : "=a" (hv_status), "+c" (control), + "+d" (input1) : [input2] "r" (input2) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "r8", "r9", "r10", "r11"); } else { __asm__ __volatile__("mov %[input2], %%r8\n" CALL_NOSPEC - : "=a" (hv_status), ASM_CALL_CONSTRAINT, - "+c" (control), "+d" (input1) + : "=a" (hv_status), "+c" (control), + "+d" (input1) : [input2] "r" (input2), THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc", "r8", "r9", "r10", "r11"); } #else @@ -210,11 +213,11 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2) u32 input2_lo = lower_32_bits(input2); __asm__ __volatile__ (CALL_NOSPEC - : "=A"(hv_status), - "+c"(input1_lo), ASM_CALL_CONSTRAINT + : "=A"(hv_status), "+c" (input1_lo) : "A" (control), "b" (input1_hi), - "D"(input2_hi), "S"(input2_lo), + "D" (input2_hi), "S" (input2_lo), THUNK_TARGET(hv_hypercall_pg) + COMMA(ASM_CALL_CONSTRAINT) : "cc"); } #endif diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index e26633c..68bdce6 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -392,9 +392,10 @@ int paravirt_disable_iospace(void); PVOP_TEST_NULL(op); \ asm volatile(ALTERNATIVE(PARAVIRT_CALL, ALT_CALL_INSTR, \ ALT_CALL_ALWAYS) \ - : call_clbr, ASM_CALL_CONSTRAINT \ + : call_clbr \ : paravirt_ptr(op), \ ##__VA_ARGS__ \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory", "cc" extra_clbr); \ ret; \ }) @@ -407,9 +408,10 @@ int paravirt_disable_iospace(void); asm volatile(ALTERNATIVE_2(PARAVIRT_CALL, \ ALT_CALL_INSTR, ALT_CALL_ALWAYS, \ alt, cond) \ - : call_clbr, ASM_CALL_CONSTRAINT \ + : call_clbr \ : paravirt_ptr(op), \ ##__VA_ARGS__ \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory", "cc" extra_clbr); \ ret; \ }) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 8a8cf86..60390a0 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -323,10 +323,10 @@ do { \ asm_inline qual ( \ ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \ "cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \ - : ALT_OUTPUT_SP([var] "+m" (__my_cpu_var(_var)), \ - "+a" (old__.low), "+d" (old__.high)) \ - : "b" (new__.low), "c" (new__.high), \ - "S" (&(_var)) \ + : [var] "+m" (__my_cpu_var(_var)), "+a" (old__.low), \ + "+d" (old__.high) \ + : "b" (new__.low), "c" (new__.high), "S" (&(_var)) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ \ old__.var; \ @@ -353,11 +353,10 @@ do { \ ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \ "cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \ CC_SET(z) \ - : ALT_OUTPUT_SP(CC_OUT(z) (success), \ - [var] "+m" (__my_cpu_var(_var)), \ - "+a" (old__.low), "+d" (old__.high)) \ - : "b" (new__.low), "c" (new__.high), \ - "S" (&(_var)) \ + : CC_OUT(z) (success), [var] "+m" (__my_cpu_var(_var)), \ + "+a" (old__.low), "+d" (old__.high) \ + : "b" (new__.low), "c" (new__.high), "S" (&(_var)) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ if (unlikely(!success)) \ *_oval = old__.var; \ @@ -392,10 +391,10 @@ do { \ asm_inline qual ( \ ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \ "cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \ - : ALT_OUTPUT_SP([var] "+m" (__my_cpu_var(_var)), \ - "+a" (old__.low), "+d" (old__.high)) \ - : "b" (new__.low), "c" (new__.high), \ - "S" (&(_var)) \ + : [var] "+m" (__my_cpu_var(_var)), "+a" (old__.low), \ + "+d" (old__.high) \ + : "b" (new__.low), "c" (new__.high), "S" (&(_var)) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ \ old__.var; \ @@ -422,11 +421,10 @@ do { \ ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \ "cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \ CC_SET(z) \ - : ALT_OUTPUT_SP(CC_OUT(z) (success), \ - [var] "+m" (__my_cpu_var(_var)), \ - "+a" (old__.low), "+d" (old__.high)) \ - : "b" (new__.low), "c" (new__.high), \ - "S" (&(_var)) \ + : CC_OUT(z) (success), [var] "+m" (__my_cpu_var(_var)), \ + "+a" (old__.low), "+d" (old__.high) \ + : "b" (new__.low), "c" (new__.high), "S" (&(_var)) \ + COMMA(ASM_CALL_CONSTRAINT) \ : "memory"); \ if (unlikely(!success)) \ *_oval = old__.var; \ diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index 919909d..7e83482 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h @@ -121,27 +121,29 @@ extern asmlinkage void preempt_schedule_notrace_thunk(void); DECLARE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled); -#define __preempt_schedule() \ -do { \ - __STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule); \ - asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule) : ASM_CALL_CONSTRAINT); \ +#define __preempt_schedule() \ +do { \ + __STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule); \ + asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule) \ + : : ASM_CALL_CONSTRAINT); \ } while (0) DECLARE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled); -#define __preempt_schedule_notrace() \ -do { \ - __STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule_notrace); \ - asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule_notrace) : ASM_CALL_CONSTRAINT); \ +#define __preempt_schedule_notrace() \ +do { \ + __STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule_notrace); \ + asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule_notrace) \ + : : ASM_CALL_CONSTRAINT); \ } while (0) #else /* PREEMPT_DYNAMIC */ #define __preempt_schedule() \ - asm volatile ("call preempt_schedule_thunk" : ASM_CALL_CONSTRAINT); + asm volatile ("call preempt_schedule_thunk" : : ASM_CALL_CONSTRAINT); #define __preempt_schedule_notrace() \ - asm volatile ("call preempt_schedule_notrace_thunk" : ASM_CALL_CONSTRAINT); + asm volatile ("call preempt_schedule_notrace_thunk" : : ASM_CALL_CONSTRAINT); #endif /* PREEMPT_DYNAMIC */ diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h index 96bda43..c88e354 100644 --- a/arch/x86/include/asm/sync_core.h +++ b/arch/x86/include/asm/sync_core.h @@ -16,7 +16,7 @@ static __always_inline void iret_to_self(void) "pushl $1f\n\t" "iret\n\t" "1:" - : ASM_CALL_CONSTRAINT : : "memory"); + : : ASM_CALL_CONSTRAINT : "memory"); } #else static __always_inline void iret_to_self(void) @@ -34,7 +34,9 @@ static __always_inline void iret_to_self(void) "pushq $1f\n\t" "iretq\n\t" "1:" - : "=&r" (tmp), ASM_CALL_CONSTRAINT : : "cc", "memory"); + : "=&r" (tmp) + : ASM_CALL_CONSTRAINT + : "cc", "memory"); } #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 3a7755c..4a5f0c1 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -79,9 +79,9 @@ extern int __get_user_bad(void); register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ __chk_user_ptr(ptr); \ asm volatile("call __" #fn "_%c[size]" \ - : "=a" (__ret_gu), "=r" (__val_gu), \ - ASM_CALL_CONSTRAINT \ - : "0" (ptr), [size] "i" (sizeof(*(ptr)))); \ + : "=a" (__ret_gu), "=r" (__val_gu) \ + : "0" (ptr), [size] "i" (sizeof(*(ptr))) \ + COMMA(ASM_CALL_CONSTRAINT)); \ instrument_get_user(__val_gu); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ @@ -178,12 +178,12 @@ extern void __put_user_nocheck_8(void); __ptr_pu = __ptr; \ __val_pu = __x; \ asm volatile("call __" #fn "_%c[size]" \ - : "=c" (__ret_pu), \ - ASM_CALL_CONSTRAINT \ + : "=c" (__ret_pu) \ : "0" (__ptr_pu), \ "r" (__val_pu), \ [size] "i" (sizeof(*(ptr))) \ - :"ebx"); \ + COMMA(ASM_CALL_CONSTRAINT) \ + : "ebx"); \ instrument_put_user(__x, __ptr, sizeof(*(ptr))); \ __builtin_expect(__ret_pu, 0); \ }) diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index c52f013..87a1b9e 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -129,8 +129,9 @@ copy_user_generic(void *to, const void *from, unsigned long len) "call rep_movs_alternative", ALT_NOT(X86_FEATURE_FSRM)) "2:\n" _ASM_EXTABLE_UA(1b, 2b) - :"+c" (len), "+D" (to), "+S" (from), ASM_CALL_CONSTRAINT - : : "memory", "rax"); + : "+c" (len), "+D" (to), "+S" (from) + : ASM_CALL_CONSTRAINT + : "memory", "rax"); clac(); return len; } @@ -191,8 +192,9 @@ static __always_inline __must_check unsigned long __clear_user(void __user *addr "call rep_stos_alternative", ALT_NOT(X86_FEATURE_FSRS)) "2:\n" _ASM_EXTABLE_UA(1b, 2b) - : "+c" (size), "+D" (addr), ASM_CALL_CONSTRAINT - : "a" (0)); + : "+c" (size), "+D" (addr) + : "a" (0) + COMMA(ASM_CALL_CONSTRAINT)); clac(); diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 97771b9..683772a 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -101,7 +101,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func); __ADDRESSABLE_xen_hypercall \ "call __SCT__xen_hypercall" -#define __HYPERCALL_ENTRY(x) "a" (x) +#define __HYPERCALL_ENTRY(x) "a" (x) COMMA(ASM_CALL_CONSTRAINT) #ifdef CONFIG_X86_32 #define __HYPERCALL_RETREG "eax" @@ -127,7 +127,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func); register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; -#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT +#define __HYPERCALL_0PARAM "=r" (__res) #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 8b66a55..6a7eb06 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1624,8 +1624,8 @@ static noinline void __init int3_selftest(void) asm volatile ("int3_selftest_ip:\n\t" ANNOTATE_NOENDBR " int3; nop; nop; nop; nop\n\t" - : ASM_CALL_CONSTRAINT - : __ASM_SEL_RAW(a, D) (&val) + : : __ASM_SEL_RAW(a, D) (&val) + COMMA(ASM_CALL_CONSTRAINT) : "memory"); BUG_ON(val != 1); @@ -1657,8 +1657,8 @@ static noinline void __init alt_reloc_selftest(void) */ asm_inline volatile ( ALTERNATIVE("", "lea %[mem], %%" _ASM_ARG1 "; call __alt_reloc_selftest;", X86_FEATURE_ALWAYS) - : ASM_CALL_CONSTRAINT - : [mem] "m" (__alt_reloc_selftest_addr) + : : [mem] "m" (__alt_reloc_selftest_addr) + COMMA(ASM_CALL_CONSTRAINT) : _ASM_ARG1 ); } diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 60986f6..40e12a1 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1070,7 +1070,9 @@ static __always_inline u8 test_cc(unsigned int condition, unsigned long flags) flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; asm("push %[flags]; popf; " CALL_NOSPEC - : "=a"(rc), ASM_CALL_CONSTRAINT : [thunk_target]"r"(fop), [flags]"r"(flags)); + : "=a" (rc) + : [thunk_target] "r" (fop), [flags] "r" (flags) + COMMA(ASM_CALL_CONSTRAINT)); return rc; } @@ -5079,9 +5081,10 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop) fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE; asm("push %[flags]; popf; " CALL_NOSPEC " ; pushf; pop %[flags]\n" - : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags), - [thunk_target]"+S"(fop), ASM_CALL_CONSTRAINT - : "c"(ctxt->src2.val)); + : "+a" (ctxt->dst.val), "+d" (ctxt->src.val), [flags] "+D" (flags), + [thunk_target] "+S" (fop) + : "c" (ctxt->src2.val) + COMMA(ASM_CALL_CONSTRAINT)); ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); if (!fop) /* exception is returned in fop variable */ diff --git a/arch/x86/kvm/vmx/vmx_ops.h b/arch/x86/kvm/vmx/vmx_ops.h index 9667757..a614add 100644 --- a/arch/x86/kvm/vmx/vmx_ops.h +++ b/arch/x86/kvm/vmx/vmx_ops.h @@ -144,8 +144,9 @@ do_exception: /* VMREAD faulted. As above, except push '1' for @fault. */ _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_ONE_REG, %[output]) - : ASM_CALL_CONSTRAINT, [output] "=&r" (value) + : [output] "=&r" (value) : [field] "r" (field) + COMMA(ASM_CALL_CONSTRAINT) : "cc"); return value;
![]() |