[PATCH v2 5/6] Eliminate CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
From: Nathan Chancellor
Date: Wed Nov 11 2026 - 19:54:49 EST
Commit 1aa0e8b144b6 ("Kconfig: Add option for asm goto w/ tied outputs
to workaround clang-13 bug") added CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT to
avoid a bug in clang's asm goto with outputs support when a tied output
was used. The fix in clang was to match GCC's documented behavior.
Now that the minimum supported version of clang has long been bumped
past the version where the fix landed (clang-14), any compiler that
satisfies the dependencies of CONFIG_CC_HAS_ASM_GOTO_OUTPUT will support
tied outputs properly. Eliminate CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT in
favor of just checking for CONFIG_CC_HAS_ASM_GOTO_OUTPUT directly.
Signed-off-by: Nathan Chancellor <nathan@xxxxxxxxxx>
---
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: x86@xxxxxxxxxx
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Cc: Charlie Jenkins <thecharlesjenkins@xxxxxxxxx>
Cc: Paul Walmsley <pjw@xxxxxxxxxx>
Cc: Palmer Dabbelt <palmer@xxxxxxxxxxx>
Cc: linux-riscv@xxxxxxxxxxxxxxxxxxx
---
arch/riscv/lib/csum.c | 4 +--
arch/x86/include/asm/uaccess.h | 82 ++++++++++++++++++++----------------------
scripts/Kconfig.toolchain | 5 ---
3 files changed, 41 insertions(+), 50 deletions(-)
diff --git a/arch/riscv/lib/csum.c b/arch/riscv/lib/csum.c
index c2b8986a0d39..cd461a7b61a5 100644
--- a/arch/riscv/lib/csum.c
+++ b/arch/riscv/lib/csum.c
@@ -142,7 +142,7 @@ do_csum_with_alignment(const unsigned char *buff, int len)
end = (const unsigned long *)(buff + len);
csum = do_csum_common(ptr, end, data);
-#ifdef CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) {
@@ -186,7 +186,7 @@ do_csum_with_alignment(const unsigned char *buff, int len)
return csum >> 16;
}
-#endif /* CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT */
+#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
#ifndef CONFIG_32BIT
csum += ror64(csum, 32);
csum >>= 32;
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index f4700ad6b5ec..64b648e59df0 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -248,6 +248,44 @@ do { \
: [umem] "m" (__m(addr)) \
: : label)
+#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \
+ bool success; \
+ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
+ __typeof__(*(_ptr)) __old = *_old; \
+ __typeof__(*(_ptr)) __new = (_new); \
+ asm_goto_output("\n" \
+ "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
+ _ASM_EXTABLE_UA(1b, %l[label]) \
+ : "=@ccz" (success), \
+ [ptr] "+m" (*_ptr), \
+ [old] "+a" (__old) \
+ : [new] ltype (__new) \
+ : "memory" \
+ : label); \
+ if (unlikely(!success)) \
+ *_old = __old; \
+ likely(success); })
+
+#ifdef CONFIG_X86_32
+#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \
+ bool success; \
+ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
+ __typeof__(*(_ptr)) __old = *_old; \
+ __typeof__(*(_ptr)) __new = (_new); \
+ asm_goto_output("\n" \
+ "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \
+ _ASM_EXTABLE_UA(1b, %l[label]) \
+ : "=@ccz" (success), \
+ "+A" (__old), \
+ [ptr] "+m" (*_ptr) \
+ : "b" ((u32)__new), \
+ "c" ((u32)((u64)__new >> 32)) \
+ : "memory" \
+ : label); \
+ if (unlikely(!success)) \
+ *_old = __old; \
+ likely(success); })
+#endif // CONFIG_X86_32
#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT
#ifdef CONFIG_X86_32
@@ -313,48 +351,6 @@ do { \
: [umem] "m" (__m(addr)), \
"0" (err))
-#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT
-
-#ifdef CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
-#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \
- bool success; \
- __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
- __typeof__(*(_ptr)) __old = *_old; \
- __typeof__(*(_ptr)) __new = (_new); \
- asm_goto_output("\n" \
- "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
- _ASM_EXTABLE_UA(1b, %l[label]) \
- : "=@ccz" (success), \
- [ptr] "+m" (*_ptr), \
- [old] "+a" (__old) \
- : [new] ltype (__new) \
- : "memory" \
- : label); \
- if (unlikely(!success)) \
- *_old = __old; \
- likely(success); })
-
-#ifdef CONFIG_X86_32
-#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \
- bool success; \
- __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
- __typeof__(*(_ptr)) __old = *_old; \
- __typeof__(*(_ptr)) __new = (_new); \
- asm_goto_output("\n" \
- "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \
- _ASM_EXTABLE_UA(1b, %l[label]) \
- : "=@ccz" (success), \
- "+A" (__old), \
- [ptr] "+m" (*_ptr) \
- : "b" ((u32)__new), \
- "c" ((u32)((u64)__new >> 32)) \
- : "memory" \
- : label); \
- if (unlikely(!success)) \
- *_old = __old; \
- likely(success); })
-#endif // CONFIG_X86_32
-#else // !CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \
int __err = 0; \
bool success; \
@@ -410,7 +406,7 @@ do { \
*_old = __old; \
likely(__result); })
#endif // CONFIG_X86_32
-#endif // CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
+#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT
/* FIXME: this hack is definitely wrong -AK */
struct __large_struct { unsigned long buf[100]; };
diff --git a/scripts/Kconfig.toolchain b/scripts/Kconfig.toolchain
index 6520a06a9103..9454ef5294d5 100644
--- a/scripts/Kconfig.toolchain
+++ b/scripts/Kconfig.toolchain
@@ -120,11 +120,6 @@ config CC_HAS_ASM_GOTO_OUTPUT
depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
-config CC_HAS_ASM_GOTO_TIED_OUTPUT
- depends on CC_HAS_ASM_GOTO_OUTPUT
- # Detect buggy gcc and clang, fixed in gcc-11 clang-14.
- def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
-
config TOOLS_SUPPORT_RELR
def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
--
2.56.0