kcsan.h (3658B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. For more info please 4 * see Documentation/dev-tools/kcsan.rst. 5 * 6 * Copyright (C) 2019, Google LLC. 7 */ 8 9#ifndef _KERNEL_KCSAN_KCSAN_H 10#define _KERNEL_KCSAN_KCSAN_H 11 12#include <linux/atomic.h> 13#include <linux/kcsan.h> 14#include <linux/sched.h> 15 16/* The number of adjacent watchpoints to check. */ 17#define KCSAN_CHECK_ADJACENT 1 18#define NUM_SLOTS (1 + 2*KCSAN_CHECK_ADJACENT) 19 20extern unsigned int kcsan_udelay_task; 21extern unsigned int kcsan_udelay_interrupt; 22 23/* 24 * Globally enable and disable KCSAN. 25 */ 26extern bool kcsan_enabled; 27 28/* 29 * Save/restore IRQ flags state trace dirtied by KCSAN. 30 */ 31void kcsan_save_irqtrace(struct task_struct *task); 32void kcsan_restore_irqtrace(struct task_struct *task); 33 34/* 35 * Statistics counters displayed via debugfs; should only be modified in 36 * slow-paths. 37 */ 38enum kcsan_counter_id { 39 /* 40 * Number of watchpoints currently in use. 41 */ 42 KCSAN_COUNTER_USED_WATCHPOINTS, 43 44 /* 45 * Total number of watchpoints set up. 46 */ 47 KCSAN_COUNTER_SETUP_WATCHPOINTS, 48 49 /* 50 * Total number of data races. 51 */ 52 KCSAN_COUNTER_DATA_RACES, 53 54 /* 55 * Total number of ASSERT failures due to races. If the observed race is 56 * due to two conflicting ASSERT type accesses, then both will be 57 * counted. 58 */ 59 KCSAN_COUNTER_ASSERT_FAILURES, 60 61 /* 62 * Number of times no watchpoints were available. 63 */ 64 KCSAN_COUNTER_NO_CAPACITY, 65 66 /* 67 * A thread checking a watchpoint raced with another checking thread; 68 * only one will be reported. 69 */ 70 KCSAN_COUNTER_REPORT_RACES, 71 72 /* 73 * Observed data value change, but writer thread unknown. 74 */ 75 KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN, 76 77 /* 78 * The access cannot be encoded to a valid watchpoint. 79 */ 80 KCSAN_COUNTER_UNENCODABLE_ACCESSES, 81 82 /* 83 * Watchpoint encoding caused a watchpoint to fire on mismatching 84 * accesses. 85 */ 86 KCSAN_COUNTER_ENCODING_FALSE_POSITIVES, 87 88 KCSAN_COUNTER_COUNT, /* number of counters */ 89}; 90extern atomic_long_t kcsan_counters[KCSAN_COUNTER_COUNT]; 91 92/* 93 * Returns true if data races in the function symbol that maps to func_addr 94 * (offsets are ignored) should *not* be reported. 95 */ 96extern bool kcsan_skip_report_debugfs(unsigned long func_addr); 97 98/* 99 * Value-change states. 100 */ 101enum kcsan_value_change { 102 /* 103 * Did not observe a value-change, however, it is valid to report the 104 * race, depending on preferences. 105 */ 106 KCSAN_VALUE_CHANGE_MAYBE, 107 108 /* 109 * Did not observe a value-change, and it is invalid to report the race. 110 */ 111 KCSAN_VALUE_CHANGE_FALSE, 112 113 /* 114 * The value was observed to change, and the race should be reported. 115 */ 116 KCSAN_VALUE_CHANGE_TRUE, 117}; 118 119/* 120 * The calling thread hit and consumed a watchpoint: set the access information 121 * to be consumed by the reporting thread. No report is printed yet. 122 */ 123void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type, 124 unsigned long ip, int watchpoint_idx); 125 126/* 127 * The calling thread observed that the watchpoint it set up was hit and 128 * consumed: print the full report based on information set by the racing 129 * thread. 130 */ 131void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type, 132 unsigned long ip, enum kcsan_value_change value_change, 133 int watchpoint_idx, u64 old, u64 new, u64 mask); 134 135/* 136 * No other thread was observed to race with the access, but the data value 137 * before and after the stall differs. Reports a race of "unknown origin". 138 */ 139void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type, 140 unsigned long ip, u64 old, u64 new, u64 mask); 141 142#endif /* _KERNEL_KCSAN_KCSAN_H */