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/atomic.h> 12 #include <linux/kcsan.h> 13 #include <linux/sched.h> 14 15 /* The number of adjacent watchpoints to check. */ 16 #define KCSAN_CHECK_ADJACENT 1 17 #define NUM_SLOTS (1 + 2*KCSAN_CHECK_ADJACENT) 18 19 extern unsigned int kcsan_udelay_task; 20 extern unsigned int kcsan_udelay_interrupt; 21 22 /* 23 * Globally enable and disable KCSAN. 24 */ 25 extern bool kcsan_enabled; 26 27 /* 28 * Save/restore IRQ flags state trace dirtied by KCSAN. 29 */ 30 void kcsan_save_irqtrace(struct task_struct *task); 31 void kcsan_restore_irqtrace(struct task_struct *task); 32 33 /* 34 * Initialize debugfs file. 35 */ 36 void kcsan_debugfs_init(void); 37 38 /* 39 * Statistics counters displayed via debugfs; should only be modified in 40 * slow-paths. 41 */ 42 enum kcsan_counter_id { 43 /* 44 * Number of watchpoints currently in use. 45 */ 46 KCSAN_COUNTER_USED_WATCHPOINTS, 47 48 /* 49 * Total number of watchpoints set up. 50 */ 51 KCSAN_COUNTER_SETUP_WATCHPOINTS, 52 53 /* 54 * Total number of data races. 55 */ 56 KCSAN_COUNTER_DATA_RACES, 57 58 /* 59 * Total number of ASSERT failures due to races. If the observed race is 60 * due to two conflicting ASSERT type accesses, then both will be 61 * counted. 62 */ 63 KCSAN_COUNTER_ASSERT_FAILURES, 64 65 /* 66 * Number of times no watchpoints were available. 67 */ 68 KCSAN_COUNTER_NO_CAPACITY, 69 70 /* 71 * A thread checking a watchpoint raced with another checking thread; 72 * only one will be reported. 73 */ 74 KCSAN_COUNTER_REPORT_RACES, 75 76 /* 77 * Observed data value change, but writer thread unknown. 78 */ 79 KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN, 80 81 /* 82 * The access cannot be encoded to a valid watchpoint. 83 */ 84 KCSAN_COUNTER_UNENCODABLE_ACCESSES, 85 86 /* 87 * Watchpoint encoding caused a watchpoint to fire on mismatching 88 * accesses. 89 */ 90 KCSAN_COUNTER_ENCODING_FALSE_POSITIVES, 91 92 KCSAN_COUNTER_COUNT, /* number of counters */ 93 }; 94 extern atomic_long_t kcsan_counters[KCSAN_COUNTER_COUNT]; 95 96 /* 97 * Returns true if data races in the function symbol that maps to func_addr 98 * (offsets are ignored) should *not* be reported. 99 */ 100 extern bool kcsan_skip_report_debugfs(unsigned long func_addr); 101 102 /* 103 * Value-change states. 104 */ 105 enum kcsan_value_change { 106 /* 107 * Did not observe a value-change, however, it is valid to report the 108 * race, depending on preferences. 109 */ 110 KCSAN_VALUE_CHANGE_MAYBE, 111 112 /* 113 * Did not observe a value-change, and it is invalid to report the race. 114 */ 115 KCSAN_VALUE_CHANGE_FALSE, 116 117 /* 118 * The value was observed to change, and the race should be reported. 119 */ 120 KCSAN_VALUE_CHANGE_TRUE, 121 }; 122 123 enum kcsan_report_type { 124 /* 125 * The thread that set up the watchpoint and briefly stalled was 126 * signalled that another thread triggered the watchpoint. 127 */ 128 KCSAN_REPORT_RACE_SIGNAL, 129 130 /* 131 * A thread found and consumed a matching watchpoint. 132 */ 133 KCSAN_REPORT_CONSUMED_WATCHPOINT, 134 135 /* 136 * No other thread was observed to race with the access, but the data 137 * value before and after the stall differs. 138 */ 139 KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, 140 }; 141 142 /* 143 * Print a race report from thread that encountered the race. 144 */ 145 extern void kcsan_report(const volatile void *ptr, size_t size, int access_type, 146 enum kcsan_value_change value_change, 147 enum kcsan_report_type type, int watchpoint_idx); 148 149 #endif /* _KERNEL_KCSAN_KCSAN_H */ 150