linux/kernel/kcsan/kcsan.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. For more info please
   4 * see Documentation/dev-tools/kcsan.rst.
   5 *
   6 * Copyright (C) 2019, Google LLC.
   7 */
   8
   9#ifndef _KERNEL_KCSAN_KCSAN_H
  10#define _KERNEL_KCSAN_KCSAN_H
  11
  12#include <linux/atomic.h>
  13#include <linux/kcsan.h>
  14#include <linux/sched.h>
  15
  16/* The number of adjacent watchpoints to check. */
  17#define KCSAN_CHECK_ADJACENT 1
  18#define NUM_SLOTS (1 + 2*KCSAN_CHECK_ADJACENT)
  19
  20extern unsigned int kcsan_udelay_task;
  21extern unsigned int kcsan_udelay_interrupt;
  22
  23/*
  24 * Globally enable and disable KCSAN.
  25 */
  26extern bool kcsan_enabled;
  27
  28/*
  29 * Save/restore IRQ flags state trace dirtied by KCSAN.
  30 */
  31void kcsan_save_irqtrace(struct task_struct *task);
  32void kcsan_restore_irqtrace(struct task_struct *task);
  33
  34/*
  35 * Statistics counters displayed via debugfs; should only be modified in
  36 * slow-paths.
  37 */
  38enum kcsan_counter_id {
  39        /*
  40         * Number of watchpoints currently in use.
  41         */
  42        KCSAN_COUNTER_USED_WATCHPOINTS,
  43
  44        /*
  45         * Total number of watchpoints set up.
  46         */
  47        KCSAN_COUNTER_SETUP_WATCHPOINTS,
  48
  49        /*
  50         * Total number of data races.
  51         */
  52        KCSAN_COUNTER_DATA_RACES,
  53
  54        /*
  55         * Total number of ASSERT failures due to races. If the observed race is
  56         * due to two conflicting ASSERT type accesses, then both will be
  57         * counted.
  58         */
  59        KCSAN_COUNTER_ASSERT_FAILURES,
  60
  61        /*
  62         * Number of times no watchpoints were available.
  63         */
  64        KCSAN_COUNTER_NO_CAPACITY,
  65
  66        /*
  67         * A thread checking a watchpoint raced with another checking thread;
  68         * only one will be reported.
  69         */
  70        KCSAN_COUNTER_REPORT_RACES,
  71
  72        /*
  73         * Observed data value change, but writer thread unknown.
  74         */
  75        KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN,
  76
  77        /*
  78         * The access cannot be encoded to a valid watchpoint.
  79         */
  80        KCSAN_COUNTER_UNENCODABLE_ACCESSES,
  81
  82        /*
  83         * Watchpoint encoding caused a watchpoint to fire on mismatching
  84         * accesses.
  85         */
  86        KCSAN_COUNTER_ENCODING_FALSE_POSITIVES,
  87
  88        KCSAN_COUNTER_COUNT, /* number of counters */
  89};
  90extern atomic_long_t kcsan_counters[KCSAN_COUNTER_COUNT];
  91
  92/*
  93 * Returns true if data races in the function symbol that maps to func_addr
  94 * (offsets are ignored) should *not* be reported.
  95 */
  96extern bool kcsan_skip_report_debugfs(unsigned long func_addr);
  97
  98/*
  99 * Value-change states.
 100 */
 101enum kcsan_value_change {
 102        /*
 103         * Did not observe a value-change, however, it is valid to report the
 104         * race, depending on preferences.
 105         */
 106        KCSAN_VALUE_CHANGE_MAYBE,
 107
 108        /*
 109         * Did not observe a value-change, and it is invalid to report the race.
 110         */
 111        KCSAN_VALUE_CHANGE_FALSE,
 112
 113        /*
 114         * The value was observed to change, and the race should be reported.
 115         */
 116        KCSAN_VALUE_CHANGE_TRUE,
 117};
 118
 119/*
 120 * The calling thread hit and consumed a watchpoint: set the access information
 121 * to be consumed by the reporting thread. No report is printed yet.
 122 */
 123void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type,
 124                           unsigned long ip, int watchpoint_idx);
 125
 126/*
 127 * The calling thread observed that the watchpoint it set up was hit and
 128 * consumed: print the full report based on information set by the racing
 129 * thread.
 130 */
 131void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type,
 132                               unsigned long ip, enum kcsan_value_change value_change,
 133                               int watchpoint_idx, u64 old, u64 new, u64 mask);
 134
 135/*
 136 * No other thread was observed to race with the access, but the data value
 137 * before and after the stall differs. Reports a race of "unknown origin".
 138 */
 139void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type,
 140                                 unsigned long ip, u64 old, u64 new, u64 mask);
 141
 142#endif /* _KERNEL_KCSAN_KCSAN_H */
 143