diff options
Diffstat (limited to 'kernel/kcsan')
-rw-r--r-- | kernel/kcsan/report.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/kernel/kcsan/report.c b/kernel/kcsan/report.c index 8bfa970965a1..d8441bed065c 100644 --- a/kernel/kcsan/report.c +++ b/kernel/kcsan/report.c @@ -596,18 +596,10 @@ static noinline bool prepare_report(unsigned long *flags, } } -static void kcsan_report(const volatile void *ptr, size_t size, int access_type, - enum kcsan_value_change value_change, +static void kcsan_report(const struct access_info *ai, enum kcsan_value_change value_change, enum kcsan_report_type type, struct other_info *other_info) { unsigned long flags = 0; - const struct access_info ai = { - .ptr = ptr, - .size = size, - .access_type = access_type, - .task_pid = in_task() ? task_pid_nr(current) : -1, - .cpu_id = raw_smp_processor_id() - }; kcsan_disable_current(); @@ -620,14 +612,14 @@ static void kcsan_report(const volatile void *ptr, size_t size, int access_type, */ lockdep_off(); - if (prepare_report(&flags, type, &ai, other_info)) { + if (prepare_report(&flags, type, ai, other_info)) { /* * 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(). */ if (value_change != KCSAN_VALUE_CHANGE_FALSE) - print_report(value_change, type, &ai, other_info); + print_report(value_change, type, ai, other_info); release_report(&flags, other_info); } @@ -636,22 +628,38 @@ static void kcsan_report(const volatile void *ptr, size_t size, int access_type, kcsan_enable_current(); } +static struct access_info prepare_access_info(const volatile void *ptr, size_t size, + int access_type) +{ + return (struct access_info) { + .ptr = ptr, + .size = size, + .access_type = access_type, + .task_pid = in_task() ? task_pid_nr(current) : -1, + .cpu_id = raw_smp_processor_id() + }; +} + void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type, int watchpoint_idx) { - kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_MAYBE, - KCSAN_REPORT_CONSUMED_WATCHPOINT, &other_infos[watchpoint_idx]); + const struct access_info ai = prepare_access_info(ptr, size, access_type); + + kcsan_report(&ai, KCSAN_VALUE_CHANGE_MAYBE, KCSAN_REPORT_CONSUMED_WATCHPOINT, + &other_infos[watchpoint_idx]); } void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type, enum kcsan_value_change value_change, int watchpoint_idx) { - kcsan_report(ptr, size, access_type, value_change, - KCSAN_REPORT_RACE_SIGNAL, &other_infos[watchpoint_idx]); + const struct access_info ai = prepare_access_info(ptr, size, access_type); + + kcsan_report(&ai, value_change, KCSAN_REPORT_RACE_SIGNAL, &other_infos[watchpoint_idx]); } void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type) { - kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_TRUE, - KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, NULL); + const struct access_info ai = prepare_access_info(ptr, size, access_type); + + kcsan_report(&ai, KCSAN_VALUE_CHANGE_TRUE, KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, NULL); } |