xref: /linux-6.15/include/linux/kcsan.h (revision dfd402a4)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 #ifndef _LINUX_KCSAN_H
4 #define _LINUX_KCSAN_H
5 
6 #include <linux/kcsan-checks.h>
7 #include <linux/types.h>
8 
9 #ifdef CONFIG_KCSAN
10 
11 /*
12  * Context for each thread of execution: for tasks, this is stored in
13  * task_struct, and interrupts access internal per-CPU storage.
14  */
15 struct kcsan_ctx {
16 	int disable_count; /* disable counter */
17 	int atomic_next; /* number of following atomic ops */
18 
19 	/*
20 	 * We distinguish between: (a) nestable atomic regions that may contain
21 	 * other nestable regions; and (b) flat atomic regions that do not keep
22 	 * track of nesting. Both (a) and (b) are entirely independent of each
23 	 * other, and a flat region may be started in a nestable region or
24 	 * vice-versa.
25 	 *
26 	 * This is required because, for example, in the annotations for
27 	 * seqlocks, we declare seqlock writer critical sections as (a) nestable
28 	 * atomic regions, but reader critical sections as (b) flat atomic
29 	 * regions, but have encountered cases where seqlock reader critical
30 	 * sections are contained within writer critical sections (the opposite
31 	 * may be possible, too).
32 	 *
33 	 * To support these cases, we independently track the depth of nesting
34 	 * for (a), and whether the leaf level is flat for (b).
35 	 */
36 	int atomic_nest_count;
37 	bool in_flat_atomic;
38 };
39 
40 /**
41  * kcsan_init - initialize KCSAN runtime
42  */
43 void kcsan_init(void);
44 
45 /**
46  * kcsan_disable_current - disable KCSAN for the current context
47  *
48  * Supports nesting.
49  */
50 void kcsan_disable_current(void);
51 
52 /**
53  * kcsan_enable_current - re-enable KCSAN for the current context
54  *
55  * Supports nesting.
56  */
57 void kcsan_enable_current(void);
58 
59 /**
60  * kcsan_nestable_atomic_begin - begin nestable atomic region
61  *
62  * Accesses within the atomic region may appear to race with other accesses but
63  * should be considered atomic.
64  */
65 void kcsan_nestable_atomic_begin(void);
66 
67 /**
68  * kcsan_nestable_atomic_end - end nestable atomic region
69  */
70 void kcsan_nestable_atomic_end(void);
71 
72 /**
73  * kcsan_flat_atomic_begin - begin flat atomic region
74  *
75  * Accesses within the atomic region may appear to race with other accesses but
76  * should be considered atomic.
77  */
78 void kcsan_flat_atomic_begin(void);
79 
80 /**
81  * kcsan_flat_atomic_end - end flat atomic region
82  */
83 void kcsan_flat_atomic_end(void);
84 
85 /**
86  * kcsan_atomic_next - consider following accesses as atomic
87  *
88  * Force treating the next n memory accesses for the current context as atomic
89  * operations.
90  *
91  * @n number of following memory accesses to treat as atomic.
92  */
93 void kcsan_atomic_next(int n);
94 
95 #else /* CONFIG_KCSAN */
96 
97 static inline void kcsan_init(void) { }
98 
99 static inline void kcsan_disable_current(void) { }
100 
101 static inline void kcsan_enable_current(void) { }
102 
103 static inline void kcsan_nestable_atomic_begin(void) { }
104 
105 static inline void kcsan_nestable_atomic_end(void) { }
106 
107 static inline void kcsan_flat_atomic_begin(void) { }
108 
109 static inline void kcsan_flat_atomic_end(void) { }
110 
111 static inline void kcsan_atomic_next(int n) { }
112 
113 #endif /* CONFIG_KCSAN */
114 
115 #endif /* _LINUX_KCSAN_H */
116