Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_X86_BUG_H
0003 #define _ASM_X86_BUG_H
0004 
0005 #include <linux/stringify.h>
0006 #include <linux/instrumentation.h>
0007 #include <linux/objtool.h>
0008 
0009 /*
0010  * Despite that some emulators terminate on UD2, we use it for WARN().
0011  */
0012 #define ASM_UD2     ".byte 0x0f, 0x0b"
0013 #define INSN_UD2    0x0b0f
0014 #define LEN_UD2     2
0015 
0016 #ifdef CONFIG_GENERIC_BUG
0017 
0018 #ifdef CONFIG_X86_32
0019 # define __BUG_REL(val) ".long " __stringify(val)
0020 #else
0021 # define __BUG_REL(val) ".long " __stringify(val) " - ."
0022 #endif
0023 
0024 #ifdef CONFIG_DEBUG_BUGVERBOSE
0025 
0026 #define _BUG_FLAGS(ins, flags, extra)                   \
0027 do {                                    \
0028     asm_inline volatile("1:\t" ins "\n"             \
0029              ".pushsection __bug_table,\"aw\"\n"        \
0030              "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
0031              "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"   \
0032              "\t.word %c1"        "\t# bug_entry::line\n"   \
0033              "\t.word %c2"        "\t# bug_entry::flags\n"  \
0034              "\t.org 2b+%c3\n"                  \
0035              ".popsection\n"                    \
0036              extra                      \
0037              : : "i" (__FILE__), "i" (__LINE__),        \
0038              "i" (flags),                   \
0039              "i" (sizeof(struct bug_entry)));       \
0040 } while (0)
0041 
0042 #else /* !CONFIG_DEBUG_BUGVERBOSE */
0043 
0044 #define _BUG_FLAGS(ins, flags, extra)                   \
0045 do {                                    \
0046     asm_inline volatile("1:\t" ins "\n"             \
0047              ".pushsection __bug_table,\"aw\"\n"        \
0048              "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
0049              "\t.word %c0"        "\t# bug_entry::flags\n"  \
0050              "\t.org 2b+%c1\n"                  \
0051              ".popsection\n"                    \
0052              extra                      \
0053              : : "i" (flags),                   \
0054              "i" (sizeof(struct bug_entry)));       \
0055 } while (0)
0056 
0057 #endif /* CONFIG_DEBUG_BUGVERBOSE */
0058 
0059 #else
0060 
0061 #define _BUG_FLAGS(ins, flags, extra)  asm volatile(ins)
0062 
0063 #endif /* CONFIG_GENERIC_BUG */
0064 
0065 #define HAVE_ARCH_BUG
0066 #define BUG()                           \
0067 do {                                \
0068     instrumentation_begin();                \
0069     _BUG_FLAGS(ASM_UD2, 0, "");             \
0070     __builtin_unreachable();                \
0071 } while (0)
0072 
0073 /*
0074  * This instrumentation_begin() is strictly speaking incorrect; but it
0075  * suppresses the complaints from WARN()s in noinstr code. If such a WARN()
0076  * were to trigger, we'd rather wreck the machine in an attempt to get the
0077  * message out than not know about it.
0078  */
0079 #define __WARN_FLAGS(flags)                 \
0080 do {                                \
0081     __auto_type __flags = BUGFLAG_WARNING|(flags);      \
0082     instrumentation_begin();                \
0083     _BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE);        \
0084     instrumentation_end();                  \
0085 } while (0)
0086 
0087 #include <asm-generic/bug.h>
0088 
0089 #endif /* _ASM_X86_BUG_H */