blob: d3b9a96ac8a43bd503f1e1da11537a2e0abdece5 [file] [log] [blame]
Marco Elverdfd402a2019-11-14 19:02:54 +01001/* 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
16/*
17 * Globally enable and disable KCSAN.
18 */
19extern bool kcsan_enabled;
20
21/*
22 * Initialize debugfs file.
23 */
24void kcsan_debugfs_init(void);
25
26enum kcsan_counter_id {
27 /*
28 * Number of watchpoints currently in use.
29 */
30 KCSAN_COUNTER_USED_WATCHPOINTS,
31
32 /*
33 * Total number of watchpoints set up.
34 */
35 KCSAN_COUNTER_SETUP_WATCHPOINTS,
36
37 /*
38 * Total number of data races.
39 */
40 KCSAN_COUNTER_DATA_RACES,
41
42 /*
43 * Number of times no watchpoints were available.
44 */
45 KCSAN_COUNTER_NO_CAPACITY,
46
47 /*
48 * A thread checking a watchpoint raced with another checking thread;
49 * only one will be reported.
50 */
51 KCSAN_COUNTER_REPORT_RACES,
52
53 /*
54 * Observed data value change, but writer thread unknown.
55 */
56 KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN,
57
58 /*
59 * The access cannot be encoded to a valid watchpoint.
60 */
61 KCSAN_COUNTER_UNENCODABLE_ACCESSES,
62
63 /*
64 * Watchpoint encoding caused a watchpoint to fire on mismatching
65 * accesses.
66 */
67 KCSAN_COUNTER_ENCODING_FALSE_POSITIVES,
68
69 KCSAN_COUNTER_COUNT, /* number of counters */
70};
71
72/*
73 * Increment/decrement counter with given id; avoid calling these in fast-path.
74 */
Ingo Molnar5cbaefe2019-11-20 10:41:43 +010075extern void kcsan_counter_inc(enum kcsan_counter_id id);
76extern void kcsan_counter_dec(enum kcsan_counter_id id);
Marco Elverdfd402a2019-11-14 19:02:54 +010077
78/*
79 * Returns true if data races in the function symbol that maps to func_addr
80 * (offsets are ignored) should *not* be reported.
81 */
Ingo Molnar5cbaefe2019-11-20 10:41:43 +010082extern bool kcsan_skip_report_debugfs(unsigned long func_addr);
Marco Elverdfd402a2019-11-14 19:02:54 +010083
84enum kcsan_report_type {
85 /*
86 * The thread that set up the watchpoint and briefly stalled was
87 * signalled that another thread triggered the watchpoint.
88 */
89 KCSAN_REPORT_RACE_SIGNAL,
90
91 /*
92 * A thread found and consumed a matching watchpoint.
93 */
94 KCSAN_REPORT_CONSUMED_WATCHPOINT,
95
96 /*
97 * No other thread was observed to race with the access, but the data
98 * value before and after the stall differs.
99 */
100 KCSAN_REPORT_RACE_UNKNOWN_ORIGIN,
101};
Ingo Molnar5cbaefe2019-11-20 10:41:43 +0100102
Marco Elverdfd402a2019-11-14 19:02:54 +0100103/*
104 * Print a race report from thread that encountered the race.
105 */
Ingo Molnar5cbaefe2019-11-20 10:41:43 +0100106extern void kcsan_report(const volatile void *ptr, size_t size, bool is_write,
107 bool value_change, int cpu_id, enum kcsan_report_type type);
Marco Elverdfd402a2019-11-14 19:02:54 +0100108
109#endif /* _KERNEL_KCSAN_KCSAN_H */