mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
![Marco Elver](/assets/img/avatar_default.png)
Introduce read-write instrumentation hooks, to more precisely denote an operation's behaviour. KCSAN is able to distinguish compound instrumentation, and with the new instrumentation we then benefit from improved reporting. More importantly, read-write compound operations should not implicitly be treated as atomic, if they aren't actually atomic. Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
139 lines
3.6 KiB
C
139 lines
3.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
* This header provides generic wrappers for memory access instrumentation that
|
|
* the compiler cannot emit for: KASAN, KCSAN.
|
|
*/
|
|
#ifndef _LINUX_INSTRUMENTED_H
|
|
#define _LINUX_INSTRUMENTED_H
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/kasan-checks.h>
|
|
#include <linux/kcsan-checks.h>
|
|
#include <linux/types.h>
|
|
|
|
/**
|
|
* instrument_read - instrument regular read 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)
|
|
{
|
|
kasan_check_read(v, size);
|
|
kcsan_check_read(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_write - instrument regular write 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)
|
|
{
|
|
kasan_check_write(v, size);
|
|
kcsan_check_write(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_read_write - instrument regular read-write 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)
|
|
{
|
|
kasan_check_write(v, size);
|
|
kcsan_check_read_write(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_atomic_read - instrument atomic read 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)
|
|
{
|
|
kasan_check_read(v, size);
|
|
kcsan_check_atomic_read(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_atomic_write - instrument atomic write 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)
|
|
{
|
|
kasan_check_write(v, size);
|
|
kcsan_check_atomic_write(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_atomic_read_write - instrument atomic read-write 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)
|
|
{
|
|
kasan_check_write(v, size);
|
|
kcsan_check_atomic_read_write(v, size);
|
|
}
|
|
|
|
/**
|
|
* instrument_copy_to_user - instrument reads of copy_to_user
|
|
*
|
|
* 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)
|
|
{
|
|
kasan_check_read(from, n);
|
|
kcsan_check_read(from, n);
|
|
}
|
|
|
|
/**
|
|
* instrument_copy_from_user - instrument writes of copy_from_user
|
|
*
|
|
* 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(const void *to, const void __user *from, unsigned long n)
|
|
{
|
|
kasan_check_write(to, n);
|
|
kcsan_check_write(to, n);
|
|
}
|
|
|
|
#endif /* _LINUX_INSTRUMENTED_H */
|