History

kcsan: Distinguish kcsan_report() calls

Currently kcsan_report() is used to handle three distinct cases: * The caller hit a watchpoint when attempting an access. Some information regarding the caller and access are recorded, but no output is produced. * A caller which previously setup a watchpoint detected that the watchpoint has been hit, and possibly detected a change to the location in memory being watched. This may result in output reporting the interaction between this caller and the caller which hit the watchpoint. * A caller detected a change to a modification to a memory location which wasn't detected by a watchpoint, for which there is no information on the other thread. This may result in output reporting the unexpected change. ... depending on the specific case the caller has distinct pieces of information available, but the prototype of kcsan_report() has to handle all three cases. This means that in some cases we pass redundant information, and in others we don't pass all the information we could pass. This also means that the report code has to demux these three cases. So that we can pass some additional information while also simplifying the callers and report code, add separate kcsan_report_*() functions for the distinct cases, updating callers accordingly. As the watchpoint_idx is unused in the case of kcsan_report_unknown_origin(), this passes a dummy value into kcsan_report(). Subsequent patches will refactor the report code to avoid this. There should be no functional change as a result of this patch.

Mark Rutland committed 5 years ago

Commit 793c2571 parent 6f2d9813 files · +33 −15Browse files

Showing the changes to kernel (3 of 3 files). Show all

Unified · Split

3 files
  1. kernel/kcsan/core.c +4 −8
  2. kernel/kcsan/kcsan.h +6 −4
  3. kernel/kcsan/report.c +23 −3
kernel/kcsan/core.c+4−8
@@ -380,9 +380,7 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, · 379 unmodified lines
380 380
381 if (consumed) {381 if (consumed) {
382 kcsan_save_irqtrace(current);382 kcsan_save_irqtrace(current);
383 kcsan_report(ptr, size, type, KCSAN_VALUE_CHANGE_MAYBE,383 kcsan_report_set_info(ptr, size, type, watchpoint - watchpoints);
384 KCSAN_REPORT_CONSUMED_WATCHPOINT,
385 watchpoint - watchpoints);
386 kcsan_restore_irqtrace(current);384 kcsan_restore_irqtrace(current);
387 } else {385 } else {
388 /*386 /*
@@ -558,8 +556,8 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 169 unmodified lines
558 if (is_assert && value_change == KCSAN_VALUE_CHANGE_TRUE)556 if (is_assert && value_change == KCSAN_VALUE_CHANGE_TRUE)
559 atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]);557 atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]);
560 558
561 kcsan_report(ptr, size, type, value_change, KCSAN_REPORT_RACE_SIGNAL,559 kcsan_report_known_origin(ptr, size, type, value_change,
562 watchpoint - watchpoints);560 watchpoint - watchpoints);
563 } else if (value_change == KCSAN_VALUE_CHANGE_TRUE) {561 } else if (value_change == KCSAN_VALUE_CHANGE_TRUE) {
564 /* Inferring a race, since the value should not have changed. */562 /* Inferring a race, since the value should not have changed. */
565 563
@@ -568,9 +566,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 2 unmodified lines
568 atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]);566 atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]);
569 567
570 if (IS_ENABLED(CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN) || is_assert)568 if (IS_ENABLED(CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN) || is_assert)
571 kcsan_report(ptr, size, type, KCSAN_VALUE_CHANGE_TRUE,569 kcsan_report_unknown_origin(ptr, size, type);
572 KCSAN_REPORT_RACE_UNKNOWN_ORIGIN,
573 watchpoint - watchpoints);
574 }570 }
575 571
576 /*572 /*
kernel/kcsan/kcsan.h+6−4
@@ -136,10 +136,12 @@ enum kcsan_report_type { · 135 unmodified lines
136};136};
137 137
138/*138/*
139 * Print a race report from thread that encountered the race.139 * Notify the report code that a race occurred.
140 */140 */
141extern void kcsan_report(const volatile void *ptr, size_t size, int access_type,141void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type,
142 enum kcsan_value_change value_change,142 int watchpoint_idx);
143 enum kcsan_report_type type, int watchpoint_idx);143void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type,
144 enum kcsan_value_change value_change, int watchpoint_idx);
145void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type);
144 146
145#endif /* _KERNEL_KCSAN_KCSAN_H */147#endif /* _KERNEL_KCSAN_KCSAN_H */
kernel/kcsan/report.c+23−3
@@ -598,9 +598,9 @@ static noinline bool prepare_report(unsigned long *flags, · 597 unmodified lines
598 }598 }
599}599}
600 600
601void kcsan_report(const volatile void *ptr, size_t size, int access_type,601static void kcsan_report(const volatile void *ptr, size_t size, int access_type,
602 enum kcsan_value_change value_change,602 enum kcsan_value_change value_change,
603 enum kcsan_report_type type, int watchpoint_idx)603 enum kcsan_report_type type, int watchpoint_idx)
604{604{
605 unsigned long flags = 0;605 unsigned long flags = 0;
606 const struct access_info ai = {606 const struct access_info ai = {
@@ -645,3 +645,23 @@ void kcsan_report(const volatile void *ptr, size_t size, int access_type, · 38 unmodified lines
645out:645out:
646 kcsan_enable_current();646 kcsan_enable_current();
647}647}
648
649void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type,
650 int watchpoint_idx)
651{
652 kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_MAYBE,
653 KCSAN_REPORT_CONSUMED_WATCHPOINT, watchpoint_idx);
654}
655
656void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type,
657 enum kcsan_value_change value_change, int watchpoint_idx)
658{
659 kcsan_report(ptr, size, access_type, value_change,
660 KCSAN_REPORT_RACE_SIGNAL, watchpoint_idx);
661}
662
663void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type)
664{
665 kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_TRUE,
666 KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, 0);
667}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t