XenevaOS
Loading...
Searching...
No Matches
kcsan-checks.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * KCSAN access checks and modifiers. These can be used to explicitly check
4 * uninstrumented accesses, or change KCSAN checking behaviour of accesses.
5 *
6 * Copyright (C) 2019, Google LLC.
7 */
8
9#ifndef _LINUX_KCSAN_CHECKS_H
10#define _LINUX_KCSAN_CHECKS_H
11
12/* Note: Only include what is already included by compiler.h. */
14#include <linux/types.h>
15
16/* Access types -- if KCSAN_ACCESS_WRITE is not set, the access is a read. */
17#define KCSAN_ACCESS_WRITE (1 << 0) /* Access is a write. */
18#define KCSAN_ACCESS_COMPOUND (1 << 1) /* Compounded read-write instrumentation. */
19#define KCSAN_ACCESS_ATOMIC (1 << 2) /* Access is atomic. */
20/* The following are special, and never due to compiler instrumentation. */
21#define KCSAN_ACCESS_ASSERT (1 << 3) /* Access is an assertion. */
22#define KCSAN_ACCESS_SCOPED (1 << 4) /* Access is a scoped access. */
23
24/*
25 * __kcsan_*: Always calls into the runtime when KCSAN is enabled. This may be used
26 * even in compilation units that selectively disable KCSAN, but must use KCSAN
27 * to validate access to an address. Never use these in header files!
28 */
29#ifdef CONFIG_KCSAN
37void __kcsan_check_access(const volatile void *ptr, size_t size, int type);
38
39/*
40 * See definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
41 * Note: The mappings are arbitrary, and do not reflect any real mappings of C11
42 * memory orders to the LKMM memory orders and vice-versa!
43 */
44#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_mb __ATOMIC_SEQ_CST
45#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_wmb __ATOMIC_ACQ_REL
46#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_rmb __ATOMIC_ACQUIRE
47#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_release __ATOMIC_RELEASE
48
52void __kcsan_mb(void);
53
57void __kcsan_wmb(void);
58
62void __kcsan_rmb(void);
63
67void __kcsan_release(void);
68
74void kcsan_disable_current(void);
75
81void kcsan_enable_current(void);
82void kcsan_enable_current_nowarn(void); /* Safe in uaccess regions. */
83
90void kcsan_nestable_atomic_begin(void);
91
95void kcsan_nestable_atomic_end(void);
96
103void kcsan_flat_atomic_begin(void);
104
108void kcsan_flat_atomic_end(void);
109
118void kcsan_atomic_next(int n);
119
128void kcsan_set_access_mask(unsigned long mask);
129
130/* Scoped access information. */
131struct kcsan_scoped_access {
132 union {
133 struct list_head list; /* scoped_accesses list */
134 /*
135 * Not an entry in scoped_accesses list; stack depth from where
136 * the access was initialized.
137 */
138 int stack_depth;
139 };
140
141 /* Access information. */
142 const volatile void *ptr;
143 size_t size;
144 int type;
145 /* Location where scoped access was set up. */
146 unsigned long ip;
147};
148/*
149 * Automatically call kcsan_end_scoped_access() when kcsan_scoped_access goes
150 * out of scope; relies on attribute "cleanup", which is supported by all
151 * compilers that support KCSAN.
152 */
153#define __kcsan_cleanup_scoped \
154 __maybe_unused __attribute__((__cleanup__(kcsan_end_scoped_access)))
155
172struct kcsan_scoped_access *
173kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
174 struct kcsan_scoped_access *sa);
175
184void kcsan_end_scoped_access(struct kcsan_scoped_access *sa);
185
186
187#else /* CONFIG_KCSAN */
188
189static inline void __kcsan_check_access(const volatile void *ptr, size_t size,
190 int type) { }
191
192static inline void __kcsan_mb(void) { }
193static inline void __kcsan_wmb(void) { }
194static inline void __kcsan_rmb(void) { }
195static inline void __kcsan_release(void) { }
196static inline void kcsan_disable_current(void) { }
197static inline void kcsan_enable_current(void) { }
198static inline void kcsan_enable_current_nowarn(void) { }
199static inline void kcsan_nestable_atomic_begin(void) { }
200static inline void kcsan_nestable_atomic_end(void) { }
201static inline void kcsan_flat_atomic_begin(void) { }
202static inline void kcsan_flat_atomic_end(void) { }
203static inline void kcsan_atomic_next(int n) { }
204static inline void kcsan_set_access_mask(unsigned long mask) { }
205
207#define __kcsan_cleanup_scoped __maybe_unused
208static inline struct kcsan_scoped_access *
209kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
210 struct kcsan_scoped_access *sa) { return sa; }
211static inline void kcsan_end_scoped_access(struct kcsan_scoped_access *sa) { }
212
213#endif /* CONFIG_KCSAN */
214
215#ifdef __SANITIZE_THREAD__
216/*
217 * Only calls into the runtime when the particular compilation unit has KCSAN
218 * instrumentation enabled. May be used in header files.
219 */
220#define kcsan_check_access __kcsan_check_access
221
222/*
223 * Only use these to disable KCSAN for accesses in the current compilation unit;
224 * calls into libraries may still perform KCSAN checks.
225 */
226#define __kcsan_disable_current kcsan_disable_current
227#define __kcsan_enable_current kcsan_enable_current_nowarn
228#else /* __SANITIZE_THREAD__ */
229static inline void kcsan_check_access(const volatile void *ptr, size_t size,
230 int type) { }
231static inline void __kcsan_enable_current(void) { }
232static inline void __kcsan_disable_current(void) { }
233#endif /* __SANITIZE_THREAD__ */
234
235#if defined(CONFIG_KCSAN_WEAK_MEMORY) && defined(__SANITIZE_THREAD__)
236/*
237 * Normal barrier instrumentation is not done via explicit calls, but by mapping
238 * to a repurposed __atomic_signal_fence(), which normally does not generate any
239 * real instructions, but is still intercepted by fsanitize=thread. This means,
240 * like any other compile-time instrumentation, barrier instrumentation can be
241 * disabled with the __no_kcsan function attribute.
242 *
243 * Also see definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
244 *
245 * These are all macros, like <asm/barrier.h>, since some architectures use them
246 * in non-static inline functions.
247 */
248#define __KCSAN_BARRIER_TO_SIGNAL_FENCE(name) \
249 do { \
250 barrier(); \
251 __atomic_signal_fence(__KCSAN_BARRIER_TO_SIGNAL_FENCE_##name); \
252 barrier(); \
253 } while (0)
254#define kcsan_mb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(mb)
255#define kcsan_wmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(wmb)
256#define kcsan_rmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(rmb)
257#define kcsan_release() __KCSAN_BARRIER_TO_SIGNAL_FENCE(release)
258#elif defined(CONFIG_KCSAN_WEAK_MEMORY) && defined(__KCSAN_INSTRUMENT_BARRIERS__)
259#define kcsan_mb __kcsan_mb
260#define kcsan_wmb __kcsan_wmb
261#define kcsan_rmb __kcsan_rmb
262#define kcsan_release __kcsan_release
263#else /* CONFIG_KCSAN_WEAK_MEMORY && ... */
264#define kcsan_mb() do { } while (0)
265#define kcsan_wmb() do { } while (0)
266#define kcsan_rmb() do { } while (0)
267#define kcsan_release() do { } while (0)
268#endif /* CONFIG_KCSAN_WEAK_MEMORY && ... */
269
276#define __kcsan_check_read(ptr, size) __kcsan_check_access(ptr, size, 0)
277
284#define __kcsan_check_write(ptr, size) \
285 __kcsan_check_access(absolute_pointer(ptr), size, KCSAN_ACCESS_WRITE)
286
293#define __kcsan_check_read_write(ptr, size) \
294 __kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE)
295
302#define kcsan_check_read(ptr, size) kcsan_check_access(ptr, size, 0)
303
310#define kcsan_check_write(ptr, size) \
311 kcsan_check_access(absolute_pointer(ptr), size, KCSAN_ACCESS_WRITE)
312
319#define kcsan_check_read_write(ptr, size) \
320 kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE)
321
322/*
323 * Check for atomic accesses: if atomic accesses are not ignored, this simply
324 * aliases to kcsan_check_access(), otherwise becomes a no-op.
325 */
326#ifdef CONFIG_KCSAN_IGNORE_ATOMICS
327#define kcsan_check_atomic_read(...) do { } while (0)
328#define kcsan_check_atomic_write(...) do { } while (0)
329#define kcsan_check_atomic_read_write(...) do { } while (0)
330#else
331#define kcsan_check_atomic_read(ptr, size) \
332 kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC)
333#define kcsan_check_atomic_write(ptr, size) \
334 kcsan_check_access(absolute_pointer(ptr), size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE)
335#define kcsan_check_atomic_read_write(ptr, size) \
336 kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_COMPOUND)
337#endif
338
370#define ASSERT_EXCLUSIVE_WRITER(var) \
371 __kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT)
372
373/*
374 * Helper macros for implementation of for ASSERT_EXCLUSIVE_*_SCOPED(). @id is
375 * expected to be unique for the scope in which instances of kcsan_scoped_access
376 * are declared.
377 */
378#define __kcsan_scoped_name(c, suffix) __kcsan_scoped_##c##suffix
379#define __ASSERT_EXCLUSIVE_SCOPED(var, type, id) \
380 struct kcsan_scoped_access __kcsan_scoped_name(id, _) \
381 __kcsan_cleanup_scoped; \
382 struct kcsan_scoped_access *__kcsan_scoped_name(id, _dummy_p) \
383 __maybe_unused = kcsan_begin_scoped_access( \
384 &(var), sizeof(var), KCSAN_ACCESS_SCOPED | (type), \
385 &__kcsan_scoped_name(id, _))
386
419#define ASSERT_EXCLUSIVE_WRITER_SCOPED(var) \
420 __ASSERT_EXCLUSIVE_SCOPED(var, KCSAN_ACCESS_ASSERT, __COUNTER__)
421
451#define ASSERT_EXCLUSIVE_ACCESS(var) \
452 __kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT)
453
467#define ASSERT_EXCLUSIVE_ACCESS_SCOPED(var) \
468 __ASSERT_EXCLUSIVE_SCOPED(var, KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT, __COUNTER__)
469
525#define ASSERT_EXCLUSIVE_BITS(var, mask) \
526 do { \
527 kcsan_set_access_mask(mask); \
528 __kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT);\
529 kcsan_set_access_mask(0); \
530 kcsan_atomic_next(1); \
531 } while (0)
532
533#endif /* _LINUX_KCSAN_CHECKS_H */
XEProcessList * list
Definition main.cpp:27
size_t size
Definition drm_bridge.h:1299
Definition kcsan-checks.h:206
Definition list.h:11