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