summaryrefslogtreecommitdiff
path: root/kernel/kcsan/report.c
diff options
context:
space:
mode:
authorMarco Elver <elver@google.com>2020-02-11 17:04:22 +0100
committerIngo Molnar <mingo@kernel.org>2020-03-21 09:44:08 +0100
commit81af89e15862909881ff010a0adb67148487e88a (patch)
treed2cc4b1598e5136a418154244fbbff9997fde592 /kernel/kcsan/report.c
parentb738f6169f1260b4ed5bd9f220b1c84d79f3ab8d (diff)
kcsan: Add kcsan_set_access_mask() support
When setting up an access mask with kcsan_set_access_mask(), KCSAN will only report races if concurrent changes to bits set in access_mask are observed. Conveying access_mask via a separate call avoids introducing overhead in the common-case fast-path. Acked-by: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/kcsan/report.c')
-rw-r--r--kernel/kcsan/report.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/kcsan/report.c b/kernel/kcsan/report.c
index d871476dc134..11c791b886f3 100644
--- a/kernel/kcsan/report.c
+++ b/kernel/kcsan/report.c
@@ -132,6 +132,9 @@ static bool rate_limit_report(unsigned long frame1, unsigned long frame2)
static bool
skip_report(enum kcsan_value_change value_change, unsigned long top_frame)
{
+ /* Should never get here if value_change==FALSE. */
+ WARN_ON_ONCE(value_change == KCSAN_VALUE_CHANGE_FALSE);
+
/*
* The first call to skip_report always has value_change==TRUE, since we
* cannot know the value written of an instrumented access. For the 2nd
@@ -493,7 +496,15 @@ void kcsan_report(const volatile void *ptr, size_t size, int access_type,
kcsan_disable_current();
if (prepare_report(&flags, ptr, size, access_type, cpu_id, type)) {
- if (print_report(ptr, size, access_type, value_change, cpu_id, type) && panic_on_warn)
+ /*
+ * Never report if value_change is FALSE, only if we it is
+ * either TRUE or MAYBE. In case of MAYBE, further filtering may
+ * be done once we know the full stack trace in print_report().
+ */
+ bool reported = value_change != KCSAN_VALUE_CHANGE_FALSE &&
+ print_report(ptr, size, access_type, value_change, cpu_id, type);
+
+ if (reported && panic_on_warn)
panic("panic_on_warn set ...\n");
release_report(&flags, type);