2019-11-14 18:02:54 +00:00
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
kcsan: Avoid inserting __tsan_func_entry/exit if possible
To avoid inserting __tsan_func_{entry,exit}, add option if supported by
compiler. Currently only Clang can be told to not emit calls to these
functions. It is safe to not emit these, since KCSAN does not rely on
them.
Note that, if we disable __tsan_func_{entry,exit}(), we need to disable
tail-call optimization in sanitized compilation units, as otherwise we
may skip frames in the stack trace; in particular when the tail called
function is one of the KCSAN's runtime functions, and a report is
generated, we might miss the function where the actual access occurred.
Since __tsan_func_{entry,exit}() insertion effectively disabled
tail-call optimization, there should be no observable change.
This was caught and confirmed with kcsan-test & UNWINDER_ORC.
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200521142047.169334-3-elver@google.com
2020-05-21 14:20:38 +00:00
|
|
|
# GCC and Clang accept backend options differently. Do not wrap in cc-option,
|
|
|
|
# because Clang accepts "--param" even if it is unused.
|
|
|
|
ifdef CONFIG_CC_IS_CLANG
|
|
|
|
cc-param = -mllvm -$(1)
|
|
|
|
else
|
2020-06-18 09:31:16 +00:00
|
|
|
cc-param = --param $(1)
|
kcsan: Avoid inserting __tsan_func_entry/exit if possible
To avoid inserting __tsan_func_{entry,exit}, add option if supported by
compiler. Currently only Clang can be told to not emit calls to these
functions. It is safe to not emit these, since KCSAN does not rely on
them.
Note that, if we disable __tsan_func_{entry,exit}(), we need to disable
tail-call optimization in sanitized compilation units, as otherwise we
may skip frames in the stack trace; in particular when the tail called
function is one of the KCSAN's runtime functions, and a report is
generated, we might miss the function where the actual access occurred.
Since __tsan_func_{entry,exit}() insertion effectively disabled
tail-call optimization, there should be no observable change.
This was caught and confirmed with kcsan-test & UNWINDER_ORC.
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200521142047.169334-3-elver@google.com
2020-05-21 14:20:38 +00:00
|
|
|
endif
|
|
|
|
|
2020-05-21 14:20:39 +00:00
|
|
|
# Keep most options here optional, to allow enabling more compilers if absence
|
|
|
|
# of some options does not break KCSAN nor causes false positive reports.
|
2021-08-05 12:57:45 +00:00
|
|
|
kcsan-cflags := -fsanitize=thread -fno-optimize-sibling-calls \
|
kcsan: Support compounded read-write instrumentation
Add support for compounded read-write instrumentation if supported by
the compiler. Adds the necessary instrumentation functions, and a new
type which is used to generate a more descriptive report.
Furthermore, such compounded memory access instrumentation is excluded
from the "assume aligned writes up to word size are atomic" rule,
because we cannot assume that the compiler emits code that is atomic for
compound ops.
LLVM/Clang added support for the feature in:
https://github.com/llvm/llvm-project/commit/785d41a261d136b64ab6c15c5d35f2adc5ad53e3
The new instrumentation is emitted for sets of memory accesses in the
same basic block to the same address with at least one read appearing
before a write. These typically result from compound operations such as
++, --, +=, -=, |=, &=, etc. but also equivalent forms such as "var =
var + 1". Where the compiler determines that it is equivalent to emit a
call to a single __tsan_read_write instead of separate __tsan_read and
__tsan_write, we can then benefit from improved performance and better
reporting for such access patterns.
The new reports now show that the ops are both reads and writes, for
example:
read-write to 0xffffffff90548a38 of 8 bytes by task 143 on cpu 3:
test_kernel_rmw_array+0x45/0xa0
access_thread+0x71/0xb0
kthread+0x21e/0x240
ret_from_fork+0x22/0x30
read-write to 0xffffffff90548a38 of 8 bytes by task 144 on cpu 2:
test_kernel_rmw_array+0x45/0xa0
access_thread+0x71/0xb0
kthread+0x21e/0x240
ret_from_fork+0x22/0x30
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>
2020-07-24 07:00:01 +00:00
|
|
|
$(call cc-option,$(call cc-param,tsan-compound-read-before-write=1),$(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1))) \
|
2020-05-21 14:20:39 +00:00
|
|
|
$(call cc-param,tsan-distinguish-volatile=1)
|
2021-08-05 12:57:45 +00:00
|
|
|
|
2021-11-30 11:44:20 +00:00
|
|
|
ifdef CONFIG_CC_IS_GCC
|
|
|
|
# GCC started warning about operations unsupported by the TSan runtime. But
|
|
|
|
# KCSAN != TSan, so just ignore these warnings.
|
|
|
|
kcsan-cflags += -Wno-tsan
|
|
|
|
endif
|
|
|
|
|
2021-08-05 12:57:45 +00:00
|
|
|
ifndef CONFIG_KCSAN_WEAK_MEMORY
|
|
|
|
kcsan-cflags += $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0))
|
|
|
|
endif
|
|
|
|
|
|
|
|
export CFLAGS_KCSAN := $(kcsan-cflags)
|