[PATCH 2/2] bugs/s390: Use inline assembly without input operands

Heiko Carstens
2025-06-17T13:50:51Z

The recent change which adds DEBUG_BUGVERBOSE_DETAILED support for s390
changed the __EMIT_BUG() inline assembly so it has a string as immediate
input operand. Some older gcc variants cannot handle strings as immediate
input operands for inline assemblies. Doing so may result in compile
errors:

mm/mempool.c: In function 'remove_element':
include/linux/compiler_types.h:497:20: warning: asm operand 0 probably
doesn't match constraints
#define asm_inline asm __inline
^~~
arch/s390/include/asm/bug.h:12:2: note: in expansion of macro 'asm_inline'
asm_inline volatile( \
^~~~~~~~~~
arch/s390/include/asm/bug.h:43:2: note: in expansion of macro '__EMIT_BUG'
__EMIT_BUG("", 0); \
^~~~~~~~~~
include/asm-generic/bug.h:77:57: note: in expansion of macro 'BUG'
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
^~~
mm/mempool.c:149:2: note: in expansion of macro 'BUG_ON'
BUG_ON(pool->curr_nr < 0);
^~~~~~
include/linux/compiler_types.h:497:20: error: impossible constraint in 'asm'
#define asm_inline asm __inline
^~~

Rewrite the s390 generic bug support very similar to arm64 and loongarch,
and get rid of all input operands to fix this.

Fixes: 45c79ca947c9 ("bugs/s390: Use 'cond_str' in __EMIT_BUG()")
Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
Closes: https://lore.kernel.org/r/CA+G9fYuu5r34=bndUYWNxe_yLgBaPGXmK9WP3WTtoXMs_2LX-Q@mail.gmail.com
Cc: Anders Roxell <anders.roxell@linaro.org>
Cc: Naresh Kamboju <naresh.kamboju@linaro.org>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
---
arch/s390/include/asm/bug.h | 81 +++++++++++++++++++------------------
1 file changed, 41 insertions(+), 40 deletions(-)

diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index 58ab4efd9dd5..a185855ab158 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -2,54 +2,55 @@
#ifndef _ASM_S390_BUG_H
#define _ASM_S390_BUG_H

-#include <linux/compiler.h>
+#include <linux/stringify.h>

-#ifdef CONFIG_BUG
+#ifndef CONFIG_DEBUG_BUGVERBOSE
+#define _BUGVERBOSE_LOCATION(file, line)
+#else
+#define __BUGVERBOSE_LOCATION(file, line) \
+ .pushsection .rodata.str, "aMS", @progbits, 1; \
+ 10002: .string file; \
+ .popsection; \
+ \
+ .long 10002b - .; \
+ .short line;
+#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
+#endif

-#ifdef CONFIG_DEBUG_BUGVERBOSE
+#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 __EMIT_BUG(cond_str, x) do { \
- asm_inline volatile( \
- "0: mc 0,0\n" \
- ".section __bug_table,\"aw\"\n" \
- "1: .long 0b-.\n" \
- " .long %0-.\n" \
- " .short %1,%2\n" \
- " .org 1b+%3\n" \
- ".previous\n" \
- : : "i" (WARN_CONDITION_STR(cond_str) __FILE__),\
- "i" (__LINE__), \
- "i" (x), \
- "i" (sizeof(struct bug_entry))); \
+#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 __WARN_FLAGS(cond_str, flags) \
+do { \
+ __BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags)); \
} while (0)

-#else /* CONFIG_DEBUG_BUGVERBOSE */
-
-#define __EMIT_BUG(cond_str, x) do { \
- asm_inline volatile( \
- "0: mc 0,0\n" \
- ".section __bug_table,\"aw\"\n" \
- "1: .long 0b-.\n" \
- " .short %0\n" \
- " .org 1b+%1\n" \
- ".previous\n" \
- : : "i" (x), \
- "i" (sizeof(struct bug_entry))); \
-} while (0)
-
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
-
-#define BUG() do { \
- __EMIT_BUG("", 0); \
- unreachable(); \
-} while (0)
-
-#define __WARN_FLAGS(cond_str, flags) do { \
- __EMIT_BUG(cond_str, BUGFLAG_WARNING|(flags)); \
+#define BUG() \
+do { \
+ __BUG_FLAGS("", 0); \
+ unreachable(); \
} while (0)

#define HAVE_ARCH_BUG
-#endif /* CONFIG_BUG */

#include <asm-generic/bug.h>

--
2.48.1