1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 /*
4  * This header provides generic wrappers for memory access instrumentation that
5  * the compiler cannot emit for: KASAN, KCSAN.
6  */
7 #ifndef _LINUX_INSTRUMENTED_H
8 #define _LINUX_INSTRUMENTED_H
9 
10 #include <linux/compiler.h>
11 #include <linux/kasan-checks.h>
12 #include <linux/kcsan-checks.h>
13 #include <linux/types.h>
14 
15 /**
16  * instrument_read - instrument regular read access
17  *
18  * Instrument a regular read access. The instrumentation should be inserted
19  * before the actual read happens.
20  *
21  * @ptr address of access
22  * @size size of access
23  */
instrument_read(const volatile void * v,size_t size)24 static __always_inline void instrument_read(const volatile void *v, size_t size)
25 {
26 	kasan_check_read(v, size);
27 	kcsan_check_read(v, size);
28 }
29 
30 /**
31  * instrument_write - instrument regular write access
32  *
33  * Instrument a regular write access. The instrumentation should be inserted
34  * before the actual write happens.
35  *
36  * @ptr address of access
37  * @size size of access
38  */
instrument_write(const volatile void * v,size_t size)39 static __always_inline void instrument_write(const volatile void *v, size_t size)
40 {
41 	kasan_check_write(v, size);
42 	kcsan_check_write(v, size);
43 }
44 
45 /**
46  * instrument_read_write - instrument regular read-write access
47  *
48  * Instrument a regular write access. The instrumentation should be inserted
49  * before the actual write happens.
50  *
51  * @ptr address of access
52  * @size size of access
53  */
instrument_read_write(const volatile void * v,size_t size)54 static __always_inline void instrument_read_write(const volatile void *v, size_t size)
55 {
56 	kasan_check_write(v, size);
57 	kcsan_check_read_write(v, size);
58 }
59 
60 /**
61  * instrument_atomic_read - instrument atomic read access
62  *
63  * Instrument an atomic read access. The instrumentation should be inserted
64  * before the actual read happens.
65  *
66  * @ptr address of access
67  * @size size of access
68  */
instrument_atomic_read(const volatile void * v,size_t size)69 static __always_inline void instrument_atomic_read(const volatile void *v, size_t size)
70 {
71 	kasan_check_read(v, size);
72 	kcsan_check_atomic_read(v, size);
73 }
74 
75 /**
76  * instrument_atomic_write - instrument atomic write access
77  *
78  * Instrument an atomic write access. The instrumentation should be inserted
79  * before the actual write happens.
80  *
81  * @ptr address of access
82  * @size size of access
83  */
instrument_atomic_write(const volatile void * v,size_t size)84 static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
85 {
86 	kasan_check_write(v, size);
87 	kcsan_check_atomic_write(v, size);
88 }
89 
90 /**
91  * instrument_atomic_read_write - instrument atomic read-write access
92  *
93  * Instrument an atomic read-write access. The instrumentation should be
94  * inserted before the actual write happens.
95  *
96  * @ptr address of access
97  * @size size of access
98  */
instrument_atomic_read_write(const volatile void * v,size_t size)99 static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
100 {
101 	kasan_check_write(v, size);
102 	kcsan_check_atomic_read_write(v, size);
103 }
104 
105 /**
106  * instrument_copy_to_user - instrument reads of copy_to_user
107  *
108  * Instrument reads from kernel memory, that are due to copy_to_user (and
109  * variants). The instrumentation must be inserted before the accesses.
110  *
111  * @to destination address
112  * @from source address
113  * @n number of bytes to copy
114  */
115 static __always_inline void
instrument_copy_to_user(void __user * to,const void * from,unsigned long n)116 instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
117 {
118 	kasan_check_read(from, n);
119 	kcsan_check_read(from, n);
120 }
121 
122 /**
123  * instrument_copy_from_user - instrument writes of copy_from_user
124  *
125  * Instrument writes to kernel memory, that are due to copy_from_user (and
126  * variants). The instrumentation should be inserted before the accesses.
127  *
128  * @to destination address
129  * @from source address
130  * @n number of bytes to copy
131  */
132 static __always_inline void
instrument_copy_from_user(const void * to,const void __user * from,unsigned long n)133 instrument_copy_from_user(const void *to, const void __user *from, unsigned long n)
134 {
135 	kasan_check_write(to, n);
136 	kcsan_check_write(to, n);
137 }
138 
139 #endif /* _LINUX_INSTRUMENTED_H */
140