Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/include/asm/bug.h
26481 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifndef _ASM_X86_BUG_H
3
#define _ASM_X86_BUG_H
4
5
#include <linux/stringify.h>
6
#include <linux/instrumentation.h>
7
#include <linux/objtool.h>
8
9
/*
10
* Despite that some emulators terminate on UD2, we use it for WARN().
11
*/
12
#define ASM_UD2 ".byte 0x0f, 0x0b"
13
#define INSN_UD2 0x0b0f
14
#define LEN_UD2 2
15
16
/*
17
* In clang we have UD1s reporting UBSAN failures on X86, 64 and 32bit.
18
*/
19
#define INSN_ASOP 0x67
20
#define INSN_LOCK 0xf0
21
#define OPCODE_ESCAPE 0x0f
22
#define SECOND_BYTE_OPCODE_UD1 0xb9
23
#define SECOND_BYTE_OPCODE_UD2 0x0b
24
25
#define BUG_NONE 0xffff
26
#define BUG_UD2 0xfffe
27
#define BUG_UD1 0xfffd
28
#define BUG_UD1_UBSAN 0xfffc
29
#define BUG_EA 0xffea
30
#define BUG_LOCK 0xfff0
31
32
#ifdef CONFIG_GENERIC_BUG
33
34
#ifdef CONFIG_X86_32
35
# define __BUG_REL(val) ".long " val
36
#else
37
# define __BUG_REL(val) ".long " val " - ."
38
#endif
39
40
#ifdef CONFIG_DEBUG_BUGVERBOSE
41
#define __BUG_ENTRY(file, line, flags) \
42
"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n" \
43
"\t" __BUG_REL(file) "\t# bug_entry::file\n" \
44
"\t.word " line "\t# bug_entry::line\n" \
45
"\t.word " flags "\t# bug_entry::flags\n"
46
#else
47
#define __BUG_ENTRY(file, line, flags) \
48
"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n" \
49
"\t.word " flags "\t# bug_entry::flags\n"
50
#endif
51
52
#define _BUG_FLAGS_ASM(ins, file, line, flags, size, extra) \
53
"1:\t" ins "\n" \
54
".pushsection __bug_table,\"aw\"\n" \
55
__BUG_ENTRY(file, line, flags) \
56
"\t.org 2b + " size "\n" \
57
".popsection\n" \
58
extra
59
60
#define _BUG_FLAGS(ins, flags, extra) \
61
do { \
62
asm_inline volatile(_BUG_FLAGS_ASM(ins, "%c0", \
63
"%c1", "%c2", "%c3", extra) \
64
: : "i" (__FILE__), "i" (__LINE__), \
65
"i" (flags), \
66
"i" (sizeof(struct bug_entry))); \
67
} while (0)
68
69
#define ARCH_WARN_ASM(file, line, flags, size) \
70
_BUG_FLAGS_ASM(ASM_UD2, file, line, flags, size, "")
71
72
#else
73
74
#define _BUG_FLAGS(ins, flags, extra) asm volatile(ins)
75
76
#endif /* CONFIG_GENERIC_BUG */
77
78
#define HAVE_ARCH_BUG
79
#define BUG() \
80
do { \
81
instrumentation_begin(); \
82
_BUG_FLAGS(ASM_UD2, 0, ""); \
83
__builtin_unreachable(); \
84
} while (0)
85
86
/*
87
* This instrumentation_begin() is strictly speaking incorrect; but it
88
* suppresses the complaints from WARN()s in noinstr code. If such a WARN()
89
* were to trigger, we'd rather wreck the machine in an attempt to get the
90
* message out than not know about it.
91
*/
92
93
#define ARCH_WARN_REACHABLE ANNOTATE_REACHABLE(1b)
94
95
#define __WARN_FLAGS(flags) \
96
do { \
97
__auto_type __flags = BUGFLAG_WARNING|(flags); \
98
instrumentation_begin(); \
99
_BUG_FLAGS(ASM_UD2, __flags, ARCH_WARN_REACHABLE); \
100
instrumentation_end(); \
101
} while (0)
102
103
#include <asm-generic/bug.h>
104
105
#endif /* _ASM_X86_BUG_H */
106
107