projects/linux·blob master · refs

482 lines · 18.0 KiB

1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Macros and attributes for compiler-based static context analysis.
4 */
5
6#ifndef _LINUX_COMPILER_CONTEXT_ANALYSIS_H
7#define _LINUX_COMPILER_CONTEXT_ANALYSIS_H
8
9#if defined(WARN_CONTEXT_ANALYSIS) && !defined(__CHECKER__) && !defined(__GENKSYMS__)
10
11/*
12 * These attributes define new context lock (Clang: capability) types.
13 * Internal only.
14 */
15# define __ctx_lock_type(name) __attribute__((capability(#name)))
16# define __reentrant_ctx_lock __attribute__((reentrant_capability))
17# define __acquires_ctx_lock(...) __attribute__((acquire_capability(__VA_ARGS__)))
18# define __acquires_shared_ctx_lock(...) __attribute__((acquire_shared_capability(__VA_ARGS__)))
19# define __try_acquires_ctx_lock(ret, var) __attribute__((try_acquire_capability(ret, var)))
20# define __try_acquires_shared_ctx_lock(ret, var) __attribute__((try_acquire_shared_capability(ret, var)))
21# define __releases_ctx_lock(...) __attribute__((release_capability(__VA_ARGS__)))
22# define __releases_shared_ctx_lock(...) __attribute__((release_shared_capability(__VA_ARGS__)))
23# define __returns_ctx_lock(var) __attribute__((lock_returned(var)))
24
25/*
26 * The below are used to annotate code being checked. Internal only.
27 */
28# define __excludes_ctx_lock(...) __attribute__((locks_excluded(__VA_ARGS__)))
29# define __requires_ctx_lock(...) __attribute__((requires_capability(__VA_ARGS__)))
30# define __requires_shared_ctx_lock(...) __attribute__((requires_shared_capability(__VA_ARGS__)))
31
32/*
33 * The "assert_capability" attribute is a bit confusingly named. It does not
34 * generate a check. Instead, it tells the analysis to *assume* the capability
35 * is held. This is used for augmenting runtime assertions, that can then help
36 * with patterns beyond the compiler's static reasoning abilities.
37 */
38# define __assumes_ctx_lock(...) __attribute__((assert_capability(__VA_ARGS__)))
39# define __assumes_shared_ctx_lock(...) __attribute__((assert_shared_capability(__VA_ARGS__)))
40
41/**
42 * __guarded_by() - struct member and globals attribute, declares variable
43 * only accessible within active context
44 * @...: context lock instance pointer(s)
45 *
46 * Declares that the struct member or global variable is only accessible within
47 * the context entered by the given context lock(s). Read operations on the data
48 * require shared access to at least one of the context locks, while write
49 * operations require exclusive access to all listed context locks.
50 *
51 * .. code-block:: c
52 *
53 * struct some_state {
54 * spinlock_t lock;
55 * long counter __guarded_by(&lock);
56 * };
57 *
58 * struct some_state {
59 * spinlock_t lock1, lock2;
60 * long counter __guarded_by(&lock1, &lock2);
61 * };
62 */
63# define __guarded_by(...) __attribute__((guarded_by(__VA_ARGS__)))
64
65/**
66 * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
67 * data only accessible within active context
68 * @...: context lock instance pointer(s)
69 *
70 * Declares that the data pointed to by the struct member pointer or global
71 * pointer is only accessible within the context entered by the given context
72 * lock(s). Read operations on the data require shared access to at least one
73 * of the context locks, while write operations require exclusive access to all
74 * listed context locks.
75 *
76 * .. code-block:: c
77 *
78 * struct some_state {
79 * spinlock_t lock;
80 * long *counter __pt_guarded_by(&lock);
81 * };
82 *
83 * struct some_state {
84 * spinlock_t lock1, lock2;
85 * long *counter __pt_guarded_by(&lock1, &lock2);
86 * };
87 */
88# define __pt_guarded_by(...) __attribute__((pt_guarded_by(__VA_ARGS__)))
89
90/**
91 * context_lock_struct() - declare or define a context lock struct
92 * @name: struct name
93 *
94 * Helper to declare or define a struct type that is also a context lock.
95 *
96 * .. code-block:: c
97 *
98 * context_lock_struct(my_handle) {
99 * int foo;
100 * long bar;
101 * };
102 *
103 * struct some_state {
104 * ...
105 * };
106 * // ... declared elsewhere ...
107 * context_lock_struct(some_state);
108 *
109 * Note: The implementation defines several helper functions that can acquire
110 * and release the context lock.
111 */
112# define context_lock_struct(name, ...) \
113 struct __ctx_lock_type(name) __VA_ARGS__ name; \
114 static __always_inline void __acquire_ctx_lock(const struct name *var) \
115 __attribute__((overloadable)) __no_context_analysis __acquires_ctx_lock(var) { } \
116 static __always_inline void __acquire_shared_ctx_lock(const struct name *var) \
117 __attribute__((overloadable)) __no_context_analysis __acquires_shared_ctx_lock(var) { } \
118 static __always_inline bool __try_acquire_ctx_lock(const struct name *var, bool ret) \
119 __attribute__((overloadable)) __no_context_analysis __try_acquires_ctx_lock(1, var) \
120 { return ret; } \
121 static __always_inline bool __try_acquire_shared_ctx_lock(const struct name *var, bool ret) \
122 __attribute__((overloadable)) __no_context_analysis __try_acquires_shared_ctx_lock(1, var) \
123 { return ret; } \
124 static __always_inline void __release_ctx_lock(const struct name *var) \
125 __attribute__((overloadable)) __no_context_analysis __releases_ctx_lock(var) { } \
126 static __always_inline void __release_shared_ctx_lock(const struct name *var) \
127 __attribute__((overloadable)) __no_context_analysis __releases_shared_ctx_lock(var) { } \
128 static __always_inline void __assume_ctx_lock(const struct name *var) \
129 __attribute__((overloadable)) __assumes_ctx_lock(var) { } \
130 static __always_inline void __assume_shared_ctx_lock(const struct name *var) \
131 __attribute__((overloadable)) __assumes_shared_ctx_lock(var) { } \
132 struct name
133
134/**
135 * disable_context_analysis() - disables context analysis
136 *
137 * Disables context analysis. Must be paired with a later
138 * enable_context_analysis().
139 */
140# define disable_context_analysis() \
141 __diag_push(); \
142 __diag_ignore_all("-Wunknown-warning-option", "") \
143 __diag_ignore_all("-Wthread-safety", "") \
144 __diag_ignore_all("-Wthread-safety-pointer", "")
145
146/**
147 * enable_context_analysis() - re-enables context analysis
148 *
149 * Re-enables context analysis. Must be paired with a prior
150 * disable_context_analysis().
151 */
152# define enable_context_analysis() __diag_pop()
153
154/**
155 * __no_context_analysis - function attribute, disables context analysis
156 *
157 * Function attribute denoting that context analysis is disabled for the
158 * whole function. Prefer use of `context_unsafe()` where possible.
159 */
160# define __no_context_analysis __attribute__((no_thread_safety_analysis))
161
162#else /* !WARN_CONTEXT_ANALYSIS */
163
164# define __ctx_lock_type(name)
165# define __reentrant_ctx_lock
166# define __acquires_ctx_lock(...)
167# define __acquires_shared_ctx_lock(...)
168# define __try_acquires_ctx_lock(ret, var)
169# define __try_acquires_shared_ctx_lock(ret, var)
170# define __releases_ctx_lock(...)
171# define __releases_shared_ctx_lock(...)
172# define __assumes_ctx_lock(...)
173# define __assumes_shared_ctx_lock(...)
174# define __returns_ctx_lock(var)
175# define __guarded_by(...)
176# define __pt_guarded_by(...)
177# define __excludes_ctx_lock(...)
178# define __requires_ctx_lock(...)
179# define __requires_shared_ctx_lock(...)
180# define __acquire_ctx_lock(var) do { } while (0)
181# define __acquire_shared_ctx_lock(var) do { } while (0)
182# define __try_acquire_ctx_lock(var, ret) (ret)
183# define __try_acquire_shared_ctx_lock(var, ret) (ret)
184# define __release_ctx_lock(var) do { } while (0)
185# define __release_shared_ctx_lock(var) do { } while (0)
186# define __assume_ctx_lock(var) do { (void)(var); } while (0)
187# define __assume_shared_ctx_lock(var) do { (void)(var); } while (0)
188# define context_lock_struct(name, ...) struct __VA_ARGS__ name
189# define disable_context_analysis()
190# define enable_context_analysis()
191# define __no_context_analysis
192
193#endif /* WARN_CONTEXT_ANALYSIS */
194
195/**
196 * context_unsafe() - disable context checking for contained code
197 *
198 * Disables context checking for contained statements or expression.
199 *
200 * .. code-block:: c
201 *
202 * struct some_data {
203 * spinlock_t lock;
204 * int counter __guarded_by(&lock);
205 * };
206 *
207 * int foo(struct some_data *d)
208 * {
209 * // ...
210 * // other code that is still checked ...
211 * // ...
212 * return context_unsafe(d->counter);
213 * }
214 */
215#define context_unsafe(...) \
216({ \
217 disable_context_analysis(); \
218 __VA_ARGS__; \
219 enable_context_analysis() \
220})
221
222/**
223 * __context_unsafe() - function attribute, disable context checking
224 * @comment: comment explaining why opt-out is safe
225 *
226 * Function attribute denoting that context analysis is disabled for the
227 * whole function. Forces adding an inline comment as argument.
228 */
229#define __context_unsafe(comment) __no_context_analysis
230
231/**
232 * context_unsafe_alias() - helper to insert a context lock "alias barrier"
233 * @p: pointer aliasing a context lock or object containing context locks
234 *
235 * No-op function that acts as a "context lock alias barrier", where the
236 * analysis rightfully detects that we're switching aliases, but the switch is
237 * considered safe but beyond the analysis reasoning abilities.
238 *
239 * This should be inserted before the first use of such an alias.
240 *
241 * Implementation Note: The compiler ignores aliases that may be reassigned but
242 * their value cannot be determined (e.g. when passing a non-const pointer to an
243 * alias as a function argument).
244 */
245#define context_unsafe_alias(p) _context_unsafe_alias((void **)&(p))
246static inline void _context_unsafe_alias(void **p) { }
247
248/**
249 * token_context_lock() - declare an abstract global context lock instance
250 * @name: token context lock name
251 *
252 * Helper that declares an abstract global context lock instance @name, but not
253 * backed by a real data structure (linker error if accidentally referenced).
254 * The type name is `__ctx_lock_@name`.
255 */
256#define token_context_lock(name, ...) \
257 context_lock_struct(__ctx_lock_##name, ##__VA_ARGS__) {}; \
258 extern const struct __ctx_lock_##name *name
259
260/**
261 * token_context_lock_instance() - declare another instance of a global context lock
262 * @ctx: token context lock previously declared with token_context_lock()
263 * @name: name of additional global context lock instance
264 *
265 * Helper that declares an additional instance @name of the same token context
266 * lock class @ctx. This is helpful where multiple related token contexts are
267 * declared, to allow using the same underlying type (`__ctx_lock_@ctx`) as
268 * function arguments.
269 */
270#define token_context_lock_instance(ctx, name) \
271 extern const struct __ctx_lock_##ctx *name
272
273/*
274 * Common keywords for static context analysis.
275 */
276
277/**
278 * __must_hold() - function attribute, caller must hold exclusive context lock
279 *
280 * Function attribute declaring that the caller must hold the given context
281 * lock instance(s) exclusively.
282 */
283#define __must_hold(...) __requires_ctx_lock(__VA_ARGS__)
284
285/**
286 * __must_not_hold() - function attribute, caller must not hold context lock
287 *
288 * Function attribute declaring that the caller must not hold the given context
289 * lock instance(s).
290 */
291#define __must_not_hold(...) __excludes_ctx_lock(__VA_ARGS__)
292
293/**
294 * __acquires() - function attribute, function acquires context lock exclusively
295 *
296 * Function attribute declaring that the function acquires the given context
297 * lock instance(s) exclusively, but does not release them.
298 */
299#define __acquires(...) __acquires_ctx_lock(__VA_ARGS__)
300
301/*
302 * Clang's analysis does not care precisely about the value, only that it is
303 * either zero or non-zero. So the __cond_acquires() interface might be
304 * misleading if we say that @ret is the value returned if acquired. Instead,
305 * provide symbolic variants which we translate.
306 */
307#define __cond_acquires_impl_true(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
308#define __cond_acquires_impl_false(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
309#define __cond_acquires_impl_nonzero(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
310#define __cond_acquires_impl_0(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
311#define __cond_acquires_impl_nonnull(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
312#define __cond_acquires_impl_NULL(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
313
314/**
315 * __cond_acquires() - function attribute, function conditionally
316 * acquires a context lock exclusively
317 * @ret: abstract value returned by function if context lock acquired
318 * @x: context lock instance pointer
319 *
320 * Function attribute declaring that the function conditionally acquires the
321 * given context lock instance @x exclusively, but does not release it. The
322 * function return value @ret denotes when the context lock is acquired.
323 *
324 * @ret may be one of: true, false, nonzero, 0, nonnull, NULL.
325 */
326#define __cond_acquires(ret, x) __cond_acquires_impl_##ret(x)
327
328/**
329 * __releases() - function attribute, function releases a context lock exclusively
330 *
331 * Function attribute declaring that the function releases the given context
332 * lock instance(s) exclusively. The associated context(s) must be active on
333 * entry.
334 */
335#define __releases(...) __releases_ctx_lock(__VA_ARGS__)
336
337/*
338 * Clang's analysis does not care precisely about the value, only that it is
339 * either zero or non-zero. So the __cond_acquires() interface might be
340 * misleading if we say that @ret is the value returned if acquired. Instead,
341 * provide symbolic variants which we translate.
342 */
343#define __cond_acquires_impl_not_true(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
344#define __cond_acquires_impl_not_false(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
345#define __cond_acquires_impl_not_nonzero(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
346#define __cond_acquires_impl_not_0(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
347#define __cond_acquires_impl_not_nonnull(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
348#define __cond_acquires_impl_not_NULL(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
349
350/**
351 * __cond_releases() - function attribute, function conditionally
352 * releases a context lock exclusively
353 * @ret: abstract value returned by function if context lock releases
354 * @x: context lock instance pointer
355 *
356 * Function attribute declaring that the function conditionally releases the
357 * given context lock instance @x exclusively. The associated context(s) must
358 * be active on entry. The function return value @ret denotes when the context
359 * lock is released.
360 *
361 * @ret may be one of: true, false, nonzero, 0, nonnull, NULL.
362 *
363 * NOTE: clang does not have a native attribute for this; instead implement
364 * it as an unconditional release and a conditional acquire for the
365 * inverted condition -- which is semantically equivalent.
366 */
367#define __cond_releases(ret, x) __releases(x) __cond_acquires_impl_not_##ret(x)
368
369/**
370 * __acquire() - function to acquire context lock exclusively
371 * @x: context lock instance pointer
372 *
373 * No-op function that acquires the given context lock instance @x exclusively.
374 */
375#define __acquire(x) __acquire_ctx_lock(x)
376
377/**
378 * __release() - function to release context lock exclusively
379 * @x: context lock instance pointer
380 *
381 * No-op function that releases the given context lock instance @x.
382 */
383#define __release(x) __release_ctx_lock(x)
384
385/**
386 * __must_hold_shared() - function attribute, caller must hold shared context lock
387 *
388 * Function attribute declaring that the caller must hold the given context
389 * lock instance(s) with shared access.
390 */
391#define __must_hold_shared(...) __requires_shared_ctx_lock(__VA_ARGS__)
392
393/**
394 * __acquires_shared() - function attribute, function acquires context lock shared
395 *
396 * Function attribute declaring that the function acquires the given
397 * context lock instance(s) with shared access, but does not release them.
398 */
399#define __acquires_shared(...) __acquires_shared_ctx_lock(__VA_ARGS__)
400
401/**
402 * __cond_acquires_shared() - function attribute, function conditionally
403 * acquires a context lock shared
404 * @ret: abstract value returned by function if context lock acquired
405 * @x: context lock instance pointer
406 *
407 * Function attribute declaring that the function conditionally acquires the
408 * given context lock instance @x with shared access, but does not release it.
409 * The function return value @ret denotes when the context lock is acquired.
410 *
411 * @ret may be one of: true, false, nonzero, 0, nonnull, NULL.
412 */
413#define __cond_acquires_shared(ret, x) __cond_acquires_impl_##ret(x, _shared)
414
415/**
416 * __releases_shared() - function attribute, function releases a
417 * context lock shared
418 *
419 * Function attribute declaring that the function releases the given context
420 * lock instance(s) with shared access. The associated context(s) must be
421 * active on entry.
422 */
423#define __releases_shared(...) __releases_shared_ctx_lock(__VA_ARGS__)
424
425/**
426 * __acquire_shared() - function to acquire context lock shared
427 * @x: context lock instance pointer
428 *
429 * No-op function that acquires the given context lock instance @x with shared
430 * access.
431 */
432#define __acquire_shared(x) __acquire_shared_ctx_lock(x)
433
434/**
435 * __release_shared() - function to release context lock shared
436 * @x: context lock instance pointer
437 *
438 * No-op function that releases the given context lock instance @x with shared
439 * access.
440 */
441#define __release_shared(x) __release_shared_ctx_lock(x)
442
443/**
444 * __acquire_ret() - helper to acquire context lock of return value
445 * @call: call expression
446 * @ret_expr: acquire expression that uses __ret
447 */
448#define __acquire_ret(call, ret_expr) \
449 ({ \
450 __auto_type __ret = call; \
451 __acquire(ret_expr); \
452 __ret; \
453 })
454
455/**
456 * __acquire_shared_ret() - helper to acquire context lock shared of return value
457 * @call: call expression
458 * @ret_expr: acquire shared expression that uses __ret
459 */
460#define __acquire_shared_ret(call, ret_expr) \
461 ({ \
462 __auto_type __ret = call; \
463 __acquire_shared(ret_expr); \
464 __ret; \
465 })
466
467/*
468 * Attributes to mark functions returning acquired context locks.
469 *
470 * This is purely cosmetic to help readability, and should be used with the
471 * above macros as follows:
472 *
473 * struct foo { spinlock_t lock; ... };
474 * ...
475 * #define myfunc(...) __acquire_ret(_myfunc(__VA_ARGS__), &__ret->lock)
476 * struct foo *_myfunc(int bar) __acquires_ret;
477 * ...
478 */
479#define __acquires_ret __no_context_analysis
480#define __acquires_shared_ret __no_context_analysis
481
482#endif /* _LINUX_COMPILER_CONTEXT_ANALYSIS_H */