mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:38:03 +00:00
Kernel concurrency sanitizer (KCSAN) updates for v6.4
This update fixes kernel-doc warnings and also updates instrumentation from READ_ONCE() to volatile in order to avoid unaligned load-acquire instructions on arm64 in kernels built with LTO. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEbK7UrM+RBIrCoViJnr8S83LZ+4wFAmQsZnoTHHBhdWxtY2tA a2VybmVsLm9yZwAKCRCevxLzctn7jPDUEACF3CXADzH1D1Z+dm5sxnF5BT9Mfzju EXxeQ3bJ//fbgmnPOh4J/w6tQwwd8p0uRc8nbdxl+uqAgcPsgiIfN9FAsC9v0Hxu xyt958sx8zz4FpbUckKQ6ab3/7tclGVN/0VLQdTfr2DstTkWIv7DePUxb/2s6Yst 6dT0vwapxqz1qB2NFN5ghkTFG0d1RUskEYu9CCHmh4chV+8nqwgmIyf9PPwcXRRC waerO6lVKwXe/LqB4BA5hpDpMz1hP3WoPLI4DTR0wL+9gaoz6VEErqhqwiphT2J2 T9XwIMTqe32uP4g3cUSANIVgPUn9mD0CUg4H75BwiKgOXDsmPaPCKd/s5EczEBVS mxMIxLrzFQ4D9YwxNR+QR9x9kGHt1oayY/G5YGFtDdxgm/Hb5badgtyBQK/KOLJm DqOyUO96inAog6W4Mq48i74pq5Uz3iUnrJJqn/8X8Mo9eO5ywa0O83YXp980/J1Q g9lPmyuceDtMimE20+p4IosNwXNjn/d3jDbxwoN5nWOhTumBzmtELarW9QRCTvOo f97QPUD5glFSsGg9/TgZHd/iDkirZKdInXtjPergx0uzJPCbtd3KmbecPTeCt2Lj ALUoNyDZT7U8zfphZeXJ4MgTXFnHI6N6S57ro8WEa4ZiZm90VJ9QhVlKA1zqoHVu ET8Xhny+C67Izg== =AH+i -----END PGP SIGNATURE----- Merge tag 'kcsan.2023.04.04a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu Pull KCSAN updates from Paul McKenney: "Kernel concurrency sanitizer (KCSAN) updates for v6.4 This fixes kernel-doc warnings and also updates instrumentation from READ_ONCE() to volatile in order to avoid unaligned load-acquire instructions on arm64 in kernels built with LTO" * tag 'kcsan.2023.04.04a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: kcsan: Avoid READ_ONCE() in read_instrumented_memory() instrumented.h: Fix all kernel-doc format warnings
This commit is contained in:
commit
022e32094e
@ -15,12 +15,11 @@
|
||||
|
||||
/**
|
||||
* instrument_read - instrument regular read access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument a regular read access. The instrumentation should be inserted
|
||||
* before the actual read happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_read(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -30,12 +29,11 @@ static __always_inline void instrument_read(const volatile void *v, size_t size)
|
||||
|
||||
/**
|
||||
* instrument_write - instrument regular write access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument a regular write access. The instrumentation should be inserted
|
||||
* before the actual write happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_write(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -45,12 +43,11 @@ static __always_inline void instrument_write(const volatile void *v, size_t size
|
||||
|
||||
/**
|
||||
* instrument_read_write - instrument regular read-write access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument a regular write access. The instrumentation should be inserted
|
||||
* before the actual write happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_read_write(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -60,12 +57,11 @@ static __always_inline void instrument_read_write(const volatile void *v, size_t
|
||||
|
||||
/**
|
||||
* instrument_atomic_read - instrument atomic read access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument an atomic read access. The instrumentation should be inserted
|
||||
* before the actual read happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_atomic_read(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -75,12 +71,11 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_
|
||||
|
||||
/**
|
||||
* instrument_atomic_write - instrument atomic write access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument an atomic write access. The instrumentation should be inserted
|
||||
* before the actual write happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -90,12 +85,11 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size
|
||||
|
||||
/**
|
||||
* instrument_atomic_read_write - instrument atomic read-write access
|
||||
* @v: address of access
|
||||
* @size: size of access
|
||||
*
|
||||
* Instrument an atomic read-write access. The instrumentation should be
|
||||
* inserted before the actual write happens.
|
||||
*
|
||||
* @ptr address of access
|
||||
* @size size of access
|
||||
*/
|
||||
static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
|
||||
{
|
||||
@ -105,13 +99,12 @@ static __always_inline void instrument_atomic_read_write(const volatile void *v,
|
||||
|
||||
/**
|
||||
* instrument_copy_to_user - instrument reads of copy_to_user
|
||||
* @to: destination address
|
||||
* @from: source address
|
||||
* @n: number of bytes to copy
|
||||
*
|
||||
* Instrument reads from kernel memory, that are due to copy_to_user (and
|
||||
* variants). The instrumentation must be inserted before the accesses.
|
||||
*
|
||||
* @to destination address
|
||||
* @from source address
|
||||
* @n number of bytes to copy
|
||||
*/
|
||||
static __always_inline void
|
||||
instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
@ -123,13 +116,12 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
|
||||
/**
|
||||
* instrument_copy_from_user_before - add instrumentation before copy_from_user
|
||||
* @to: destination address
|
||||
* @from: source address
|
||||
* @n: number of bytes to copy
|
||||
*
|
||||
* Instrument writes to kernel memory, that are due to copy_from_user (and
|
||||
* variants). The instrumentation should be inserted before the accesses.
|
||||
*
|
||||
* @to destination address
|
||||
* @from source address
|
||||
* @n number of bytes to copy
|
||||
*/
|
||||
static __always_inline void
|
||||
instrument_copy_from_user_before(const void *to, const void __user *from, unsigned long n)
|
||||
@ -140,14 +132,13 @@ instrument_copy_from_user_before(const void *to, const void __user *from, unsign
|
||||
|
||||
/**
|
||||
* instrument_copy_from_user_after - add instrumentation after copy_from_user
|
||||
* @to: destination address
|
||||
* @from: source address
|
||||
* @n: number of bytes to copy
|
||||
* @left: number of bytes not copied (as returned by copy_from_user)
|
||||
*
|
||||
* Instrument writes to kernel memory, that are due to copy_from_user (and
|
||||
* variants). The instrumentation should be inserted after the accesses.
|
||||
*
|
||||
* @to destination address
|
||||
* @from source address
|
||||
* @n number of bytes to copy
|
||||
* @left number of bytes not copied (as returned by copy_from_user)
|
||||
*/
|
||||
static __always_inline void
|
||||
instrument_copy_from_user_after(const void *to, const void __user *from,
|
||||
@ -158,12 +149,11 @@ instrument_copy_from_user_after(const void *to, const void __user *from,
|
||||
|
||||
/**
|
||||
* instrument_get_user() - add instrumentation to get_user()-like macros
|
||||
* @to: destination variable, may not be address-taken
|
||||
*
|
||||
* get_user() and friends are fragile, so it may depend on the implementation
|
||||
* whether the instrumentation happens before or after the data is copied from
|
||||
* the userspace.
|
||||
*
|
||||
* @to destination variable, may not be address-taken
|
||||
*/
|
||||
#define instrument_get_user(to) \
|
||||
({ \
|
||||
@ -175,14 +165,13 @@ instrument_copy_from_user_after(const void *to, const void __user *from,
|
||||
|
||||
/**
|
||||
* instrument_put_user() - add instrumentation to put_user()-like macros
|
||||
* @from: source address
|
||||
* @ptr: userspace pointer to copy to
|
||||
* @size: number of bytes to copy
|
||||
*
|
||||
* put_user() and friends are fragile, so it may depend on the implementation
|
||||
* whether the instrumentation happens before or after the data is copied from
|
||||
* the userspace.
|
||||
*
|
||||
* @from source address
|
||||
* @ptr userspace pointer to copy to
|
||||
* @size number of bytes to copy
|
||||
*/
|
||||
#define instrument_put_user(from, ptr, size) \
|
||||
({ \
|
||||
|
@ -337,11 +337,20 @@ static void delay_access(int type)
|
||||
*/
|
||||
static __always_inline u64 read_instrumented_memory(const volatile void *ptr, size_t size)
|
||||
{
|
||||
/*
|
||||
* In the below we don't necessarily need the read of the location to
|
||||
* be atomic, and we don't use READ_ONCE(), since all we need for race
|
||||
* detection is to observe 2 different values.
|
||||
*
|
||||
* Furthermore, on certain architectures (such as arm64), READ_ONCE()
|
||||
* may turn into more complex instructions than a plain load that cannot
|
||||
* do unaligned accesses.
|
||||
*/
|
||||
switch (size) {
|
||||
case 1: return READ_ONCE(*(const u8 *)ptr);
|
||||
case 2: return READ_ONCE(*(const u16 *)ptr);
|
||||
case 4: return READ_ONCE(*(const u32 *)ptr);
|
||||
case 8: return READ_ONCE(*(const u64 *)ptr);
|
||||
case 1: return *(const volatile u8 *)ptr;
|
||||
case 2: return *(const volatile u16 *)ptr;
|
||||
case 4: return *(const volatile u32 *)ptr;
|
||||
case 8: return *(const volatile u64 *)ptr;
|
||||
default: return 0; /* Ignore; we do not diff the values. */
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user