KCSAN updates for v5.17
This series provides KCSAN fixes and also the ability to take memory barriers into account for weakly-ordered systems. This last can increase the probability of detecting certain types of data races. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEbK7UrM+RBIrCoViJnr8S83LZ+4wFAmHbuRwTHHBhdWxtY2tA a2VybmVsLm9yZwAKCRCevxLzctn7jKDPEACWuzYnd/u/02AHyRd3PIF3Px9uFKlK TFwaXX95oYSFCXcrmO42YtDUlZm4QcbwNb85KMCu1DvckRtIsNw0rkBU7BGyqv3Z ZoJEfMNpmC0x9+IFBOeseBHySPVT0x7GmYus05MSh0OLfkbCfyImmxRzgoKJGL+A ADF9EQb4z2feWjmVEoN8uRaarCAD4f77rSXiX6oTCNDuKrHarqMld/TmoXFrJbu2 QtfwHeyvraKBnZdUoYfVbGVenyKb1vMv4bUlvrOcuJEgIi/J/th4FupR3XCGYulI aWJTl2TQTGnMoE8VnFHgI27I841w3k5PVL+Y1hr/S4uN1/rIoQQuBzCtlnFeCksa BiBXsHIchN8N0Dwh8zD8NMd2uxV4t3fmpxXTDAwaOm7vs5hA8AJ0XNu6Sz94Lyjv wk2CxX41WWUNJVo3gh6SrS4mL6lC8+VvHF1hbIap++jrevj58gj1jAR1fdx4ANlT e2qA00EeoMngEogDNZH42/Fxs3H9zxrBta2ZbkPkwzIqTHH+4pIQDCy2xO3T3oxc twdGPYpjYdkf79EGsG4I4R/VA/IfcS09VIWTce8xSDeSnqkgFhcG37r1orJe8hTB tH+ODkNOsz5HaEoa8OoAL4ko2l0fL99p2AtMPpuQfHjRj7aorF+dJIrqCizASxwx 37PjQgOmHeDHgQ== =Q5fg -----END PGP SIGNATURE----- Merge tag 'kcsan.2022.01.09a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu Pull KCSAN updates from Paul McKenney: "This provides KCSAN fixes and also the ability to take memory barriers into account for weakly-ordered systems. This last can increase the probability of detecting certain types of data races" * tag 'kcsan.2022.01.09a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: (29 commits) kcsan: Only test clear_bit_unlock_is_negative_byte if arch defines it kcsan: Avoid nested contexts reading inconsistent reorder_access kcsan: Turn barrier instrumentation into macros kcsan: Make barrier tests compatible with lockdep kcsan: Support WEAK_MEMORY with Clang where no objtool support exists compiler_attributes.h: Add __disable_sanitizer_instrumentation objtool, kcsan: Remove memory barrier instrumentation from noinstr objtool, kcsan: Add memory barrier instrumentation to whitelist sched, kcsan: Enable memory barrier instrumentation mm, kcsan: Enable barrier instrumentation x86/qspinlock, kcsan: Instrument barrier of pv_queued_spin_unlock() x86/barriers, kcsan: Use generic instrumentation for non-smp barriers asm-generic/bitops, kcsan: Add instrumentation for barriers locking/atomics, kcsan: Add instrumentation for barriers locking/barriers, kcsan: Support generic instrumentation locking/barriers, kcsan: Add instrumentation for barriers kcsan: selftest: Add test case to check memory barrier instrumentation kcsan: Ignore GCC 11+ warnings about TSan runtime support kcsan: test: Add test cases for memory barrier instrumentation kcsan: test: Match reordered or normal accesses ...
This commit is contained in:
commit
1be5bdf8cd
27 changed files with 1346 additions and 171 deletions
|
|
@ -45,6 +45,7 @@ atomic_set(atomic_t *v, int i)
|
|||
static __always_inline void
|
||||
atomic_set_release(atomic_t *v, int i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_write(v, sizeof(*v));
|
||||
arch_atomic_set_release(v, i);
|
||||
}
|
||||
|
|
@ -59,6 +60,7 @@ atomic_add(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_add_return(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_add_return(i, v);
|
||||
}
|
||||
|
|
@ -73,6 +75,7 @@ atomic_add_return_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_add_return_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_add_return_release(i, v);
|
||||
}
|
||||
|
|
@ -87,6 +90,7 @@ atomic_add_return_relaxed(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_add(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_add(i, v);
|
||||
}
|
||||
|
|
@ -101,6 +105,7 @@ atomic_fetch_add_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_add_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_add_release(i, v);
|
||||
}
|
||||
|
|
@ -122,6 +127,7 @@ atomic_sub(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_sub_return(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_sub_return(i, v);
|
||||
}
|
||||
|
|
@ -136,6 +142,7 @@ atomic_sub_return_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_sub_return_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_sub_return_release(i, v);
|
||||
}
|
||||
|
|
@ -150,6 +157,7 @@ atomic_sub_return_relaxed(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_sub(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_sub(i, v);
|
||||
}
|
||||
|
|
@ -164,6 +172,7 @@ atomic_fetch_sub_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_sub_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_sub_release(i, v);
|
||||
}
|
||||
|
|
@ -185,6 +194,7 @@ atomic_inc(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_inc_return(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_inc_return(v);
|
||||
}
|
||||
|
|
@ -199,6 +209,7 @@ atomic_inc_return_acquire(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_inc_return_release(atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_inc_return_release(v);
|
||||
}
|
||||
|
|
@ -213,6 +224,7 @@ atomic_inc_return_relaxed(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_inc(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_inc(v);
|
||||
}
|
||||
|
|
@ -227,6 +239,7 @@ atomic_fetch_inc_acquire(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_inc_release(atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_inc_release(v);
|
||||
}
|
||||
|
|
@ -248,6 +261,7 @@ atomic_dec(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_dec_return(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_dec_return(v);
|
||||
}
|
||||
|
|
@ -262,6 +276,7 @@ atomic_dec_return_acquire(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_dec_return_release(atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_dec_return_release(v);
|
||||
}
|
||||
|
|
@ -276,6 +291,7 @@ atomic_dec_return_relaxed(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_dec(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_dec(v);
|
||||
}
|
||||
|
|
@ -290,6 +306,7 @@ atomic_fetch_dec_acquire(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_dec_release(atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_dec_release(v);
|
||||
}
|
||||
|
|
@ -311,6 +328,7 @@ atomic_and(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_and(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_and(i, v);
|
||||
}
|
||||
|
|
@ -325,6 +343,7 @@ atomic_fetch_and_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_and_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_and_release(i, v);
|
||||
}
|
||||
|
|
@ -346,6 +365,7 @@ atomic_andnot(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_andnot(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_andnot(i, v);
|
||||
}
|
||||
|
|
@ -360,6 +380,7 @@ atomic_fetch_andnot_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_andnot_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_andnot_release(i, v);
|
||||
}
|
||||
|
|
@ -381,6 +402,7 @@ atomic_or(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_or(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_or(i, v);
|
||||
}
|
||||
|
|
@ -395,6 +417,7 @@ atomic_fetch_or_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_or_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_or_release(i, v);
|
||||
}
|
||||
|
|
@ -416,6 +439,7 @@ atomic_xor(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_xor(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_xor(i, v);
|
||||
}
|
||||
|
|
@ -430,6 +454,7 @@ atomic_fetch_xor_acquire(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_xor_release(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_xor_release(i, v);
|
||||
}
|
||||
|
|
@ -444,6 +469,7 @@ atomic_fetch_xor_relaxed(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_xchg(atomic_t *v, int i)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_xchg(v, i);
|
||||
}
|
||||
|
|
@ -458,6 +484,7 @@ atomic_xchg_acquire(atomic_t *v, int i)
|
|||
static __always_inline int
|
||||
atomic_xchg_release(atomic_t *v, int i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_xchg_release(v, i);
|
||||
}
|
||||
|
|
@ -472,6 +499,7 @@ atomic_xchg_relaxed(atomic_t *v, int i)
|
|||
static __always_inline int
|
||||
atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_cmpxchg(v, old, new);
|
||||
}
|
||||
|
|
@ -486,6 +514,7 @@ atomic_cmpxchg_acquire(atomic_t *v, int old, int new)
|
|||
static __always_inline int
|
||||
atomic_cmpxchg_release(atomic_t *v, int old, int new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_cmpxchg_release(v, old, new);
|
||||
}
|
||||
|
|
@ -500,6 +529,7 @@ atomic_cmpxchg_relaxed(atomic_t *v, int old, int new)
|
|||
static __always_inline bool
|
||||
atomic_try_cmpxchg(atomic_t *v, int *old, int new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic_try_cmpxchg(v, old, new);
|
||||
|
|
@ -516,6 +546,7 @@ atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
|
|||
static __always_inline bool
|
||||
atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic_try_cmpxchg_release(v, old, new);
|
||||
|
|
@ -532,6 +563,7 @@ atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
|
|||
static __always_inline bool
|
||||
atomic_sub_and_test(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_sub_and_test(i, v);
|
||||
}
|
||||
|
|
@ -539,6 +571,7 @@ atomic_sub_and_test(int i, atomic_t *v)
|
|||
static __always_inline bool
|
||||
atomic_dec_and_test(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_dec_and_test(v);
|
||||
}
|
||||
|
|
@ -546,6 +579,7 @@ atomic_dec_and_test(atomic_t *v)
|
|||
static __always_inline bool
|
||||
atomic_inc_and_test(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_inc_and_test(v);
|
||||
}
|
||||
|
|
@ -553,6 +587,7 @@ atomic_inc_and_test(atomic_t *v)
|
|||
static __always_inline bool
|
||||
atomic_add_negative(int i, atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_add_negative(i, v);
|
||||
}
|
||||
|
|
@ -560,6 +595,7 @@ atomic_add_negative(int i, atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_fetch_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_fetch_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -567,6 +603,7 @@ atomic_fetch_add_unless(atomic_t *v, int a, int u)
|
|||
static __always_inline bool
|
||||
atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -574,6 +611,7 @@ atomic_add_unless(atomic_t *v, int a, int u)
|
|||
static __always_inline bool
|
||||
atomic_inc_not_zero(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_inc_not_zero(v);
|
||||
}
|
||||
|
|
@ -581,6 +619,7 @@ atomic_inc_not_zero(atomic_t *v)
|
|||
static __always_inline bool
|
||||
atomic_inc_unless_negative(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_inc_unless_negative(v);
|
||||
}
|
||||
|
|
@ -588,6 +627,7 @@ atomic_inc_unless_negative(atomic_t *v)
|
|||
static __always_inline bool
|
||||
atomic_dec_unless_positive(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_dec_unless_positive(v);
|
||||
}
|
||||
|
|
@ -595,6 +635,7 @@ atomic_dec_unless_positive(atomic_t *v)
|
|||
static __always_inline int
|
||||
atomic_dec_if_positive(atomic_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_dec_if_positive(v);
|
||||
}
|
||||
|
|
@ -623,6 +664,7 @@ atomic64_set(atomic64_t *v, s64 i)
|
|||
static __always_inline void
|
||||
atomic64_set_release(atomic64_t *v, s64 i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_write(v, sizeof(*v));
|
||||
arch_atomic64_set_release(v, i);
|
||||
}
|
||||
|
|
@ -637,6 +679,7 @@ atomic64_add(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_add_return(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_add_return(i, v);
|
||||
}
|
||||
|
|
@ -651,6 +694,7 @@ atomic64_add_return_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_add_return_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_add_return_release(i, v);
|
||||
}
|
||||
|
|
@ -665,6 +709,7 @@ atomic64_add_return_relaxed(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_add(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_add(i, v);
|
||||
}
|
||||
|
|
@ -679,6 +724,7 @@ atomic64_fetch_add_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_add_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_add_release(i, v);
|
||||
}
|
||||
|
|
@ -700,6 +746,7 @@ atomic64_sub(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_sub_return(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_sub_return(i, v);
|
||||
}
|
||||
|
|
@ -714,6 +761,7 @@ atomic64_sub_return_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_sub_return_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_sub_return_release(i, v);
|
||||
}
|
||||
|
|
@ -728,6 +776,7 @@ atomic64_sub_return_relaxed(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_sub(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_sub(i, v);
|
||||
}
|
||||
|
|
@ -742,6 +791,7 @@ atomic64_fetch_sub_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_sub_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_sub_release(i, v);
|
||||
}
|
||||
|
|
@ -763,6 +813,7 @@ atomic64_inc(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_inc_return(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_inc_return(v);
|
||||
}
|
||||
|
|
@ -777,6 +828,7 @@ atomic64_inc_return_acquire(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_inc_return_release(atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_inc_return_release(v);
|
||||
}
|
||||
|
|
@ -791,6 +843,7 @@ atomic64_inc_return_relaxed(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_inc(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_inc(v);
|
||||
}
|
||||
|
|
@ -805,6 +858,7 @@ atomic64_fetch_inc_acquire(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_inc_release(atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_inc_release(v);
|
||||
}
|
||||
|
|
@ -826,6 +880,7 @@ atomic64_dec(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_dec_return(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_dec_return(v);
|
||||
}
|
||||
|
|
@ -840,6 +895,7 @@ atomic64_dec_return_acquire(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_dec_return_release(atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_dec_return_release(v);
|
||||
}
|
||||
|
|
@ -854,6 +910,7 @@ atomic64_dec_return_relaxed(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_dec(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_dec(v);
|
||||
}
|
||||
|
|
@ -868,6 +925,7 @@ atomic64_fetch_dec_acquire(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_dec_release(atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_dec_release(v);
|
||||
}
|
||||
|
|
@ -889,6 +947,7 @@ atomic64_and(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_and(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_and(i, v);
|
||||
}
|
||||
|
|
@ -903,6 +962,7 @@ atomic64_fetch_and_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_and_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_and_release(i, v);
|
||||
}
|
||||
|
|
@ -924,6 +984,7 @@ atomic64_andnot(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_andnot(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_andnot(i, v);
|
||||
}
|
||||
|
|
@ -938,6 +999,7 @@ atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_andnot_release(i, v);
|
||||
}
|
||||
|
|
@ -959,6 +1021,7 @@ atomic64_or(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_or(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_or(i, v);
|
||||
}
|
||||
|
|
@ -973,6 +1036,7 @@ atomic64_fetch_or_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_or_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_or_release(i, v);
|
||||
}
|
||||
|
|
@ -994,6 +1058,7 @@ atomic64_xor(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_xor(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_xor(i, v);
|
||||
}
|
||||
|
|
@ -1008,6 +1073,7 @@ atomic64_fetch_xor_acquire(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_xor_release(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_xor_release(i, v);
|
||||
}
|
||||
|
|
@ -1022,6 +1088,7 @@ atomic64_fetch_xor_relaxed(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_xchg(atomic64_t *v, s64 i)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_xchg(v, i);
|
||||
}
|
||||
|
|
@ -1036,6 +1103,7 @@ atomic64_xchg_acquire(atomic64_t *v, s64 i)
|
|||
static __always_inline s64
|
||||
atomic64_xchg_release(atomic64_t *v, s64 i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_xchg_release(v, i);
|
||||
}
|
||||
|
|
@ -1050,6 +1118,7 @@ atomic64_xchg_relaxed(atomic64_t *v, s64 i)
|
|||
static __always_inline s64
|
||||
atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_cmpxchg(v, old, new);
|
||||
}
|
||||
|
|
@ -1064,6 +1133,7 @@ atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new)
|
|||
static __always_inline s64
|
||||
atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_cmpxchg_release(v, old, new);
|
||||
}
|
||||
|
|
@ -1078,6 +1148,7 @@ atomic64_cmpxchg_relaxed(atomic64_t *v, s64 old, s64 new)
|
|||
static __always_inline bool
|
||||
atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic64_try_cmpxchg(v, old, new);
|
||||
|
|
@ -1094,6 +1165,7 @@ atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
|
|||
static __always_inline bool
|
||||
atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic64_try_cmpxchg_release(v, old, new);
|
||||
|
|
@ -1110,6 +1182,7 @@ atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
|
|||
static __always_inline bool
|
||||
atomic64_sub_and_test(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_sub_and_test(i, v);
|
||||
}
|
||||
|
|
@ -1117,6 +1190,7 @@ atomic64_sub_and_test(s64 i, atomic64_t *v)
|
|||
static __always_inline bool
|
||||
atomic64_dec_and_test(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_dec_and_test(v);
|
||||
}
|
||||
|
|
@ -1124,6 +1198,7 @@ atomic64_dec_and_test(atomic64_t *v)
|
|||
static __always_inline bool
|
||||
atomic64_inc_and_test(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_inc_and_test(v);
|
||||
}
|
||||
|
|
@ -1131,6 +1206,7 @@ atomic64_inc_and_test(atomic64_t *v)
|
|||
static __always_inline bool
|
||||
atomic64_add_negative(s64 i, atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_add_negative(i, v);
|
||||
}
|
||||
|
|
@ -1138,6 +1214,7 @@ atomic64_add_negative(s64 i, atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_fetch_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -1145,6 +1222,7 @@ atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
|||
static __always_inline bool
|
||||
atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -1152,6 +1230,7 @@ atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
|
|||
static __always_inline bool
|
||||
atomic64_inc_not_zero(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_inc_not_zero(v);
|
||||
}
|
||||
|
|
@ -1159,6 +1238,7 @@ atomic64_inc_not_zero(atomic64_t *v)
|
|||
static __always_inline bool
|
||||
atomic64_inc_unless_negative(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_inc_unless_negative(v);
|
||||
}
|
||||
|
|
@ -1166,6 +1246,7 @@ atomic64_inc_unless_negative(atomic64_t *v)
|
|||
static __always_inline bool
|
||||
atomic64_dec_unless_positive(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_dec_unless_positive(v);
|
||||
}
|
||||
|
|
@ -1173,6 +1254,7 @@ atomic64_dec_unless_positive(atomic64_t *v)
|
|||
static __always_inline s64
|
||||
atomic64_dec_if_positive(atomic64_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic64_dec_if_positive(v);
|
||||
}
|
||||
|
|
@ -1201,6 +1283,7 @@ atomic_long_set(atomic_long_t *v, long i)
|
|||
static __always_inline void
|
||||
atomic_long_set_release(atomic_long_t *v, long i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_write(v, sizeof(*v));
|
||||
arch_atomic_long_set_release(v, i);
|
||||
}
|
||||
|
|
@ -1215,6 +1298,7 @@ atomic_long_add(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_add_return(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_add_return(i, v);
|
||||
}
|
||||
|
|
@ -1229,6 +1313,7 @@ atomic_long_add_return_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_add_return_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_add_return_release(i, v);
|
||||
}
|
||||
|
|
@ -1243,6 +1328,7 @@ atomic_long_add_return_relaxed(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_add(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_add(i, v);
|
||||
}
|
||||
|
|
@ -1257,6 +1343,7 @@ atomic_long_fetch_add_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_add_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_add_release(i, v);
|
||||
}
|
||||
|
|
@ -1278,6 +1365,7 @@ atomic_long_sub(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_sub_return(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_sub_return(i, v);
|
||||
}
|
||||
|
|
@ -1292,6 +1380,7 @@ atomic_long_sub_return_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_sub_return_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_sub_return_release(i, v);
|
||||
}
|
||||
|
|
@ -1306,6 +1395,7 @@ atomic_long_sub_return_relaxed(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_sub(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_sub(i, v);
|
||||
}
|
||||
|
|
@ -1320,6 +1410,7 @@ atomic_long_fetch_sub_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_sub_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_sub_release(i, v);
|
||||
}
|
||||
|
|
@ -1341,6 +1432,7 @@ atomic_long_inc(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_inc_return(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_inc_return(v);
|
||||
}
|
||||
|
|
@ -1355,6 +1447,7 @@ atomic_long_inc_return_acquire(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_inc_return_release(atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_inc_return_release(v);
|
||||
}
|
||||
|
|
@ -1369,6 +1462,7 @@ atomic_long_inc_return_relaxed(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_inc(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_inc(v);
|
||||
}
|
||||
|
|
@ -1383,6 +1477,7 @@ atomic_long_fetch_inc_acquire(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_inc_release(atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_inc_release(v);
|
||||
}
|
||||
|
|
@ -1404,6 +1499,7 @@ atomic_long_dec(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_dec_return(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_dec_return(v);
|
||||
}
|
||||
|
|
@ -1418,6 +1514,7 @@ atomic_long_dec_return_acquire(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_dec_return_release(atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_dec_return_release(v);
|
||||
}
|
||||
|
|
@ -1432,6 +1529,7 @@ atomic_long_dec_return_relaxed(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_dec(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_dec(v);
|
||||
}
|
||||
|
|
@ -1446,6 +1544,7 @@ atomic_long_fetch_dec_acquire(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_dec_release(atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_dec_release(v);
|
||||
}
|
||||
|
|
@ -1467,6 +1566,7 @@ atomic_long_and(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_and(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_and(i, v);
|
||||
}
|
||||
|
|
@ -1481,6 +1581,7 @@ atomic_long_fetch_and_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_and_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_and_release(i, v);
|
||||
}
|
||||
|
|
@ -1502,6 +1603,7 @@ atomic_long_andnot(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_andnot(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_andnot(i, v);
|
||||
}
|
||||
|
|
@ -1516,6 +1618,7 @@ atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_andnot_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_andnot_release(i, v);
|
||||
}
|
||||
|
|
@ -1537,6 +1640,7 @@ atomic_long_or(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_or(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_or(i, v);
|
||||
}
|
||||
|
|
@ -1551,6 +1655,7 @@ atomic_long_fetch_or_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_or_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_or_release(i, v);
|
||||
}
|
||||
|
|
@ -1572,6 +1677,7 @@ atomic_long_xor(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_xor(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_xor(i, v);
|
||||
}
|
||||
|
|
@ -1586,6 +1692,7 @@ atomic_long_fetch_xor_acquire(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_xor_release(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_xor_release(i, v);
|
||||
}
|
||||
|
|
@ -1600,6 +1707,7 @@ atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_xchg(atomic_long_t *v, long i)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_xchg(v, i);
|
||||
}
|
||||
|
|
@ -1614,6 +1722,7 @@ atomic_long_xchg_acquire(atomic_long_t *v, long i)
|
|||
static __always_inline long
|
||||
atomic_long_xchg_release(atomic_long_t *v, long i)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_xchg_release(v, i);
|
||||
}
|
||||
|
|
@ -1628,6 +1737,7 @@ atomic_long_xchg_relaxed(atomic_long_t *v, long i)
|
|||
static __always_inline long
|
||||
atomic_long_cmpxchg(atomic_long_t *v, long old, long new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_cmpxchg(v, old, new);
|
||||
}
|
||||
|
|
@ -1642,6 +1752,7 @@ atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new)
|
|||
static __always_inline long
|
||||
atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_cmpxchg_release(v, old, new);
|
||||
}
|
||||
|
|
@ -1656,6 +1767,7 @@ atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new)
|
|||
static __always_inline bool
|
||||
atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic_long_try_cmpxchg(v, old, new);
|
||||
|
|
@ -1672,6 +1784,7 @@ atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new)
|
|||
static __always_inline bool
|
||||
atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new)
|
||||
{
|
||||
kcsan_release();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
instrument_atomic_read_write(old, sizeof(*old));
|
||||
return arch_atomic_long_try_cmpxchg_release(v, old, new);
|
||||
|
|
@ -1688,6 +1801,7 @@ atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new)
|
|||
static __always_inline bool
|
||||
atomic_long_sub_and_test(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_sub_and_test(i, v);
|
||||
}
|
||||
|
|
@ -1695,6 +1809,7 @@ atomic_long_sub_and_test(long i, atomic_long_t *v)
|
|||
static __always_inline bool
|
||||
atomic_long_dec_and_test(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_dec_and_test(v);
|
||||
}
|
||||
|
|
@ -1702,6 +1817,7 @@ atomic_long_dec_and_test(atomic_long_t *v)
|
|||
static __always_inline bool
|
||||
atomic_long_inc_and_test(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_inc_and_test(v);
|
||||
}
|
||||
|
|
@ -1709,6 +1825,7 @@ atomic_long_inc_and_test(atomic_long_t *v)
|
|||
static __always_inline bool
|
||||
atomic_long_add_negative(long i, atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_add_negative(i, v);
|
||||
}
|
||||
|
|
@ -1716,6 +1833,7 @@ atomic_long_add_negative(long i, atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_fetch_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -1723,6 +1841,7 @@ atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u)
|
|||
static __always_inline bool
|
||||
atomic_long_add_unless(atomic_long_t *v, long a, long u)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_add_unless(v, a, u);
|
||||
}
|
||||
|
|
@ -1730,6 +1849,7 @@ atomic_long_add_unless(atomic_long_t *v, long a, long u)
|
|||
static __always_inline bool
|
||||
atomic_long_inc_not_zero(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_inc_not_zero(v);
|
||||
}
|
||||
|
|
@ -1737,6 +1857,7 @@ atomic_long_inc_not_zero(atomic_long_t *v)
|
|||
static __always_inline bool
|
||||
atomic_long_inc_unless_negative(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_inc_unless_negative(v);
|
||||
}
|
||||
|
|
@ -1744,6 +1865,7 @@ atomic_long_inc_unless_negative(atomic_long_t *v)
|
|||
static __always_inline bool
|
||||
atomic_long_dec_unless_positive(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_dec_unless_positive(v);
|
||||
}
|
||||
|
|
@ -1751,6 +1873,7 @@ atomic_long_dec_unless_positive(atomic_long_t *v)
|
|||
static __always_inline long
|
||||
atomic_long_dec_if_positive(atomic_long_t *v)
|
||||
{
|
||||
kcsan_mb();
|
||||
instrument_atomic_read_write(v, sizeof(*v));
|
||||
return arch_atomic_long_dec_if_positive(v);
|
||||
}
|
||||
|
|
@ -1758,6 +1881,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define xchg(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_xchg(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1772,6 +1896,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define xchg_release(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_release(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_xchg_release(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1786,6 +1911,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define cmpxchg(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1800,6 +1926,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define cmpxchg_release(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_release(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_cmpxchg_release(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1814,6 +1941,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define cmpxchg64(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_cmpxchg64(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1828,6 +1956,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define cmpxchg64_release(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_release(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_cmpxchg64_release(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1843,6 +1972,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
typeof(oldp) __ai_oldp = (oldp); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \
|
||||
arch_try_cmpxchg(__ai_ptr, __ai_oldp, __VA_ARGS__); \
|
||||
|
|
@ -1861,6 +1991,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
typeof(oldp) __ai_oldp = (oldp); \
|
||||
kcsan_release(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \
|
||||
arch_try_cmpxchg_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \
|
||||
|
|
@ -1892,6 +2023,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define sync_cmpxchg(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \
|
||||
arch_sync_cmpxchg(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1899,6 +2031,7 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
#define cmpxchg_double(ptr, ...) \
|
||||
({ \
|
||||
typeof(ptr) __ai_ptr = (ptr); \
|
||||
kcsan_mb(); \
|
||||
instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \
|
||||
arch_cmpxchg_double(__ai_ptr, __VA_ARGS__); \
|
||||
})
|
||||
|
|
@ -1912,4 +2045,4 @@ atomic_long_dec_if_positive(atomic_long_t *v)
|
|||
})
|
||||
|
||||
#endif /* _LINUX_ATOMIC_INSTRUMENTED_H */
|
||||
// 2a9553f0a9d5619f19151092df5cabbbf16ce835
|
||||
// 87c974b93032afd42143613434d1a7788fa598f9
|
||||
|
|
|
|||
|
|
@ -308,6 +308,24 @@
|
|||
# define __compiletime_warning(msg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Optional: only supported since clang >= 14.0
|
||||
*
|
||||
* clang: https://clang.llvm.org/docs/AttributeReference.html#disable-sanitizer-instrumentation
|
||||
*
|
||||
* disable_sanitizer_instrumentation is not always similar to
|
||||
* no_sanitize((<sanitizer-name>)): the latter may still let specific sanitizers
|
||||
* insert code into functions to prevent false positives. Unlike that,
|
||||
* disable_sanitizer_instrumentation prevents all kinds of instrumentation to
|
||||
* functions with the attribute.
|
||||
*/
|
||||
#if __has_attribute(disable_sanitizer_instrumentation)
|
||||
# define __disable_sanitizer_instrumentation \
|
||||
__attribute__((disable_sanitizer_instrumentation))
|
||||
#else
|
||||
# define __disable_sanitizer_instrumentation
|
||||
#endif
|
||||
|
||||
/*
|
||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
|
||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
|
||||
|
|
|
|||
|
|
@ -198,9 +198,20 @@ struct ftrace_likely_data {
|
|||
# define __no_kasan_or_inline __always_inline
|
||||
#endif
|
||||
|
||||
#define __no_kcsan __no_sanitize_thread
|
||||
#ifdef __SANITIZE_THREAD__
|
||||
/*
|
||||
* Clang still emits instrumentation for __tsan_func_{entry,exit}() and builtin
|
||||
* atomics even with __no_sanitize_thread (to avoid false positives in userspace
|
||||
* ThreadSanitizer). The kernel's requirements are stricter and we really do not
|
||||
* want any instrumentation with __no_kcsan.
|
||||
*
|
||||
* Therefore we add __disable_sanitizer_instrumentation where available to
|
||||
* disable all instrumentation. See Kconfig.kcsan where this is mandatory.
|
||||
*/
|
||||
# define __no_kcsan __no_sanitize_thread __disable_sanitizer_instrumentation
|
||||
# define __no_sanitize_or_inline __no_kcsan notrace __maybe_unused
|
||||
#else
|
||||
# define __no_kcsan
|
||||
#endif
|
||||
|
||||
#ifndef __no_sanitize_or_inline
|
||||
|
|
|
|||
|
|
@ -36,6 +36,36 @@
|
|||
*/
|
||||
void __kcsan_check_access(const volatile void *ptr, size_t size, int type);
|
||||
|
||||
/*
|
||||
* See definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
|
||||
* Note: The mappings are arbitrary, and do not reflect any real mappings of C11
|
||||
* memory orders to the LKMM memory orders and vice-versa!
|
||||
*/
|
||||
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_mb __ATOMIC_SEQ_CST
|
||||
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_wmb __ATOMIC_ACQ_REL
|
||||
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_rmb __ATOMIC_ACQUIRE
|
||||
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE_release __ATOMIC_RELEASE
|
||||
|
||||
/**
|
||||
* __kcsan_mb - full memory barrier instrumentation
|
||||
*/
|
||||
void __kcsan_mb(void);
|
||||
|
||||
/**
|
||||
* __kcsan_wmb - write memory barrier instrumentation
|
||||
*/
|
||||
void __kcsan_wmb(void);
|
||||
|
||||
/**
|
||||
* __kcsan_rmb - read memory barrier instrumentation
|
||||
*/
|
||||
void __kcsan_rmb(void);
|
||||
|
||||
/**
|
||||
* __kcsan_release - release barrier instrumentation
|
||||
*/
|
||||
void __kcsan_release(void);
|
||||
|
||||
/**
|
||||
* kcsan_disable_current - disable KCSAN for the current context
|
||||
*
|
||||
|
|
@ -99,7 +129,15 @@ void kcsan_set_access_mask(unsigned long mask);
|
|||
|
||||
/* Scoped access information. */
|
||||
struct kcsan_scoped_access {
|
||||
struct list_head list;
|
||||
union {
|
||||
struct list_head list; /* scoped_accesses list */
|
||||
/*
|
||||
* Not an entry in scoped_accesses list; stack depth from where
|
||||
* the access was initialized.
|
||||
*/
|
||||
int stack_depth;
|
||||
};
|
||||
|
||||
/* Access information. */
|
||||
const volatile void *ptr;
|
||||
size_t size;
|
||||
|
|
@ -151,6 +189,10 @@ void kcsan_end_scoped_access(struct kcsan_scoped_access *sa);
|
|||
static inline void __kcsan_check_access(const volatile void *ptr, size_t size,
|
||||
int type) { }
|
||||
|
||||
static inline void __kcsan_mb(void) { }
|
||||
static inline void __kcsan_wmb(void) { }
|
||||
static inline void __kcsan_rmb(void) { }
|
||||
static inline void __kcsan_release(void) { }
|
||||
static inline void kcsan_disable_current(void) { }
|
||||
static inline void kcsan_enable_current(void) { }
|
||||
static inline void kcsan_enable_current_nowarn(void) { }
|
||||
|
|
@ -183,12 +225,47 @@ static inline void kcsan_end_scoped_access(struct kcsan_scoped_access *sa) { }
|
|||
*/
|
||||
#define __kcsan_disable_current kcsan_disable_current
|
||||
#define __kcsan_enable_current kcsan_enable_current_nowarn
|
||||
#else
|
||||
#else /* __SANITIZE_THREAD__ */
|
||||
static inline void kcsan_check_access(const volatile void *ptr, size_t size,
|
||||
int type) { }
|
||||
static inline void __kcsan_enable_current(void) { }
|
||||
static inline void __kcsan_disable_current(void) { }
|
||||
#endif
|
||||
#endif /* __SANITIZE_THREAD__ */
|
||||
|
||||
#if defined(CONFIG_KCSAN_WEAK_MEMORY) && defined(__SANITIZE_THREAD__)
|
||||
/*
|
||||
* Normal barrier instrumentation is not done via explicit calls, but by mapping
|
||||
* to a repurposed __atomic_signal_fence(), which normally does not generate any
|
||||
* real instructions, but is still intercepted by fsanitize=thread. This means,
|
||||
* like any other compile-time instrumentation, barrier instrumentation can be
|
||||
* disabled with the __no_kcsan function attribute.
|
||||
*
|
||||
* Also see definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
|
||||
*
|
||||
* These are all macros, like <asm/barrier.h>, since some architectures use them
|
||||
* in non-static inline functions.
|
||||
*/
|
||||
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE(name) \
|
||||
do { \
|
||||
barrier(); \
|
||||
__atomic_signal_fence(__KCSAN_BARRIER_TO_SIGNAL_FENCE_##name); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
#define kcsan_mb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(mb)
|
||||
#define kcsan_wmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(wmb)
|
||||
#define kcsan_rmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(rmb)
|
||||
#define kcsan_release() __KCSAN_BARRIER_TO_SIGNAL_FENCE(release)
|
||||
#elif defined(CONFIG_KCSAN_WEAK_MEMORY) && defined(__KCSAN_INSTRUMENT_BARRIERS__)
|
||||
#define kcsan_mb __kcsan_mb
|
||||
#define kcsan_wmb __kcsan_wmb
|
||||
#define kcsan_rmb __kcsan_rmb
|
||||
#define kcsan_release __kcsan_release
|
||||
#else /* CONFIG_KCSAN_WEAK_MEMORY && ... */
|
||||
#define kcsan_mb() do { } while (0)
|
||||
#define kcsan_wmb() do { } while (0)
|
||||
#define kcsan_rmb() do { } while (0)
|
||||
#define kcsan_release() do { } while (0)
|
||||
#endif /* CONFIG_KCSAN_WEAK_MEMORY && ... */
|
||||
|
||||
/**
|
||||
* __kcsan_check_read - check regular read access for races
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
struct kcsan_ctx {
|
||||
int disable_count; /* disable counter */
|
||||
int disable_scoped; /* disable scoped access counter */
|
||||
int atomic_next; /* number of following atomic ops */
|
||||
|
||||
/*
|
||||
|
|
@ -48,8 +49,16 @@ struct kcsan_ctx {
|
|||
*/
|
||||
unsigned long access_mask;
|
||||
|
||||
/* List of scoped accesses. */
|
||||
/* List of scoped accesses; likely to be empty. */
|
||||
struct list_head scoped_accesses;
|
||||
|
||||
#ifdef CONFIG_KCSAN_WEAK_MEMORY
|
||||
/*
|
||||
* Scoped access for modeling access reordering to detect missing memory
|
||||
* barriers; only keep 1 to keep fast-path complexity manageable.
|
||||
*/
|
||||
struct kcsan_scoped_access reorder_access;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1339,6 +1339,9 @@ struct task_struct {
|
|||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
struct irqtrace_events kcsan_save_irqtrace;
|
||||
#endif
|
||||
#ifdef CONFIG_KCSAN_WEAK_MEMORY
|
||||
int kcsan_stack_depth;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_KUNIT)
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ do { \
|
|||
* Architectures that can implement ACQUIRE better need to take care.
|
||||
*/
|
||||
#ifndef smp_mb__after_spinlock
|
||||
#define smp_mb__after_spinlock() do { } while (0)
|
||||
#define smp_mb__after_spinlock() kcsan_mb()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPINLOCK
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue