xref: /openbmc/linux/kernel/kcsan/kcsan.h (revision 5656a7a0)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 /*
4  * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. For more info please
5  * see Documentation/dev-tools/kcsan.rst.
6  */
7 
8 #ifndef _KERNEL_KCSAN_KCSAN_H
9 #define _KERNEL_KCSAN_KCSAN_H
10 
11 #include <linux/kcsan.h>
12 
13 /* The number of adjacent watchpoints to check. */
14 #define KCSAN_CHECK_ADJACENT 1
15 #define NUM_SLOTS (1 + 2*KCSAN_CHECK_ADJACENT)
16 
17 extern unsigned int kcsan_udelay_task;
18 extern unsigned int kcsan_udelay_interrupt;
19 
20 /*
21  * Globally enable and disable KCSAN.
22  */
23 extern bool kcsan_enabled;
24 
25 /*
26  * Initialize debugfs file.
27  */
28 void kcsan_debugfs_init(void);
29 
30 enum kcsan_counter_id {
31 	/*
32 	 * Number of watchpoints currently in use.
33 	 */
34 	KCSAN_COUNTER_USED_WATCHPOINTS,
35 
36 	/*
37 	 * Total number of watchpoints set up.
38 	 */
39 	KCSAN_COUNTER_SETUP_WATCHPOINTS,
40 
41 	/*
42 	 * Total number of data races.
43 	 */
44 	KCSAN_COUNTER_DATA_RACES,
45 
46 	/*
47 	 * Total number of ASSERT failures due to races. If the observed race is
48 	 * due to two conflicting ASSERT type accesses, then both will be
49 	 * counted.
50 	 */
51 	KCSAN_COUNTER_ASSERT_FAILURES,
52 
53 	/*
54 	 * Number of times no watchpoints were available.
55 	 */
56 	KCSAN_COUNTER_NO_CAPACITY,
57 
58 	/*
59 	 * A thread checking a watchpoint raced with another checking thread;
60 	 * only one will be reported.
61 	 */
62 	KCSAN_COUNTER_REPORT_RACES,
63 
64 	/*
65 	 * Observed data value change, but writer thread unknown.
66 	 */
67 	KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN,
68 
69 	/*
70 	 * The access cannot be encoded to a valid watchpoint.
71 	 */
72 	KCSAN_COUNTER_UNENCODABLE_ACCESSES,
73 
74 	/*
75 	 * Watchpoint encoding caused a watchpoint to fire on mismatching
76 	 * accesses.
77 	 */
78 	KCSAN_COUNTER_ENCODING_FALSE_POSITIVES,
79 
80 	KCSAN_COUNTER_COUNT, /* number of counters */
81 };
82 
83 /*
84  * Increment/decrement counter with given id; avoid calling these in fast-path.
85  */
86 extern void kcsan_counter_inc(enum kcsan_counter_id id);
87 extern void kcsan_counter_dec(enum kcsan_counter_id id);
88 
89 /*
90  * Returns true if data races in the function symbol that maps to func_addr
91  * (offsets are ignored) should *not* be reported.
92  */
93 extern bool kcsan_skip_report_debugfs(unsigned long func_addr);
94 
95 /*
96  * Value-change states.
97  */
98 enum kcsan_value_change {
99 	/*
100 	 * Did not observe a value-change, however, it is valid to report the
101 	 * race, depending on preferences.
102 	 */
103 	KCSAN_VALUE_CHANGE_MAYBE,
104 
105 	/*
106 	 * Did not observe a value-change, and it is invalid to report the race.
107 	 */
108 	KCSAN_VALUE_CHANGE_FALSE,
109 
110 	/*
111 	 * The value was observed to change, and the race should be reported.
112 	 */
113 	KCSAN_VALUE_CHANGE_TRUE,
114 };
115 
116 enum kcsan_report_type {
117 	/*
118 	 * The thread that set up the watchpoint and briefly stalled was
119 	 * signalled that another thread triggered the watchpoint.
120 	 */
121 	KCSAN_REPORT_RACE_SIGNAL,
122 
123 	/*
124 	 * A thread found and consumed a matching watchpoint.
125 	 */
126 	KCSAN_REPORT_CONSUMED_WATCHPOINT,
127 
128 	/*
129 	 * No other thread was observed to race with the access, but the data
130 	 * value before and after the stall differs.
131 	 */
132 	KCSAN_REPORT_RACE_UNKNOWN_ORIGIN,
133 };
134 
135 /*
136  * Print a race report from thread that encountered the race.
137  */
138 extern void kcsan_report(const volatile void *ptr, size_t size, int access_type,
139 			 enum kcsan_value_change value_change,
140 			 enum kcsan_report_type type, int watchpoint_idx);
141 
142 #endif /* _KERNEL_KCSAN_KCSAN_H */
143