[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <74E07B14-61DB-4346-9F63-B6822A3B50AF@zytor.com>
Date: Fri, 07 Mar 2025 14:06:08 -0800
From: "H. Peter Anvin" <hpa@...or.com>
To: linux-kernel@...r.kernel.org,
tip-bot2 for Josh Poimboeuf <tip-bot2@...utronix.de>,
linux-tip-commits@...r.kernel.org
CC: kernel test robot <lkp@...el.com>, Josh Poimboeuf <jpoimboe@...nel.org>,
Ingo Molnar <mingo@...nel.org>,
"Peter Zijlstra (Intel)" <peterz@...radead.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Brian Gerst <brgerst@...il.com>, x86@...nel.org
Subject: Re: [tip: x86/asm] x86/asm: Fix ASM_CALL_CONSTRAINT for Clang 19 + KCOV + KMSAN
On March 4, 2025 2:36:24 AM PST, tip-bot2 for Josh Poimboeuf <tip-bot2@...utronix.de> wrote:
>The following commit has been merged into the x86/asm branch of tip:
>
>Commit-ID: 6530eb13c1fe8ab6452c23815ef17c278665d746
>Gitweb: https://git.kernel.org/tip/6530eb13c1fe8ab6452c23815ef17c278665d746
>Author: Josh Poimboeuf <jpoimboe@...nel.org>
>AuthorDate: Sun, 02 Mar 2025 17:21:02 -08:00
>Committer: Ingo Molnar <mingo@...nel.org>
>CommitterDate: Tue, 04 Mar 2025 11:21:40 +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@...el.com>
>Signed-off-by: Josh Poimboeuf <jpoimboe@...nel.org>
>Signed-off-by: Ingo Molnar <mingo@...nel.org>
>Acked-by: Peter Zijlstra (Intel) <peterz@...radead.org>
>Cc: Linus Torvalds <torvalds@...ux-foundation.org>
>Cc: Brian Gerst <brgerst@...il.com>
>Cc: H. Peter Anvin <hpa@...or.com>
>Cc: linux-kernel@...r.kernel.org
>Closes: https://lore.kernel.org/oe-kbuild-all/202502150634.qjxwSeJR-lkp@intel.com/
>---
> 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;
>
Note that the gcc people have explicitly disavowed this form and have rejected a request to support it going forward.
As such, it seems like a Really Bad Idea
Powered by blists - more mailing lists