xref: /openbmc/linux/arch/x86/include/asm/bug.h (revision 5f8b7d4b2e9604d03ae06f1a2dd5a1f34c33e533)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21965aae3SH. Peter Anvin #ifndef _ASM_X86_BUG_H
31965aae3SH. Peter Anvin #define _ASM_X86_BUG_H
4bb898558SAl Viro 
59a93848fSPeter Zijlstra #include <linux/stringify.h>
6d19e789fSIngo Molnar #include <linux/instrumentation.h>
7dca5da2aSPeter Zijlstra #include <linux/objtool.h>
89a93848fSPeter Zijlstra 
99a93848fSPeter Zijlstra /*
103b3a371cSPeter Zijlstra  * Despite that some emulators terminate on UD2, we use it for WARN().
119a93848fSPeter Zijlstra  */
129a93848fSPeter Zijlstra #define ASM_UD2		".byte 0x0f, 0x0b"
139a93848fSPeter Zijlstra #define INSN_UD2	0x0b0f
143b3a371cSPeter Zijlstra #define LEN_UD2		2
159a93848fSPeter Zijlstra 
16*86ee1845SGatlin Newhouse /*
17*86ee1845SGatlin Newhouse  * In clang we have UD1s reporting UBSAN failures on X86, 64 and 32bit.
18*86ee1845SGatlin Newhouse  */
19*86ee1845SGatlin Newhouse #define INSN_ASOP		0x67
20*86ee1845SGatlin Newhouse #define OPCODE_ESCAPE		0x0f
21*86ee1845SGatlin Newhouse #define SECOND_BYTE_OPCODE_UD1	0xb9
22*86ee1845SGatlin Newhouse #define SECOND_BYTE_OPCODE_UD2	0x0b
23*86ee1845SGatlin Newhouse 
24*86ee1845SGatlin Newhouse #define BUG_NONE		0xffff
25*86ee1845SGatlin Newhouse #define BUG_UD1			0xfffe
26*86ee1845SGatlin Newhouse #define BUG_UD2			0xfffd
27*86ee1845SGatlin Newhouse 
28ffb61c63SIngo Molnar #ifdef CONFIG_GENERIC_BUG
29ffb61c63SIngo Molnar 
30ffb61c63SIngo Molnar #ifdef CONFIG_X86_32
31ffb61c63SIngo Molnar # define __BUG_REL(val)	".long " __stringify(val)
32ffb61c63SIngo Molnar #else
3369505e3dSJosh Poimboeuf # define __BUG_REL(val)	".long " __stringify(val) " - ."
34ffb61c63SIngo Molnar #endif
35ffb61c63SIngo Molnar 
36ffb61c63SIngo Molnar #ifdef CONFIG_DEBUG_BUGVERBOSE
37ffb61c63SIngo Molnar 
38bfb1a7c9SNick Desaulniers #define _BUG_FLAGS(ins, flags, extra)					\
39bb898558SAl Viro do {									\
4032ee8230SRasmus Villemoes 	asm_inline volatile("1:\t" ins "\n"				\
41ffb61c63SIngo Molnar 		     ".pushsection __bug_table,\"aw\"\n"		\
42ffb61c63SIngo Molnar 		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
43ffb61c63SIngo Molnar 		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
44ffb61c63SIngo Molnar 		     "\t.word %c1"        "\t# bug_entry::line\n"	\
45ffb61c63SIngo Molnar 		     "\t.word %c2"        "\t# bug_entry::flags\n"	\
46ffb61c63SIngo Molnar 		     "\t.org 2b+%c3\n"					\
47bfb1a7c9SNick Desaulniers 		     ".popsection\n"					\
48bfb1a7c9SNick Desaulniers 		     extra						\
49bb898558SAl Viro 		     : : "i" (__FILE__), "i" (__LINE__),		\
509a93848fSPeter Zijlstra 			 "i" (flags),					\
51bb898558SAl Viro 			 "i" (sizeof(struct bug_entry)));		\
529a93848fSPeter Zijlstra } while (0)
539a93848fSPeter Zijlstra 
54ffb61c63SIngo Molnar #else /* !CONFIG_DEBUG_BUGVERBOSE */
55ffb61c63SIngo Molnar 
56bfb1a7c9SNick Desaulniers #define _BUG_FLAGS(ins, flags, extra)					\
57ffb61c63SIngo Molnar do {									\
5832ee8230SRasmus Villemoes 	asm_inline volatile("1:\t" ins "\n"				\
59ffb61c63SIngo Molnar 		     ".pushsection __bug_table,\"aw\"\n"		\
60ffb61c63SIngo Molnar 		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
61ffb61c63SIngo Molnar 		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
62ffb61c63SIngo Molnar 		     "\t.org 2b+%c1\n"					\
63bfb1a7c9SNick Desaulniers 		     ".popsection\n"					\
64bfb1a7c9SNick Desaulniers 		     extra						\
65ffb61c63SIngo Molnar 		     : : "i" (flags),					\
66ffb61c63SIngo Molnar 			 "i" (sizeof(struct bug_entry)));		\
67ffb61c63SIngo Molnar } while (0)
68ffb61c63SIngo Molnar 
69ffb61c63SIngo Molnar #endif /* CONFIG_DEBUG_BUGVERBOSE */
70ffb61c63SIngo Molnar 
71ffb61c63SIngo Molnar #else
72ffb61c63SIngo Molnar 
73bfb1a7c9SNick Desaulniers #define _BUG_FLAGS(ins, flags, extra)  asm volatile(ins)
74ffb61c63SIngo Molnar 
75ffb61c63SIngo Molnar #endif /* CONFIG_GENERIC_BUG */
76ffb61c63SIngo Molnar 
7770579a86SArnd Bergmann #define HAVE_ARCH_BUG
789a93848fSPeter Zijlstra #define BUG()							\
799a93848fSPeter Zijlstra do {								\
805916d5f9SThomas Gleixner 	instrumentation_begin();				\
81bfb1a7c9SNick Desaulniers 	_BUG_FLAGS(ASM_UD2, 0, "");				\
82bfb1a7c9SNick Desaulniers 	__builtin_unreachable();				\
83bb898558SAl Viro } while (0)
84bb898558SAl Viro 
858e8bb06dSPeter Zijlstra /*
868e8bb06dSPeter Zijlstra  * This instrumentation_begin() is strictly speaking incorrect; but it
878e8bb06dSPeter Zijlstra  * suppresses the complaints from WARN()s in noinstr code. If such a WARN()
888e8bb06dSPeter Zijlstra  * were to trigger, we'd rather wreck the machine in an attempt to get the
898e8bb06dSPeter Zijlstra  * message out than not know about it.
908e8bb06dSPeter Zijlstra  */
912b5db668SJosh Poimboeuf #define __WARN_FLAGS(flags)					\
922b5db668SJosh Poimboeuf do {								\
939ce02f0fSVincent Mailhol 	__auto_type __flags = BUGFLAG_WARNING|(flags);		\
945916d5f9SThomas Gleixner 	instrumentation_begin();				\
959ce02f0fSVincent Mailhol 	_BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE);		\
965916d5f9SThomas Gleixner 	instrumentation_end();					\
972b5db668SJosh Poimboeuf } while (0)
989a93848fSPeter Zijlstra 
99bb898558SAl Viro #include <asm-generic/bug.h>
100f05e798aSDavid Howells 
1011965aae3SH. Peter Anvin #endif /* _ASM_X86_BUG_H */
102