Skip to content

Commit 63722bb

Browse files
author
Ingo Molnar
committed
Merge branch 'kcsan' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into locking/core
Pull v5.9 KCSAN bits from Paul E. McKenney. Perhaps the most important change is that GCC 11 now has all fixes in place to support KCSAN, so GCC support can be enabled again. Signed-off-by: Ingo Molnar <[email protected]>
2 parents 28cff52 + 61d56d7 commit 63722bb

File tree

12 files changed

+1166
-14
lines changed

12 files changed

+1166
-14
lines changed

Documentation/dev-tools/kcsan.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ approach to detect races. KCSAN's primary purpose is to detect `data races`_.
88
Usage
99
-----
1010

11-
KCSAN requires Clang version 11 or later.
11+
KCSAN is supported by both GCC and Clang. With GCC we require version 11 or
12+
later, and with Clang also require version 11 or later.
1213

1314
To enable KCSAN configure the kernel with::
1415

arch/x86/mm/pat/set_memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static inline void cpa_inc_2m_checked(void)
135135

136136
static inline void cpa_inc_4k_install(void)
137137
{
138-
cpa_4k_install++;
138+
data_race(cpa_4k_install++);
139139
}
140140

141141
static inline void cpa_inc_lp_sameprot(int level)

include/linux/rculist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ static inline void __list_splice_init_rcu(struct list_head *list,
248248
*/
249249

250250
sync();
251+
ASSERT_EXCLUSIVE_ACCESS(*first);
252+
ASSERT_EXCLUSIVE_ACCESS(*last);
251253

252254
/*
253255
* Readers are finished with the source list, so perform splice.

kernel/fork.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,13 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
359359
struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
360360

361361
if (new) {
362-
*new = *orig;
362+
ASSERT_EXCLUSIVE_WRITER(orig->vm_flags);
363+
ASSERT_EXCLUSIVE_WRITER(orig->vm_file);
364+
/*
365+
* orig->shared.rb may be modified concurrently, but the clone
366+
* will be reinitialized.
367+
*/
368+
*new = data_race(*orig);
363369
INIT_LIST_HEAD(&new->anon_vma_chain);
364370
new->vm_next = new->vm_prev = NULL;
365371
}

kernel/kcsan/Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ CFLAGS_REMOVE_core.o = $(CC_FLAGS_FTRACE)
77
CFLAGS_REMOVE_debugfs.o = $(CC_FLAGS_FTRACE)
88
CFLAGS_REMOVE_report.o = $(CC_FLAGS_FTRACE)
99

10-
CFLAGS_core.o := $(call cc-option,-fno-conserve-stack,) \
11-
$(call cc-option,-fno-stack-protector,)
10+
CFLAGS_core.o := $(call cc-option,-fno-conserve-stack) \
11+
-fno-stack-protector -DDISABLE_BRANCH_PROFILING
1212

1313
obj-y := core.o debugfs.o report.o
14-
obj-$(CONFIG_KCSAN_SELFTEST) += test.o
14+
obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
15+
16+
CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
17+
obj-$(CONFIG_KCSAN_TEST) += kcsan-test.o

kernel/kcsan/atomic.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
#ifndef _KERNEL_KCSAN_ATOMIC_H
44
#define _KERNEL_KCSAN_ATOMIC_H
55

6-
#include <linux/jiffies.h>
7-
#include <linux/sched.h>
6+
#include <linux/types.h>
87

98
/*
109
* Special rules for certain memory where concurrent conflicting accesses are
@@ -13,8 +12,7 @@
1312
*/
1413
static bool kcsan_is_atomic_special(const volatile void *ptr)
1514
{
16-
/* volatile globals that have been observed in data races. */
17-
return ptr == &jiffies || ptr == &current->state;
15+
return false;
1816
}
1917

2018
#endif /* _KERNEL_KCSAN_ATOMIC_H */

kernel/kcsan/core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ EXPORT_SYMBOL(__kcsan_check_access);
776776
*/
777777

778778
#define DEFINE_TSAN_READ_WRITE(size) \
779+
void __tsan_read##size(void *ptr); \
779780
void __tsan_read##size(void *ptr) \
780781
{ \
781782
check_access(ptr, size, 0); \
@@ -784,6 +785,7 @@ EXPORT_SYMBOL(__kcsan_check_access);
784785
void __tsan_unaligned_read##size(void *ptr) \
785786
__alias(__tsan_read##size); \
786787
EXPORT_SYMBOL(__tsan_unaligned_read##size); \
788+
void __tsan_write##size(void *ptr); \
787789
void __tsan_write##size(void *ptr) \
788790
{ \
789791
check_access(ptr, size, KCSAN_ACCESS_WRITE); \
@@ -799,12 +801,14 @@ DEFINE_TSAN_READ_WRITE(4);
799801
DEFINE_TSAN_READ_WRITE(8);
800802
DEFINE_TSAN_READ_WRITE(16);
801803

804+
void __tsan_read_range(void *ptr, size_t size);
802805
void __tsan_read_range(void *ptr, size_t size)
803806
{
804807
check_access(ptr, size, 0);
805808
}
806809
EXPORT_SYMBOL(__tsan_read_range);
807810

811+
void __tsan_write_range(void *ptr, size_t size);
808812
void __tsan_write_range(void *ptr, size_t size)
809813
{
810814
check_access(ptr, size, KCSAN_ACCESS_WRITE);
@@ -821,6 +825,7 @@ EXPORT_SYMBOL(__tsan_write_range);
821825
* the size-check of compiletime_assert_rwonce_type().
822826
*/
823827
#define DEFINE_TSAN_VOLATILE_READ_WRITE(size) \
828+
void __tsan_volatile_read##size(void *ptr); \
824829
void __tsan_volatile_read##size(void *ptr) \
825830
{ \
826831
const bool is_atomic = size <= sizeof(long long) && \
@@ -833,6 +838,7 @@ EXPORT_SYMBOL(__tsan_write_range);
833838
void __tsan_unaligned_volatile_read##size(void *ptr) \
834839
__alias(__tsan_volatile_read##size); \
835840
EXPORT_SYMBOL(__tsan_unaligned_volatile_read##size); \
841+
void __tsan_volatile_write##size(void *ptr); \
836842
void __tsan_volatile_write##size(void *ptr) \
837843
{ \
838844
const bool is_atomic = size <= sizeof(long long) && \
@@ -858,14 +864,17 @@ DEFINE_TSAN_VOLATILE_READ_WRITE(16);
858864
* The below are not required by KCSAN, but can still be emitted by the
859865
* compiler.
860866
*/
867+
void __tsan_func_entry(void *call_pc);
861868
void __tsan_func_entry(void *call_pc)
862869
{
863870
}
864871
EXPORT_SYMBOL(__tsan_func_entry);
872+
void __tsan_func_exit(void);
865873
void __tsan_func_exit(void)
866874
{
867875
}
868876
EXPORT_SYMBOL(__tsan_func_exit);
877+
void __tsan_init(void);
869878
void __tsan_init(void)
870879
{
871880
}

0 commit comments

Comments
 (0)