From e3abd056ffc9d6397766817eadbd4297632aceaf Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 9 Jan 2026 16:31:37 +0100 Subject: [PATCH] s390/bug: Convert to inline assembly with input operands MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Rewrite the bug inline assembly so it uses input operands again instead of pure macro replacements. This more or less reverts the conversion done when 'cond_str' support was added [1]. Reason for this is that the upcoming __WARN_printf() implementation requires an inline assembly with an output operand. At the same time input strings (format specifier and condition string) may contain the special '%' character. As soon as an inline assembly is specified to have input/output operands the '%' has a special meaning: e.g. converting the existing #define __BUG_FLAGS(cond_str, flags) \ asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags))); to #define __BUG_FLAGS(cond_str, flags) \ asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags))::); will result in a compile error as soon as 'cond_str' contains a '%' character: net/core/neighbour.c: In function ‘neigh_table_init’: ././include/linux/compiler_types.h:546:20: error: invalid 'asm': invalid %-code ... net/core/neighbour.c:1838:17: note: in expansion of macro ‘WARN_ON’ 1838 | WARN_ON(tbl->entry_size % NEIGH_PRIV_ALIGN); | ^~~~~~~ Convert the code, use immediate operands, and also add comments similar to x86 which are emitted to the generated assembly file, which makes debugging much easier. Note: since gcc-8 does not support strings as immediate input operands, guard the new implementation with CC_HAS_ASM_IMMEDIATE_STRINGS and fallback to the generic non-exception based warning implementation for incompatible compilers. [1] 6584ff203aec ("bugs/s390: Use 'cond_str' in __EMIT_BUG()") Reviewed-by: Sven Schnelle Signed-off-by: Heiko Carstens --- arch/s390/include/asm/bug.h | 73 ++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index ee9221bb5d180..73f65d91da500 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -2,60 +2,49 @@ #ifndef _ASM_S390_BUG_H #define _ASM_S390_BUG_H -#include +#include -#ifdef CONFIG_BUG +#if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS) -#ifndef CONFIG_DEBUG_BUGVERBOSE -#define _BUGVERBOSE_LOCATION(file, line) +#ifdef CONFIG_DEBUG_BUGVERBOSE +#define __BUG_ENTRY_VERBOSE(file, line) \ + " .long " file " - . # bug_entry::file\n" \ + " .short " line " # bug_entry::line\n" #else -#define __BUGVERBOSE_LOCATION(file, line) \ - .pushsection .rodata.str, "aMS", @progbits, 1; \ - .align 2; \ - 10002: .ascii file "\0"; \ - .popsection; \ - \ - .long 10002b - .; \ - .short line; -#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) +#define __BUG_ENTRY_VERBOSE(file, line) #endif -#ifndef CONFIG_GENERIC_BUG -#define __BUG_ENTRY(cond_str, flags) -#else -#define __BUG_ENTRY(cond_str, flags) \ - .pushsection __bug_table, "aw"; \ - .align 4; \ - 10000: .long 10001f - .; \ - _BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \ - .short flags; \ - .popsection; \ - 10001: -#endif - -#define ASM_BUG_FLAGS(cond_str, flags) \ - __BUG_ENTRY(cond_str, flags) \ - mc 0,0 - -#define ASM_BUG() ASM_BUG_FLAGS("", 0) - -#define __BUG_FLAGS(cond_str, flags) \ - asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags))); +#define __BUG_ASM(cond_str, flags) \ +do { \ + asm_inline volatile("\n" \ + "0: mc 0,0\n" \ + " .section __bug_table,\"aw\"\n" \ + "1: .long 0b - . # bug_entry::bug_addr\n" \ + __BUG_ENTRY_VERBOSE("%[file]", "%[line]") \ + " .short %[flgs] # bug_entry::flags\n" \ + " .org 1b+%[size]\n" \ + " .previous" \ + : \ + : [file] "i" (WARN_CONDITION_STR(cond_str) __FILE__), \ + [line] "i" (__LINE__), \ + [flgs] "i" (flags), \ + [size] "i" (sizeof(struct bug_entry))); \ +} while (0) -#define __WARN_FLAGS(cond_str, flags) \ -do { \ - __BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags)); \ +#define BUG() \ +do { \ + __BUG_ASM("", 0); \ + unreachable(); \ } while (0) -#define BUG() \ -do { \ - __BUG_FLAGS("", 0); \ - unreachable(); \ +#define __WARN_FLAGS(cond_str, flags) \ +do { \ + __BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \ } while (0) #define HAVE_ARCH_BUG -#endif /* CONFIG_BUG */ +#endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */ #include -- 2.47.3