Lines Matching +full:disable +full:- +full:report +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0
24 * Max. number of stack entries to show in the report.
40 * up the watchpoint, which then prints the complete report atomically.
69 * as we have watchpoints (upper bound on concurrent races to report).
71 static struct other_info other_infos[CONFIG_KCSAN_NUM_WATCHPOINTS + NUM_SLOTS-1];
95 * Therefore, we use a fixed-size array, which at most will occupy a page. This
108 * Spinlock serializing report generation, and access to @other_infos. Although
109 * it could make sense to have a finer-grained locking story for @other_infos,
110 * report generation needs to be serialized either way, so not much is gained.
116 * been reported since (now - KCSAN_REPORT_ONCE_IN_MS).
129 invalid_before = jiffies - msecs_to_jiffies(CONFIG_KCSAN_REPORT_ONCE_IN_MS); in rate_limit_report()
131 /* Check if a matching race report exists. */ in rate_limit_report()
141 if (time_before(rt->time, use_entry->time)) in rate_limit_report()
148 if (rt->time == 0) in rate_limit_report()
152 if (time_before(rt->time, invalid_before)) in rate_limit_report()
156 if ((rt->frame1 == frame1 && rt->frame2 == frame2) || in rate_limit_report()
157 (rt->frame1 == frame2 && rt->frame2 == frame1)) in rate_limit_report()
161 use_entry->time = jiffies; in rate_limit_report()
162 use_entry->frame1 = frame1; in rate_limit_report()
163 use_entry->frame2 = frame2; in rate_limit_report()
181 * 1. read watchpoint, conflicting write (value_change==TRUE): report; in skip_report()
183 * 3. write watchpoint, conflicting write (value_change==TRUE): report; in skip_report()
186 * 6. write watchpoint, conflicting read (value_change==TRUE): report; in skip_report()
188 * Cases 1-4 are intuitive and expected; case 5 ensures we do not report in skip_report()
198 * We opt-out of this filter for certain functions at request of in skip_report()
239 return "read-write"; in get_access_type()
241 return "read-write (marked)"; in get_access_type()
251 return "read-write (reordered)"; in get_access_type()
253 return "read-write (marked, reordered)"; in get_access_type()
261 return (type & KCSAN_ACCESS_ASSERT) != 0 ? "assert: race" : "data-race"; in get_bug_type()
267 if (task_id != -1) { in get_thread_desc()
276 /* Helper to skip KCSAN-related functions in stack-trace. */
300 * No match for runtime functions -- @skip entries to skip to in get_stack_skipnr()
323 target_func = ip - offset; in replace_stack_entry()
332 func -= offset; in replace_stack_entry()
372 pr_err(" |\n +-> reordered to: %pS\n", (void *)reordered_to); in print_stack_trace()
391 u64 old, u64 new, u64 mask) in print_report() argument
396 int skipnr = sanitize_stack_entries(stack_entries, num_stack_entries, ai->ip, &reordered_to); in print_report()
403 * Must check report filter rules before starting to print. in print_report()
409 other_skipnr = sanitize_stack_entries(other_info->stack_entries, in print_report()
410 other_info->num_stack_entries, in print_report()
411 other_info->ai.ip, &other_reordered_to); in print_report()
412 other_frame = other_info->stack_entries[other_skipnr]; in print_report()
422 /* Print report header. */ in print_report()
433 get_bug_type(ai->access_type | other_info->ai.access_type), in print_report()
437 pr_err("BUG: KCSAN: %s in %pS\n", get_bug_type(ai->access_type), in print_report()
446 get_access_type(other_info->ai.access_type), other_info->ai.ptr, in print_report()
447 other_info->ai.size, get_thread_desc(other_info->ai.task_pid), in print_report()
448 other_info->ai.cpu_id); in print_report()
451 print_stack_trace(other_info->stack_entries + other_skipnr, in print_report()
452 other_info->num_stack_entries - other_skipnr, in print_report()
455 print_verbose_info(other_info->task); in print_report()
459 get_access_type(ai->access_type), ai->ptr, ai->size, in print_report()
460 get_thread_desc(ai->task_pid), ai->cpu_id); in print_report()
463 get_access_type(ai->access_type), ai->ptr, ai->size, in print_report()
464 get_thread_desc(ai->task_pid), ai->cpu_id); in print_report()
467 print_stack_trace(stack_entries + skipnr, num_stack_entries - skipnr, reordered_to); in print_report()
472 if (ai->size <= 8) { in print_report()
473 int hex_len = ai->size * 2; in print_report()
476 if (mask) in print_report()
477 diff &= mask; in print_report()
480 pr_err("value changed: 0x%0*llx -> 0x%0*llx\n", in print_report()
482 if (mask) { in print_report()
483 pr_err(" bits changed: 0x%0*llx with mask 0x%0*llx\n", in print_report()
484 hex_len, diff, hex_len, mask); in print_report()
489 /* Print report footer. */ in print_report()
502 * 0-sized accesses. in release_report()
504 other_info->ai.size = 0; in release_report()
509 * Sets @other_info->task and awaits consumption of @other_info.
519 * We may be instrumenting a code-path where current->state is already in set_other_info_task_blocking()
533 other_info->task = current; in set_other_info_task_blocking()
546 * determine if sleeping here is permitted -- see in_atomic(). in set_other_info_task_blocking()
551 if (timeout-- < 0) { in set_other_info_task_blocking()
553 * Abort. Reset @other_info->task to NULL, since it in set_other_info_task_blocking()
558 other_info->task = NULL; in set_other_info_task_blocking()
565 } while (other_info->ai.size && other_info->ai.ptr == ai->ptr && in set_other_info_task_blocking()
566 other_info->task == current); in set_other_info_task_blocking()
580 * there is a one-to-one mapping to watchpoint slots (@watchpoints in in prepare_report_producer()
587 * To check this property holds, size should never be non-zero here, in prepare_report_producer()
591 WARN_ON(other_info->ai.size); in prepare_report_producer()
593 other_info->ai = *ai; in prepare_report_producer()
594 other_info->num_stack_entries = stack_trace_save(other_info->stack_entries, NUM_STACK_ENTRIES, 2); in prepare_report_producer()
609 while (!other_info->ai.size) { /* Await valid @other_info. */ in prepare_report_consumer()
616 …if (WARN_ON(!matching_access((unsigned long)other_info->ai.ptr & WATCHPOINT_ADDR_MASK, other_info-… in prepare_report_consumer()
617 (unsigned long)ai->ptr & WATCHPOINT_ADDR_MASK, ai->size))) in prepare_report_consumer()
620 if (!matching_access((unsigned long)other_info->ai.ptr, other_info->ai.size, in prepare_report_consumer()
621 (unsigned long)ai->ptr, ai->size)) { in prepare_report_consumer()
644 .task_pid = in_task() ? task_pid_nr(current) : -1, in prepare_access_info()
668 int watchpoint_idx, u64 old, u64 new, u64 mask) in kcsan_report_known_origin() argument
678 * called in print_report() is scheduler-safe, accept the risk, and just in kcsan_report_known_origin()
679 * get our message out. As such, also disable lockdep to hide the in kcsan_report_known_origin()
687 * Never report if value_change is FALSE, only when it is in kcsan_report_known_origin()
692 print_report(value_change, &ai, other_info, old, new, mask); in kcsan_report_known_origin()
701 unsigned long ip, u64 old, u64 new, u64 mask) in kcsan_report_unknown_origin() argument
710 print_report(KCSAN_VALUE_CHANGE_TRUE, &ai, NULL, old, new, mask); in kcsan_report_unknown_origin()