Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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