Pull KCSAN updates from Paul E. McKenney: - improve comments - introduce CONFIG_KCSAN_STRICT (which RCU uses) - optimize use of get_ctx() by kcsan_found_watchpoint() - rework atomic.h into permissive.h - add the ability to ignore writes that change only one bit of a given data-racy variable.
Unified · Split
| @@ -127,6 +127,18 @@ Kconfig options: · 126 unmodified lines | |||
| 127 | causes KCSAN to not report data races due to conflicts where the only plain | 127 | causes KCSAN to not report data races due to conflicts where the only plain |
| 128 | accesses are aligned writes up to word size. | 128 | accesses are aligned writes up to word size. |
| 129 | 129 | ||
| 130 | * ``CONFIG_KCSAN_PERMISSIVE``: Enable additional permissive rules to ignore | ||
| 131 | certain classes of common data races. Unlike the above, the rules are more | ||
| 132 | complex involving value-change patterns, access type, and address. This | ||
| 133 | option depends on ``CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=y``. For details | ||
| 134 | please see the ``kernel/kcsan/permissive.h``. Testers and maintainers that | ||
| 135 | only focus on reports from specific subsystems and not the whole kernel are | ||
| 136 | recommended to disable this option. | ||
| 137 | |||
| 138 | To use the strictest possible rules, select ``CONFIG_KCSAN_STRICT=y``, which | ||
| 139 | configures KCSAN to follow the Linux-kernel memory consistency model (LKMM) as | ||
| 140 | closely as possible. | ||
| 141 | |||
| 130 | DebugFS interface | 142 | DebugFS interface |
| 131 | ~~~~~~~~~~~~~~~~~ | 143 | ~~~~~~~~~~~~~~~~~ |
| 132 | 144 | ||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Rules for implicitly atomic memory accesses. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2019, Google LLC. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _KERNEL_KCSAN_ATOMIC_H | ||
| 9 | #define _KERNEL_KCSAN_ATOMIC_H | ||
| 10 | |||
| 11 | #include <linux/types.h> | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Special rules for certain memory where concurrent conflicting accesses are | ||
| 15 | * common, however, the current convention is to not mark them; returns true if | ||
| 16 | * access to @ptr should be considered atomic. Called from slow-path. | ||
| 17 | */ | ||
| 18 | static bool kcsan_is_atomic_special(const volatile void *ptr) | ||
| 19 | { | ||
| 20 | return false; | ||
| 21 | } | ||
| 22 | |||
| 23 | #endif /* _KERNEL_KCSAN_ATOMIC_H */ | ||
| @@ -20,9 +20,9 @@ · 19 unmodified lines | |||
| 20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
| 21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | 22 | ||
| 23 | #include "atomic.h" | ||
| 24 | #include "encoding.h" | 23 | #include "encoding.h" |
| 25 | #include "kcsan.h" | 24 | #include "kcsan.h" |
| 25 | #include "permissive.h" | ||
| 26 | 26 | ||
| 27 | static bool kcsan_early_enable = IS_ENABLED(CONFIG_KCSAN_EARLY_ENABLE); | 27 | static bool kcsan_early_enable = IS_ENABLED(CONFIG_KCSAN_EARLY_ENABLE); |
| 28 | unsigned int kcsan_udelay_task = CONFIG_KCSAN_UDELAY_TASK; | 28 | unsigned int kcsan_udelay_task = CONFIG_KCSAN_UDELAY_TASK; |
| @@ -301,9 +301,9 @@ static inline void reset_kcsan_skip(void) · 272 unmodified lines | |||
| 301 | this_cpu_write(kcsan_skip, skip_count); | 301 | this_cpu_write(kcsan_skip, skip_count); |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | static __always_inline bool kcsan_is_enabled(void) | 304 | static __always_inline bool kcsan_is_enabled(struct kcsan_ctx *ctx) |
| 305 | { | 305 | { |
| 306 | return READ_ONCE(kcsan_enabled) && get_ctx()->disable_count == 0; | 306 | return READ_ONCE(kcsan_enabled) && !ctx->disable_count; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | /* Introduce delay depending on context and configuration. */ | 309 | /* Introduce delay depending on context and configuration. */ |
| @@ -353,10 +353,18 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, · 43 unmodified lines | |||
| 353 | atomic_long_t *watchpoint, | 353 | atomic_long_t *watchpoint, |
| 354 | long encoded_watchpoint) | 354 | long encoded_watchpoint) |
| 355 | { | 355 | { |
| 356 | const bool is_assert = (type & KCSAN_ACCESS_ASSERT) != 0; | ||
| 357 | struct kcsan_ctx *ctx = get_ctx(); | ||
| 356 | unsigned long flags; | 358 | unsigned long flags; |
| 357 | bool consumed; | 359 | bool consumed; |
| 358 | 360 | ||
| 359 | if (!kcsan_is_enabled()) | 361 | /* |
| 362 | * We know a watchpoint exists. Let's try to keep the race-window | ||
| 363 | * between here and finally consuming the watchpoint below as small as | ||
| 364 | * possible -- avoid unneccessarily complex code until consumed. | ||
| 365 | */ | ||
| 366 | |||
| 367 | if (!kcsan_is_enabled(ctx)) | ||
| 360 | return; | 368 | return; |
| 361 | 369 | ||
| 362 | /* | 370 | /* |
| @@ -364,14 +372,22 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, · 1 unmodified line | |||
| 364 | * reporting a race where e.g. the writer set up the watchpoint, but the | 372 | * reporting a race where e.g. the writer set up the watchpoint, but the |
| 365 | * reader has access_mask!=0, we have to ignore the found watchpoint. | 373 | * reader has access_mask!=0, we have to ignore the found watchpoint. |
| 366 | */ | 374 | */ |
| 367 | if (get_ctx()->access_mask != 0) | 375 | if (ctx->access_mask) |
| 368 | return; | 376 | return; |
| 369 | 377 | ||
| 370 | /* | 378 | /* |
| 371 | * Consume the watchpoint as soon as possible, to minimize the chances | 379 | * If the other thread does not want to ignore the access, and there was |
| 372 | * of !consumed. Consuming the watchpoint must always be guarded by | 380 | * a value change as a result of this thread's operation, we will still |
| 373 | * kcsan_is_enabled() check, as otherwise we might erroneously | 381 | * generate a report of unknown origin. |
| 374 | * triggering reports when disabled. | 382 | * |
| 383 | * Use CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN=n to filter. | ||
| 384 | */ | ||
| 385 | if (!is_assert && kcsan_ignore_address(ptr)) | ||
| 386 | return; | ||
| 387 | |||
| 388 | /* | ||
| 389 | * Consuming the watchpoint must be guarded by kcsan_is_enabled() to | ||
| 390 | * avoid erroneously triggering reports if the context is disabled. | ||
| 375 | */ | 391 | */ |
| 376 | consumed = try_consume_watchpoint(watchpoint, encoded_watchpoint); | 392 | consumed = try_consume_watchpoint(watchpoint, encoded_watchpoint); |
| 377 | 393 | ||
| @@ -391,7 +407,7 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, · 13 unmodified lines | |||
| 391 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_REPORT_RACES]); | 407 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_REPORT_RACES]); |
| 392 | } | 408 | } |
| 393 | 409 | ||
| 394 | if ((type & KCSAN_ACCESS_ASSERT) != 0) | 410 | if (is_assert) |
| 395 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]); | 411 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]); |
| 396 | else | 412 | else |
| 397 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_DATA_RACES]); | 413 | atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_DATA_RACES]); |
| @@ -409,6 +425,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 11 unmodified lines | |||
| 409 | unsigned long access_mask; | 425 | unsigned long access_mask; |
| 410 | enum kcsan_value_change value_change = KCSAN_VALUE_CHANGE_MAYBE; | 426 | enum kcsan_value_change value_change = KCSAN_VALUE_CHANGE_MAYBE; |
| 411 | unsigned long ua_flags = user_access_save(); | 427 | unsigned long ua_flags = user_access_save(); |
| 428 | struct kcsan_ctx *ctx = get_ctx(); | ||
| 412 | unsigned long irq_flags = 0; | 429 | unsigned long irq_flags = 0; |
| 413 | 430 | ||
| 414 | /* | 431 | /* |
| @@ -417,16 +434,14 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 2 unmodified lines | |||
| 417 | */ | 434 | */ |
| 418 | reset_kcsan_skip(); | 435 | reset_kcsan_skip(); |
| 419 | 436 | ||
| 420 | if (!kcsan_is_enabled()) | 437 | if (!kcsan_is_enabled(ctx)) |
| 421 | goto out; | 438 | goto out; |
| 422 | 439 | ||
| 423 | /* | 440 | /* |
| 424 | * Special atomic rules: unlikely to be true, so we check them here in | 441 | * Check to-ignore addresses after kcsan_is_enabled(), as we may access |
| 425 | * the slow-path, and not in the fast-path in is_atomic(). Call after | 442 | * memory that is not yet initialized during early boot. |
| 426 | * kcsan_is_enabled(), as we may access memory that is not yet | ||
| 427 | * initialized during early boot. | ||
| 428 | */ | 443 | */ |
| 429 | if (!is_assert && kcsan_is_atomic_special(ptr)) | 444 | if (!is_assert && kcsan_ignore_address(ptr)) |
| 430 | goto out; | 445 | goto out; |
| 431 | 446 | ||
| 432 | if (!check_encodable((unsigned long)ptr, size)) { | 447 | if (!check_encodable((unsigned long)ptr, size)) { |
| @@ -479,15 +494,6 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 46 unmodified lines | |||
| 479 | break; /* ignore; we do not diff the values */ | 494 | break; /* ignore; we do not diff the values */ |
| 480 | } | 495 | } |
| 481 | 496 | ||
| 482 | if (IS_ENABLED(CONFIG_KCSAN_DEBUG)) { | ||
| 483 | kcsan_disable_current(); | ||
| 484 | pr_err("watching %s, size: %zu, addr: %px [slot: %d, encoded: %lx]\n", | ||
| 485 | is_write ? "write" : "read", size, ptr, | ||
| 486 | watchpoint_slot((unsigned long)ptr), | ||
| 487 | encode_watchpoint((unsigned long)ptr, size, is_write)); | ||
| 488 | kcsan_enable_current(); | ||
| 489 | } | ||
| 490 | |||
| 491 | /* | 497 | /* |
| 492 | * Delay this thread, to increase probability of observing a racy | 498 | * Delay this thread, to increase probability of observing a racy |
| 493 | * conflicting access. | 499 | * conflicting access. |
| @@ -498,7 +504,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 4 unmodified lines | |||
| 498 | * Re-read value, and check if it is as expected; if not, we infer a | 504 | * Re-read value, and check if it is as expected; if not, we infer a |
| 499 | * racy access. | 505 | * racy access. |
| 500 | */ | 506 | */ |
| 501 | access_mask = get_ctx()->access_mask; | 507 | access_mask = ctx->access_mask; |
| 502 | new = 0; | 508 | new = 0; |
| 503 | switch (size) { | 509 | switch (size) { |
| 504 | case 1: | 510 | case 1: |
| @@ -521,8 +527,14 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) · 16 unmodified lines | |||
| 521 | if (access_mask) | 527 | if (access_mask) |
| 522 | diff &= access_mask; | 528 | diff &= access_mask; |
| 523 | 529 | ||
| 524 | /* Were we able to observe a value-change? */ | 530 | /* |
| 525 | if (diff != 0) | 531 | * Check if we observed a value change. |
| 532 | * | ||
| 533 | * Also check if the data race should be ignored (the rules depend on | ||
| 534 | * non-zero diff); if it is to be ignored, the below rules for | ||
| 535 | * KCSAN_VALUE_CHANGE_MAYBE apply. | ||
| 536 | */ | ||
| 537 | if (diff && !kcsan_ignore_data_race(size, type, old, new, diff)) | ||
| 526 | value_change = KCSAN_VALUE_CHANGE_TRUE; | 538 | value_change = KCSAN_VALUE_CHANGE_TRUE; |
| 527 | 539 | ||
| 528 | /* Check if this access raced with another. */ | 540 | /* Check if this access raced with another. */ |
| @@ -644,6 +656,15 @@ void __init kcsan_init(void) · 115 unmodified lines | |||
| 644 | pr_info("enabled early\n"); | 656 | pr_info("enabled early\n"); |
| 645 | WRITE_ONCE(kcsan_enabled, true); | 657 | WRITE_ONCE(kcsan_enabled, true); |
| 646 | } | 658 | } |
| 659 | |||
| 660 | if (IS_ENABLED(CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY) || | ||
| 661 | IS_ENABLED(CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC) || | ||
| 662 | IS_ENABLED(CONFIG_KCSAN_PERMISSIVE) || | ||
| 663 | IS_ENABLED(CONFIG_KCSAN_IGNORE_ATOMICS)) { | ||
| 664 | pr_warn("non-strict mode configured - use CONFIG_KCSAN_STRICT=y to see all data races\n"); | ||
| 665 | } else { | ||
| 666 | pr_info("strict mode configured\n"); | ||
| 667 | } | ||
| 647 | } | 668 | } |
| 648 | 669 | ||
| 649 | /* === Exported interface =================================================== */ | 670 | /* === Exported interface =================================================== */ |
| @@ -414,6 +414,14 @@ static noinline void test_kernel_atomic_builtins(void) · 413 unmodified lines | |||
| 414 | __atomic_load_n(&test_var, __ATOMIC_RELAXED); | 414 | __atomic_load_n(&test_var, __ATOMIC_RELAXED); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static noinline void test_kernel_xor_1bit(void) | ||
| 418 | { | ||
| 419 | /* Do not report data races between the read-writes. */ | ||
| 420 | kcsan_nestable_atomic_begin(); | ||
| 421 | test_var ^= 0x10000; | ||
| 422 | kcsan_nestable_atomic_end(); | ||
| 423 | } | ||
| 424 | |||
| 417 | /* ===== Test cases ===== */ | 425 | /* ===== Test cases ===== */ |
| 418 | 426 | ||
| 419 | /* Simple test with normal data race. */ | 427 | /* Simple test with normal data race. */ |
| @@ -952,6 +960,29 @@ static void test_atomic_builtins(struct kunit *test) · 532 unmodified lines | |||
| 952 | KUNIT_EXPECT_FALSE(test, match_never); | 960 | KUNIT_EXPECT_FALSE(test, match_never); |
| 953 | } | 961 | } |
| 954 | 962 | ||
| 963 | __no_kcsan | ||
| 964 | static void test_1bit_value_change(struct kunit *test) | ||
| 965 | { | ||
| 966 | const struct expect_report expect = { | ||
| 967 | .access = { | ||
| 968 | { test_kernel_read, &test_var, sizeof(test_var), 0 }, | ||
| 969 | { test_kernel_xor_1bit, &test_var, sizeof(test_var), __KCSAN_ACCESS_RW(KCSAN_ACCESS_WRITE) }, | ||
| 970 | }, | ||
| 971 | }; | ||
| 972 | bool match = false; | ||
| 973 | |||
| 974 | begin_test_checks(test_kernel_read, test_kernel_xor_1bit); | ||
| 975 | do { | ||
| 976 | match = IS_ENABLED(CONFIG_KCSAN_PERMISSIVE) | ||
| 977 | ? report_available() | ||
| 978 | : report_matches(&expect); | ||
| 979 | } while (!end_test_checks(match)); | ||
| 980 | if (IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) | ||
| 981 | KUNIT_EXPECT_FALSE(test, match); | ||
| 982 | else | ||
| 983 | KUNIT_EXPECT_TRUE(test, match); | ||
| 984 | } | ||
| 985 | |||
| 955 | /* | 986 | /* |
| 956 | * Generate thread counts for all test cases. Values generated are in interval | 987 | * Generate thread counts for all test cases. Values generated are in interval |
| 957 | * [2, 5] followed by exponentially increasing thread counts from 8 to 32. | 988 | * [2, 5] followed by exponentially increasing thread counts from 8 to 32. |
| @@ -1024,6 +1055,7 @@ static struct kunit_case kcsan_test_cases[] = { · 66 unmodified lines | |||
| 1024 | KCSAN_KUNIT_CASE(test_jiffies_noreport), | 1055 | KCSAN_KUNIT_CASE(test_jiffies_noreport), |
| 1025 | KCSAN_KUNIT_CASE(test_seqlock_noreport), | 1056 | KCSAN_KUNIT_CASE(test_seqlock_noreport), |
| 1026 | KCSAN_KUNIT_CASE(test_atomic_builtins), | 1057 | KCSAN_KUNIT_CASE(test_atomic_builtins), |
| 1058 | KCSAN_KUNIT_CASE(test_1bit_value_change), | ||
| 1027 | {}, | 1059 | {}, |
| 1028 | }; | 1060 | }; |
| 1029 | 1061 | ||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Special rules for ignoring entire classes of data-racy memory accesses. None | ||
| 4 | * of the rules here imply that such data races are generally safe! | ||
| 5 | * | ||
| 6 | * All rules in this file can be configured via CONFIG_KCSAN_PERMISSIVE. Keep | ||
| 7 | * them separate from core code to make it easier to audit. | ||
| 8 | * | ||
| 9 | * Copyright (C) 2019, Google LLC. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _KERNEL_KCSAN_PERMISSIVE_H | ||
| 13 | #define _KERNEL_KCSAN_PERMISSIVE_H | ||
| 14 | |||
| 15 | #include <linux/bitops.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Access ignore rules based on address. | ||
| 21 | */ | ||
| 22 | static __always_inline bool kcsan_ignore_address(const volatile void *ptr) | ||
| 23 | { | ||
| 24 | if (!IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) | ||
| 25 | return false; | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Data-racy bitops on current->flags are too common, ignore completely | ||
| 29 | * for now. | ||
| 30 | */ | ||
| 31 | return ptr == ¤t->flags; | ||
| 32 | } | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Data race ignore rules based on access type and value change patterns. | ||
| 36 | */ | ||
| 37 | static bool | ||
| 38 | kcsan_ignore_data_race(size_t size, int type, u64 old, u64 new, u64 diff) | ||
| 39 | { | ||
| 40 | if (!IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) | ||
| 41 | return false; | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Rules here are only for plain read accesses, so that we still report | ||
| 45 | * data races between plain read-write accesses. | ||
| 46 | */ | ||
| 47 | if (type || size > sizeof(long)) | ||
| 48 | return false; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * A common pattern is checking/setting just 1 bit in a variable; for | ||
| 52 | * example: | ||
| 53 | * | ||
| 54 | * if (flags & SOME_FLAG) { ... } | ||
| 55 | * | ||
| 56 | * and elsewhere flags is updated concurrently: | ||
| 57 | * | ||
| 58 | * flags |= SOME_OTHER_FLAG; // just 1 bit | ||
| 59 | * | ||
| 60 | * While it is still recommended that such accesses be marked | ||
| 61 | * appropriately, in many cases these types of data races are so common | ||
| 62 | * that marking them all is often unrealistic and left to maintainer | ||
| 63 | * preference. | ||
| 64 | * | ||
| 65 | * The assumption in all cases is that with all known compiler | ||
| 66 | * optimizations (including those that tear accesses), because no more | ||
| 67 | * than 1 bit changed, the plain accesses are safe despite the presence | ||
| 68 | * of data races. | ||
| 69 | * | ||
| 70 | * The rules here will ignore the data races if we observe no more than | ||
| 71 | * 1 bit changed. | ||
| 72 | * | ||
| 73 | * Of course many operations can effecively change just 1 bit, but the | ||
| 74 | * general assuption that data races involving 1-bit changes can be | ||
| 75 | * tolerated still applies. | ||
| 76 | * | ||
| 77 | * And in case a true bug is missed, the bug likely manifests as a | ||
| 78 | * reportable data race elsewhere. | ||
| 79 | */ | ||
| 80 | if (hweight64(diff) == 1) { | ||
| 81 | /* | ||
| 82 | * Exception: Report data races where the values look like | ||
| 83 | * ordinary booleans (one of them was 0 and the 0th bit was | ||
| 84 | * changed) More often than not, they come with interesting | ||
| 85 | * memory ordering requirements, so let's report them. | ||
| 86 | */ | ||
| 87 | if (!((!old || !new) && diff == 1)) | ||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | return false; | ||
| 92 | } | ||
| 93 | |||
| 94 | #endif /* _KERNEL_KCSAN_PERMISSIVE_H */ | ||
| @@ -40,10 +40,14 @@ menuconfig KCSAN · 39 unmodified lines | |||
| 40 | 40 | ||
| 41 | if KCSAN | 41 | if KCSAN |
| 42 | 42 | ||
| 43 | # Compiler capabilities that should not fail the test if they are unavailable. | ||
| 44 | config CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE | 43 | config CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE |
| 45 | def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=thread -mllvm -tsan-compound-read-before-write=1)) || \ | 44 | def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=thread -mllvm -tsan-compound-read-before-write=1)) || \ |
| 46 | (CC_IS_GCC && $(cc-option,-fsanitize=thread --param tsan-compound-read-before-write=1)) | 45 | (CC_IS_GCC && $(cc-option,-fsanitize=thread --param tsan-compound-read-before-write=1)) |
| 46 | help | ||
| 47 | The compiler instruments plain compound read-write operations | ||
| 48 | differently (++, --, +=, -=, |=, &=, etc.), which allows KCSAN to | ||
| 49 | distinguish them from other plain accesses. This is currently | ||
| 50 | supported by Clang 12 or later. | ||
| 47 | 51 | ||
| 48 | config KCSAN_VERBOSE | 52 | config KCSAN_VERBOSE |
| 49 | bool "Show verbose reports with more information about system state" | 53 | bool "Show verbose reports with more information about system state" |
| @@ -58,9 +62,6 @@ config KCSAN_VERBOSE · 8 unmodified lines | |||
| 58 | generated from any one of them, system stability may suffer due to | 62 | generated from any one of them, system stability may suffer due to |
| 59 | deadlocks or recursion. If in doubt, say N. | 63 | deadlocks or recursion. If in doubt, say N. |
| 60 | 64 | ||
| 61 | config KCSAN_DEBUG | ||
| 62 | bool "Debugging of KCSAN internals" | ||
| 63 | |||
| 64 | config KCSAN_SELFTEST | 65 | config KCSAN_SELFTEST |
| 65 | bool "Perform short selftests on boot" | 66 | bool "Perform short selftests on boot" |
| 66 | default y | 67 | default y |
| @@ -149,7 +150,8 @@ config KCSAN_SKIP_WATCH_RANDOMIZE · 82 unmodified lines | |||
| 149 | KCSAN_WATCH_SKIP. | 150 | KCSAN_WATCH_SKIP. |
| 150 | 151 | ||
| 151 | config KCSAN_INTERRUPT_WATCHER | 152 | config KCSAN_INTERRUPT_WATCHER |
| 152 | bool "Interruptible watchers" | 153 | bool "Interruptible watchers" if !KCSAN_STRICT |
| 154 | default KCSAN_STRICT | ||
| 153 | help | 155 | help |
| 154 | If enabled, a task that set up a watchpoint may be interrupted while | 156 | If enabled, a task that set up a watchpoint may be interrupted while |
| 155 | delayed. This option will allow KCSAN to detect races between | 157 | delayed. This option will allow KCSAN to detect races between |
| @@ -169,13 +171,9 @@ config KCSAN_REPORT_ONCE_IN_MS · 13 unmodified lines | |||
| 169 | reporting to avoid flooding the console with reports. Setting this | 171 | reporting to avoid flooding the console with reports. Setting this |
| 170 | to 0 disables rate limiting. | 172 | to 0 disables rate limiting. |
| 171 | 173 | ||
| 172 | # The main purpose of the below options is to control reported data races (e.g. | 174 | # The main purpose of the below options is to control reported data races, and |
| 173 | # in fuzzer configs), and are not expected to be switched frequently by other | 175 | # are not expected to be switched frequently by non-testers or at runtime. |
| 174 | # users. We could turn some of them into boot parameters, but given they should | 176 | # The defaults are chosen to be conservative, and can miss certain bugs. |
| 175 | # not be switched normally, let's keep them here to simplify configuration. | ||
| 176 | # | ||
| 177 | # The defaults below are chosen to be very conservative, and may miss certain | ||
| 178 | # bugs. | ||
| 179 | 177 | ||
| 180 | config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN | 178 | config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN |
| 181 | bool "Report races of unknown origin" | 179 | bool "Report races of unknown origin" |
| @@ -186,9 +184,17 @@ config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN · 4 unmodified lines | |||
| 186 | reported if it was only possible to infer a race due to a data value | 184 | reported if it was only possible to infer a race due to a data value |
| 187 | change while an access is being delayed on a watchpoint. | 185 | change while an access is being delayed on a watchpoint. |
| 188 | 186 | ||
| 187 | config KCSAN_STRICT | ||
| 188 | bool "Strict data-race checking" | ||
| 189 | help | ||
| 190 | KCSAN will report data races with the strictest possible rules, which | ||
| 191 | closely aligns with the rules defined by the Linux-kernel memory | ||
| 192 | consistency model (LKMM). | ||
| 193 | |||
| 189 | config KCSAN_REPORT_VALUE_CHANGE_ONLY | 194 | config KCSAN_REPORT_VALUE_CHANGE_ONLY |
| 190 | bool "Only report races where watcher observed a data value change" | 195 | bool "Only report races where watcher observed a data value change" |
| 191 | default y | 196 | default y |
| 197 | depends on !KCSAN_STRICT | ||
| 192 | help | 198 | help |
| 193 | If enabled and a conflicting write is observed via a watchpoint, but | 199 | If enabled and a conflicting write is observed via a watchpoint, but |
| 194 | the data value of the memory location was observed to remain | 200 | the data value of the memory location was observed to remain |
| @@ -197,6 +203,7 @@ config KCSAN_REPORT_VALUE_CHANGE_ONLY · 2 unmodified lines | |||
| 197 | config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC | 203 | config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC |
| 198 | bool "Assume that plain aligned writes up to word size are atomic" | 204 | bool "Assume that plain aligned writes up to word size are atomic" |
| 199 | default y | 205 | default y |
| 206 | depends on !KCSAN_STRICT | ||
| 200 | help | 207 | help |
| 201 | Assume that plain aligned writes up to word size are atomic by | 208 | Assume that plain aligned writes up to word size are atomic by |
| 202 | default, and also not subject to other unsafe compiler optimizations | 209 | default, and also not subject to other unsafe compiler optimizations |
| @@ -209,6 +216,7 @@ config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC · 6 unmodified lines | |||
| 209 | 216 | ||
| 210 | config KCSAN_IGNORE_ATOMICS | 217 | config KCSAN_IGNORE_ATOMICS |
| 211 | bool "Do not instrument marked atomic accesses" | 218 | bool "Do not instrument marked atomic accesses" |
| 219 | depends on !KCSAN_STRICT | ||
| 212 | help | 220 | help |
| 213 | Never instrument marked atomic accesses. This option can be used for | 221 | Never instrument marked atomic accesses. This option can be used for |
| 214 | additional filtering. Conflicting marked atomic reads and plain | 222 | additional filtering. Conflicting marked atomic reads and plain |
| @@ -224,4 +232,14 @@ config KCSAN_IGNORE_ATOMICS · 9 unmodified lines | |||
| 224 | due to two conflicting plain writes will be reported (aligned and | 232 | due to two conflicting plain writes will be reported (aligned and |
| 225 | unaligned, if CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n). | 233 | unaligned, if CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n). |
| 226 | 234 | ||
| 235 | config KCSAN_PERMISSIVE | ||
| 236 | bool "Enable all additional permissive rules" | ||
| 237 | depends on KCSAN_REPORT_VALUE_CHANGE_ONLY | ||
| 238 | help | ||
| 239 | Enable additional permissive rules to ignore certain classes of data | ||
| 240 | races (also see kernel/kcsan/permissive.h). None of the permissive | ||
| 241 | rules imply that such data races are generally safe, but can be used | ||
| 242 | to further reduce reported data races due to data-racy patterns | ||
| 243 | common across the kernel. | ||
| 244 | |||
| 227 | endif # KCSAN | 245 | endif # KCSAN |