* [PATCH 1/2] kbuild: rust: enable KCSAN support
@ 2026-10-12 13:39 Marco Elver
2026-10-12 13:39 ` [PATCH 2/2] rust: kcsan: add KUnit test for data race detection Marco Elver
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Marco Elver @ 2026-10-12 13:39 UTC (permalink / raw)
To: elver, Boqun Feng, Miguel Ojeda, Gary Guo
Cc: Alexander Potapenko, kasan-dev, linux-kernel, Jonathan Corbet,
Shuah Khan, Randy Dunlap, Andrew Morton, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Nathan Chancellor,
Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt,
Asahi Lina, Yury Norov, Eliot Courtney, Joel Fernandes,
workflows, linux-doc, rust-for-linux, linux-kbuild, llvm
Rust supports ThreadSanitizer instrumentation via LLVM, which is what
KCSAN relies on; however, Rust code is not currently instrumented.
Pass -Zsanitizer=thread and the same TSan backend options used for C
code to rustc. Wire up KCSAN_SANITIZE in scripts/Makefile.lib for parity
with C (though rustc currently rejects linking crates with mismatched
instrumentation).
rustc only accepts -Zsanitizer=thread for targets that declare support
for it. Of the targets used by the kernel, this is only possible for the
generated x86_64 target specification, so restrict instrumentation of
Rust code to x86_64 for now via HAVE_KCSAN_RUSTC. On other architectures
Rust code remains uninstrumented as before.
All TSan options used are supported by the LLVM versions of the minimum
supported rustc, so no rustc-option checks are needed (they would also
fail, because x86_64-unknown-none used for option checks does not
support -Zsanitizer=thread).
With this enabled we can detect data races in kernel Rust code and
between Rust and C code.
Signed-off-by: Marco Elver <elver@google.com>
---
Documentation/dev-tools/kcsan.rst | 7 +++++++
lib/Kconfig.kcsan | 7 +++++++
scripts/Makefile.kcsan | 13 +++++++++++++
scripts/Makefile.lib | 3 +++
scripts/generate_rust_target.rs | 2 +-
5 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/Documentation/dev-tools/kcsan.rst b/Documentation/dev-tools/kcsan.rst
index 8575178aa87f..3bb8754f844b 100644
--- a/Documentation/dev-tools/kcsan.rst
+++ b/Documentation/dev-tools/kcsan.rst
@@ -14,6 +14,9 @@ Usage
KCSAN is supported by both GCC and Clang. With GCC we require version 11 or
later, and with Clang also require version 11 or later.
+Rust code is instrumented as well on architectures whose Rust target supports
+it (currently only x86_64; see ``CONFIG_HAVE_KCSAN_RUSTC``).
+
To enable KCSAN configure the kernel with::
CONFIG_KCSAN = y
@@ -121,6 +124,10 @@ the below options are available:
KCSAN_SANITIZE := n
+ Note that ``rustc`` rejects linking crates built with and without KCSAN
+ instrumentation, so ``KCSAN_SANITIZE`` and ``KCSAN_SANITIZE_<target>.o``
+ cannot currently be used for Rust code.
+
.. _"Marking Shared-Memory Accesses" in the LKMM: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/memory-model/Documentation/access-marking.txt
Furthermore, it is possible to tell KCSAN to show or hide entire classes of
diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan
index 4ce4b0c0109c..f0096e1c8b61 100644
--- a/lib/Kconfig.kcsan
+++ b/lib/Kconfig.kcsan
@@ -10,6 +10,13 @@ config HAVE_KCSAN_COMPILER
For the list of compilers that support KCSAN, please see
<file:Documentation/dev-tools/kcsan.rst>.
+config HAVE_KCSAN_RUSTC
+ def_bool RUST && X86_64
+ help
+ rustc only accepts -Zsanitizer=thread for targets that declare
+ support for it; of the kernel's Rust targets, only x86_64 does.
+ Elsewhere, Rust code is not instrumented.
+
menuconfig KCSAN
bool "KCSAN: dynamic data race detector"
depends on HAVE_ARCH_KCSAN && HAVE_KCSAN_COMPILER
diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan
index 19f693b68a96..01af6fd71006 100644
--- a/scripts/Makefile.kcsan
+++ b/scripts/Makefile.kcsan
@@ -24,3 +24,16 @@ kcsan-cflags += $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit
endif
export CFLAGS_KCSAN := $(kcsan-cflags)
+
+ifdef CONFIG_HAVE_KCSAN_RUSTC
+# The minimum supported rustc's LLVM supports all of these options.
+rustc-param = -Cllvm-args=-$(1)
+kcsan-rustflags := -Zsanitizer=thread \
+ $(call rustc-param,tsan-compound-read-before-write=1) \
+ $(call rustc-param,tsan-distinguish-volatile=1)
+ifndef CONFIG_KCSAN_WEAK_MEMORY
+kcsan-rustflags += $(call rustc-param,tsan-instrument-func-entry-exit=0)
+endif
+endif
+
+export RUSTFLAGS_KCSAN := $(kcsan-rustflags)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a4fdd8bd975..78f1c23e54be 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -98,6 +98,9 @@ ifeq ($(CONFIG_KCSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \
$(CFLAGS_KCSAN))
+_rust_flags += $(if $(patsubst n%,, \
+ $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \
+ $(RUSTFLAGS_KCSAN))
# Some uninstrumented files provide implied barriers required to avoid false
# positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only.
_c_flags += $(if $(patsubst n%,, \
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 7687b0dd5474..4b02bffa6b46 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -231,7 +231,7 @@ fn main() {
}
ts.push("features", features);
ts.push("llvm-target", "x86_64-linux-gnu");
- ts.push("supported-sanitizers", ["kcfi", "kernel-address"]);
+ ts.push("supported-sanitizers", ["kcfi", "kernel-address", "thread"]);
if cfg.rustc_version_atleast(1, 91, 0) {
ts.push("target-pointer-width", 64);
} else {
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] rust: kcsan: add KUnit test for data race detection
2026-10-12 13:39 [PATCH 1/2] kbuild: rust: enable KCSAN support Marco Elver
@ 2026-10-12 13:39 ` Marco Elver
2026-10-12 15:03 ` Alexander Potapenko
2026-10-12 14:17 ` [PATCH 1/2] kbuild: rust: enable KCSAN support Miguel Ojeda
2026-10-12 14:52 ` Boqun Feng
2 siblings, 1 reply; 8+ messages in thread
From: Marco Elver @ 2026-10-12 13:39 UTC (permalink / raw)
To: elver, Boqun Feng, Miguel Ojeda, Gary Guo
Cc: Alexander Potapenko, kasan-dev, linux-kernel, Jonathan Corbet,
Shuah Khan, Randy Dunlap, Andrew Morton, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Nathan Chancellor,
Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt,
Asahi Lina, Yury Norov, Eliot Courtney, Joel Fernandes,
workflows, linux-doc, rust-for-linux, linux-kbuild, llvm
Add a minimal KUnit test that checks that KCSAN detects data races in
Rust code: two threads concurrently increment a shared counter without
synchronization, and a probe on the console tracepoint waits for the
KCSAN report (similar to kcsan_test.c):
| BUG: KCSAN: data-race in _RNvNtNtCskctMpSfuwL9_6kernel10kcsan_test5tests8racy_inc / _RNvNtNtCskctMpSfuwL9_6kernel10kcsan_test5tests8racy_inc
|
| read-write to 0xffffffffb751ae28 of 8 bytes by task 116 on cpu 5:
| _RNvNtNtCskctMpSfuwL9_6kernel10kcsan_test5tests8racy_inc+0x1c/0x30
| _RNvNtNtCskctMpSfuwL9_6kernel10kcsan_test5tests28kunit_rust_wrapper_data_race+0x28c/0x850
| kunit_try_run_case+0xdf/0x2a0
| kunit_generic_run_threadfn_adapter+0x48/0x80
| kthread+0x234/0x280
| ret_from_fork+0xf8/0x280
| ret_from_fork_asm+0x1a/0x30
|
| read-write to 0xffffffffb751ae28 of 8 bytes by task 12 on cpu 3:
| _RNvNtNtCskctMpSfuwL9_6kernel10kcsan_test5tests8racy_inc+0x1c/0x30
| _RNvXsb_NtCskctMpSfuwL9_6kernel9workqueueINtNtCs1G77UTwpz6o_4core3pin3PinINtNtNtB7_5alloc4kbox3BoxINtB5_11ClosureWorkNCNvNtNtB7_10kcsan_test5tests9data_races_0ENtNtB1d_9allocator7KmallocEEINtB5_15WorkItemPointerKy0_E3runB7_+0x55/0x120
| process_scheduled_works+0x4cd/0x970
| worker_thread+0x4de/0x6e0
| kthread+0x234/0x280
| ret_from_fork+0xf8/0x280
| ret_from_fork_asm+0x1a/0x30
|
| value changed: 0x000000000000022b -> 0x00000000000005a2
| [...]
The test is intentionally kept minimal; comprehensive tests of KCSAN's
runtime behaviour are in kernel/kcsan/kcsan_test.c.
Assisted-by: Antigravity
Signed-off-by: Marco Elver <elver@google.com>
---
MAINTAINERS | 1 +
rust/bindings/bindings_helper.h | 1 +
rust/kernel/Kconfig.test | 11 +++
rust/kernel/kcsan_test.rs | 120 ++++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 2 +
5 files changed, 135 insertions(+)
create mode 100644 rust/kernel/kcsan_test.rs
diff --git a/MAINTAINERS b/MAINTAINERS
index cc3cae2e378b..3fbbfbb31f5d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14089,6 +14089,7 @@ F: Documentation/dev-tools/kcsan.rst
F: include/linux/kcsan*.h
F: kernel/kcsan/
F: lib/Kconfig.kcsan
+F: rust/kernel/kcsan_test.rs
F: scripts/Makefile.kcsan
KDUMP
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 4b31aa7f432f..b06d5142d6e1 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -97,6 +97,7 @@
#include <linux/xarray.h>
#include <net/genetlink.h>
#include <net/netlink.h>
+#include <trace/events/printk.h>
#include <trace/events/rust_sample.h>
/*
diff --git a/rust/kernel/Kconfig.test b/rust/kernel/Kconfig.test
index e6a5c7a795f0..caf98a23de76 100644
--- a/rust/kernel/Kconfig.test
+++ b/rust/kernel/Kconfig.test
@@ -83,4 +83,15 @@ config RUST_BITFIELD_KUNIT_TEST
If unsure, say N.
+config RUST_KCSAN_KUNIT_TEST
+ bool "KUnit test for KCSAN instrumentation of Rust code" if !KUNIT_ALL_TESTS
+ depends on KCSAN && HAVE_KCSAN_RUSTC && TRACEPOINTS
+ default KUNIT_ALL_TESTS
+ help
+ This option enables a KUnit test checking that KCSAN detects data
+ races in Rust code. The test needs at least 2 CPUs to reliably
+ observe a data race.
+
+ If unsure, say N.
+
endif
diff --git a/rust/kernel/kcsan_test.rs b/rust/kernel/kcsan_test.rs
new file mode 100644
index 000000000000..5ddc9090cd6e
--- /dev/null
+++ b/rust/kernel/kcsan_test.rs
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! KUnit test checking that KCSAN detects data races in Rust code.
+
+#[macros::kunit_tests(rust_kcsan)]
+mod tests {
+ use crate::{
+ bindings,
+ error::to_result,
+ ffi::{c_char, c_void},
+ prelude::*,
+ sync::{
+ atomic::{Atomic, Relaxed},
+ Arc, Completion,
+ },
+ time::{Delta, Instant, Monotonic},
+ types::ScopeGuard,
+ workqueue,
+ };
+ use core::{cell::UnsafeCell, ptr, slice};
+
+ struct Racy(UnsafeCell<u64>);
+
+ // SAFETY: Not actually safe: unsynchronized concurrent access is the point of this test.
+ unsafe impl Sync for Racy {}
+
+ static RACY: Racy = Racy(UnsafeCell::new(0));
+
+ /// Set by [`probe_console`] once KCSAN reported a data race in [`racy_inc`].
+ static OBSERVED: Atomic<bool> = Atomic::new(false);
+
+ #[inline(never)]
+ fn racy_inc() {
+ let p = RACY.0.get();
+ // SAFETY: `p` is valid; the data race is intentional. `wrapping_add()` keeps the load and
+ // store in one basic block, so that the access is instrumented as a compound access (plain
+ // writes may be assumed atomic with `CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=y`).
+ unsafe { *p = (*p).wrapping_add(1); }
+ }
+
+ fn contains(haystack: &[u8], needle: &[u8]) -> bool {
+ haystack.windows(needle.len()).any(|w| w == needle)
+ }
+
+ /// Probe for the `console` tracepoint.
+ ///
+ /// # Safety
+ ///
+ /// `buf` must be non-null and valid for reads of `len` bytes.
+ unsafe extern "C" fn probe_console(_data: *mut c_void, buf: *const c_char, len: usize) {
+ // SAFETY: By the safety requirements of this function.
+ let line = unsafe { slice::from_raw_parts(buf.cast::<u8>(), len) };
+
+ if contains(line, b"BUG: KCSAN: data-race in ") && contains(line, b"racy_inc") {
+ OBSERVED.store(true, Relaxed);
+ }
+ }
+
+ #[pin_data]
+ struct Ctx {
+ stop: Atomic<bool>,
+ #[pin]
+ done: Completion,
+ }
+
+ #[test]
+ fn data_race() -> Result {
+ // Do not pass on a report from a previous run of this suite.
+ OBSERVED.store(false, Relaxed);
+
+ let ctx = Arc::pin_init(
+ pin_init!(Ctx {
+ stop: Atomic::new(false),
+ done <- Completion::new(),
+ }),
+ GFP_KERNEL,
+ )?;
+
+ // SAFETY: `probe_console` has the signature expected by the `console` tracepoint. Being
+ // part of the kernel image, it and `OBSERVED` outlive the registration, so there is no
+ // need to synchronize with in-flight probes after unregistering.
+ to_result(unsafe {
+ bindings::tracepoint_probe_register(
+ &raw mut bindings::__tracepoint_console,
+ probe_console as *mut c_void,
+ ptr::null_mut(),
+ )
+ })?;
+ let _unregister = ScopeGuard::new(|| {
+ // SAFETY: The probe was registered above.
+ unsafe {
+ bindings::tracepoint_probe_unregister(
+ &raw mut bindings::__tracepoint_console,
+ probe_console as *mut c_void,
+ ptr::null_mut(),
+ );
+ }
+ });
+
+ let worker = ctx.clone();
+ workqueue::system_unbound().try_spawn(GFP_KERNEL, move || {
+ while !worker.stop.load(Relaxed) {
+ racy_inc();
+ }
+ worker.done.complete_all();
+ })?;
+
+ let start = Instant::<Monotonic>::now();
+ while !OBSERVED.load(Relaxed) && start.elapsed() < Delta::from_secs(10) {
+ racy_inc();
+ }
+
+ ctx.stop.store(true, Relaxed);
+ ctx.done.wait_for_completion();
+ drop(_unregister);
+
+ assert!(OBSERVED.load(Relaxed));
+ Ok(())
+ }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 4d5c96ddc49c..009efda9e7a4 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -94,6 +94,8 @@
pub mod iov;
pub mod irq;
pub mod jump_label;
+#[cfg(CONFIG_RUST_KCSAN_KUNIT_TEST)]
+mod kcsan_test;
#[cfg(CONFIG_KUNIT)]
pub mod kunit;
pub mod list;
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] kbuild: rust: enable KCSAN support
2026-10-12 13:39 [PATCH 1/2] kbuild: rust: enable KCSAN support Marco Elver
2026-10-12 13:39 ` [PATCH 2/2] rust: kcsan: add KUnit test for data race detection Marco Elver
@ 2026-10-12 14:17 ` Miguel Ojeda
2026-10-12 14:37 ` Marco Elver
2026-10-12 14:52 ` Boqun Feng
2 siblings, 1 reply; 8+ messages in thread
From: Miguel Ojeda @ 2026-10-12 14:17 UTC (permalink / raw)
To: Marco Elver
Cc: Boqun Feng, Miguel Ojeda, Gary Guo, Alexander Potapenko,
kasan-dev, linux-kernel, Jonathan Corbet, Shuah Khan,
Randy Dunlap, Andrew Morton, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Nathan Chancellor,
Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt,
Asahi Lina, Yury Norov, Eliot Courtney, Joel Fernandes,
workflows, linux-doc, rust-for-linux, linux-kbuild, llvm
On Mon, Oct 12, 2026 at 3:42 PM Marco Elver <elver@google.com> wrote:
>
> +Rust code is instrumented as well on architectures whose Rust target supports
> +it (currently only x86_64; see ``CONFIG_HAVE_KCSAN_RUSTC``).
Maybe we can omit the x86_64 bit, to avoid maintaining the list in two
places, although it is convenient to know in the docs (but risks
getting out of date, of course).
> + Note that ``rustc`` rejects linking crates built with and without KCSAN
> + instrumentation, so ``KCSAN_SANITIZE`` and ``KCSAN_SANITIZE_<target>.o``
> + cannot currently be used for Rust code.
Would `-Cunsafe-allow-abi-mismatch=sanitizer` work? Not a blocker for
the patch (and in fact I don't know if we would like to actually
support it even if it works), but perhaps in the future we can relax
it using that.
(If it doesn't work for some reason, and we want it, then we can ask
upstream for an "escape hatch" as we usually do, since things like
this should normally have one...)
> +# The minimum supported rustc's LLVM supports all of these options.
Just to double-check: does this refer to the LLVM version of the
upstream `rustc` binary (LLVM 19.1.7) or the actual minimum they
support in that minimum `rustc` version (LLVM 18 major)?
I think all the options exist for a long time, so it doesn't matter,
but just to confirm...
In any case, this sounds all reasonable:
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] kbuild: rust: enable KCSAN support
2026-10-12 14:17 ` [PATCH 1/2] kbuild: rust: enable KCSAN support Miguel Ojeda
@ 2026-10-12 14:37 ` Marco Elver
0 siblings, 0 replies; 8+ messages in thread
From: Marco Elver @ 2026-10-12 14:37 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Boqun Feng, Miguel Ojeda, Gary Guo, Alexander Potapenko,
kasan-dev, linux-kernel, Jonathan Corbet, Shuah Khan,
Randy Dunlap, Andrew Morton, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Nathan Chancellor,
Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt,
Asahi Lina, Yury Norov, Eliot Courtney, Joel Fernandes,
workflows, linux-doc, rust-for-linux, linux-kbuild, llvm
On Mon, 12 Oct 2026 at 16:18, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Mon, Oct 12, 2026 at 3:42 PM Marco Elver <elver@google.com> wrote:
> >
> > +Rust code is instrumented as well on architectures whose Rust target supports
> > +it (currently only x86_64; see ``CONFIG_HAVE_KCSAN_RUSTC``).
>
> Maybe we can omit the x86_64 bit, to avoid maintaining the list in two
> places, although it is convenient to know in the docs (but risks
> getting out of date, of course).
I think any future patch that enables more architectures, can also
update the docs. We have historically maintained the set of supported
compilers + architectures (if that set was still small) in the
sanitizer docs. Once that set grows large enough, we can omit.
> > + Note that ``rustc`` rejects linking crates built with and without KCSAN
> > + instrumentation, so ``KCSAN_SANITIZE`` and ``KCSAN_SANITIZE_<target>.o``
> > + cannot currently be used for Rust code.
>
> Would `-Cunsafe-allow-abi-mismatch=sanitizer` work? Not a blocker for
> the patch (and in fact I don't know if we would like to actually
> support it even if it works), but perhaps in the future we can relax
> it using that.
If rustc's sanitizer instrumentation is similar to clang's, and rustc
doesn't introduce other ABI divergence due to sanitizers, then it
should work. Same with KASAN + Rust, so this would need to be a
general Rust + sanitizers decision.
The only exception is KMSAN (which I think is not yet enabled for
Rust), which does affect ABI.
> (If it doesn't work for some reason, and we want it, then we can ask
> upstream for an "escape hatch" as we usually do, since things like
> this should normally have one...)
>
> > +# The minimum supported rustc's LLVM supports all of these options.
>
> Just to double-check: does this refer to the LLVM version of the
> upstream `rustc` binary (LLVM 19.1.7) or the actual minimum they
> support in that minimum `rustc` version (LLVM 18 major)?
>
> I think all the options exist for a long time, so it doesn't matter,
> but just to confirm...
Whichever minimum we could ever see the kernel compiled with, which
looks like LLVM 18 in some custom setups? But yeah, all we need is at
least LLVM 12...
> In any case, this sounds all reasonable:
>
> Acked-by: Miguel Ojeda <ojeda@kernel.org>
Thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] kbuild: rust: enable KCSAN support
2026-10-12 13:39 [PATCH 1/2] kbuild: rust: enable KCSAN support Marco Elver
2026-10-12 13:39 ` [PATCH 2/2] rust: kcsan: add KUnit test for data race detection Marco Elver
2026-10-12 14:17 ` [PATCH 1/2] kbuild: rust: enable KCSAN support Miguel Ojeda
@ 2026-10-12 14:52 ` Boqun Feng
2 siblings, 0 replies; 8+ messages in thread
From: Boqun Feng @ 2026-10-12 14:52 UTC (permalink / raw)
To: Marco Elver
Cc: Boqun Feng, Miguel Ojeda, Gary Guo, Alexander Potapenko,
kasan-dev, linux-kernel, Jonathan Corbet, Shuah Khan,
Randy Dunlap, Andrew Morton, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Nathan Chancellor, Nicolas Schier,
Nick Desaulniers, Bill Wendling, Justin Stitt, Asahi Lina,
Yury Norov, Eliot Courtney, Joel Fernandes, workflows, linux-doc,
rust-for-linux, linux-kbuild, llvm
On Mon, Oct 12, 2026 at 01:39:14PM +0000, Marco Elver wrote:
> Rust supports ThreadSanitizer instrumentation via LLVM, which is what
> KCSAN relies on; however, Rust code is not currently instrumented.
>
> Pass -Zsanitizer=thread and the same TSan backend options used for C
> code to rustc. Wire up KCSAN_SANITIZE in scripts/Makefile.lib for parity
> with C (though rustc currently rejects linking crates with mismatched
> instrumentation).
>
> rustc only accepts -Zsanitizer=thread for targets that declare support
> for it. Of the targets used by the kernel, this is only possible for the
> generated x86_64 target specification, so restrict instrumentation of
> Rust code to x86_64 for now via HAVE_KCSAN_RUSTC. On other architectures
> Rust code remains uninstrumented as before.
>
> All TSan options used are supported by the LLVM versions of the minimum
> supported rustc, so no rustc-option checks are needed (they would also
> fail, because x86_64-unknown-none used for option checks does not
> support -Zsanitizer=thread).
>
> With this enabled we can detect data races in kernel Rust code and
> between Rust and C code.
>
Help has finally arrived! :)
Thank you for looking into this, for both patches:
Acked-by: Boqun Feng <boqun@kernel.org>
Regards,
Boqun
> Signed-off-by: Marco Elver <elver@google.com>
> ---
> Documentation/dev-tools/kcsan.rst | 7 +++++++
> lib/Kconfig.kcsan | 7 +++++++
> scripts/Makefile.kcsan | 13 +++++++++++++
> scripts/Makefile.lib | 3 +++
> scripts/generate_rust_target.rs | 2 +-
> 5 files changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/dev-tools/kcsan.rst b/Documentation/dev-tools/kcsan.rst
> index 8575178aa87f..3bb8754f844b 100644
> --- a/Documentation/dev-tools/kcsan.rst
> +++ b/Documentation/dev-tools/kcsan.rst
> @@ -14,6 +14,9 @@ Usage
> KCSAN is supported by both GCC and Clang. With GCC we require version 11 or
> later, and with Clang also require version 11 or later.
>
> +Rust code is instrumented as well on architectures whose Rust target supports
> +it (currently only x86_64; see ``CONFIG_HAVE_KCSAN_RUSTC``).
> +
> To enable KCSAN configure the kernel with::
>
> CONFIG_KCSAN = y
> @@ -121,6 +124,10 @@ the below options are available:
>
> KCSAN_SANITIZE := n
>
> + Note that ``rustc`` rejects linking crates built with and without KCSAN
> + instrumentation, so ``KCSAN_SANITIZE`` and ``KCSAN_SANITIZE_<target>.o``
> + cannot currently be used for Rust code.
> +
> .. _"Marking Shared-Memory Accesses" in the LKMM: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/memory-model/Documentation/access-marking.txt
>
> Furthermore, it is possible to tell KCSAN to show or hide entire classes of
> diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan
> index 4ce4b0c0109c..f0096e1c8b61 100644
> --- a/lib/Kconfig.kcsan
> +++ b/lib/Kconfig.kcsan
> @@ -10,6 +10,13 @@ config HAVE_KCSAN_COMPILER
> For the list of compilers that support KCSAN, please see
> <file:Documentation/dev-tools/kcsan.rst>.
>
> +config HAVE_KCSAN_RUSTC
> + def_bool RUST && X86_64
> + help
> + rustc only accepts -Zsanitizer=thread for targets that declare
> + support for it; of the kernel's Rust targets, only x86_64 does.
> + Elsewhere, Rust code is not instrumented.
> +
> menuconfig KCSAN
> bool "KCSAN: dynamic data race detector"
> depends on HAVE_ARCH_KCSAN && HAVE_KCSAN_COMPILER
> diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan
> index 19f693b68a96..01af6fd71006 100644
> --- a/scripts/Makefile.kcsan
> +++ b/scripts/Makefile.kcsan
> @@ -24,3 +24,16 @@ kcsan-cflags += $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit
> endif
>
> export CFLAGS_KCSAN := $(kcsan-cflags)
> +
> +ifdef CONFIG_HAVE_KCSAN_RUSTC
> +# The minimum supported rustc's LLVM supports all of these options.
> +rustc-param = -Cllvm-args=-$(1)
> +kcsan-rustflags := -Zsanitizer=thread \
> + $(call rustc-param,tsan-compound-read-before-write=1) \
> + $(call rustc-param,tsan-distinguish-volatile=1)
> +ifndef CONFIG_KCSAN_WEAK_MEMORY
> +kcsan-rustflags += $(call rustc-param,tsan-instrument-func-entry-exit=0)
> +endif
> +endif
> +
> +export RUSTFLAGS_KCSAN := $(kcsan-rustflags)
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index 0a4fdd8bd975..78f1c23e54be 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -98,6 +98,9 @@ ifeq ($(CONFIG_KCSAN),y)
> _c_flags += $(if $(patsubst n%,, \
> $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \
> $(CFLAGS_KCSAN))
> +_rust_flags += $(if $(patsubst n%,, \
> + $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \
> + $(RUSTFLAGS_KCSAN))
> # Some uninstrumented files provide implied barriers required to avoid false
> # positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only.
> _c_flags += $(if $(patsubst n%,, \
> diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
> index 7687b0dd5474..4b02bffa6b46 100644
> --- a/scripts/generate_rust_target.rs
> +++ b/scripts/generate_rust_target.rs
> @@ -231,7 +231,7 @@ fn main() {
> }
> ts.push("features", features);
> ts.push("llvm-target", "x86_64-linux-gnu");
> - ts.push("supported-sanitizers", ["kcfi", "kernel-address"]);
> + ts.push("supported-sanitizers", ["kcfi", "kernel-address", "thread"]);
> if cfg.rustc_version_atleast(1, 91, 0) {
> ts.push("target-pointer-width", 64);
> } else {
> --
> 2.56.0.385.gd3acb90ef8-goog
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] rust: kcsan: add KUnit test for data race detection
2026-10-12 13:39 ` [PATCH 2/2] rust: kcsan: add KUnit test for data race detection Marco Elver
@ 2026-10-12 15:03 ` Alexander Potapenko
2026-10-12 15:15 ` Marco Elver
0 siblings, 1 reply; 8+ messages in thread
From: Alexander Potapenko @ 2026-10-12 15:03 UTC (permalink / raw)
To: Marco Elver
Cc: Boqun Feng, Miguel Ojeda, Gary Guo, kasan-dev, linux-kernel,
Jonathan Corbet, Shuah Khan, Randy Dunlap, Andrew Morton,
Boqun Feng, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan,
Nathan Chancellor, Nicolas Schier, Nick Desaulniers,
Bill Wendling, Justin Stitt, Asahi Lina, Yury Norov,
Eliot Courtney, Joel Fernandes, workflows, linux-doc,
rust-for-linux, linux-kbuild, llvm
> rust/bindings/bindings_helper.h | 1 +
> rust/kernel/Kconfig.test | 11 +++
> rust/kernel/kcsan_test.rs | 120 ++++++++++++++++++++++++++++++++
> rust/kernel/lib.rs | 2 +
> 5 files changed, 135 insertions(+)
> create mode 100644 rust/kernel/kcsan_test.rs
FWIW `make rustfmtcheck` fails for me on kcsan_test.rs
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] rust: kcsan: add KUnit test for data race detection
2026-10-12 15:03 ` Alexander Potapenko
@ 2026-10-12 15:15 ` Marco Elver
2026-10-12 15:21 ` Miguel Ojeda
0 siblings, 1 reply; 8+ messages in thread
From: Marco Elver @ 2026-10-12 15:15 UTC (permalink / raw)
To: Alexander Potapenko
Cc: Boqun Feng, Miguel Ojeda, Gary Guo, kasan-dev, linux-kernel,
Jonathan Corbet, Shuah Khan, Randy Dunlap, Andrew Morton,
Boqun Feng, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan,
Nathan Chancellor, Nicolas Schier, Nick Desaulniers,
Bill Wendling, Justin Stitt, Asahi Lina, Yury Norov,
Eliot Courtney, Joel Fernandes, workflows, linux-doc,
rust-for-linux, linux-kbuild, llvm
On Mon, 12 Oct 2026 at 17:04, Alexander Potapenko <glider@google.com> wrote:
>
> > rust/bindings/bindings_helper.h | 1 +
> > rust/kernel/Kconfig.test | 11 +++
> > rust/kernel/kcsan_test.rs | 120 ++++++++++++++++++++++++++++++++
> > rust/kernel/lib.rs | 2 +
> > 5 files changed, 135 insertions(+)
> > create mode 100644 rust/kernel/kcsan_test.rs
>
> FWIW `make rustfmtcheck` fails for me on kcsan_test.rs
Oops. I guess we'll make a v2.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] rust: kcsan: add KUnit test for data race detection
2026-10-12 15:15 ` Marco Elver
@ 2026-10-12 15:21 ` Miguel Ojeda
0 siblings, 0 replies; 8+ messages in thread
From: Miguel Ojeda @ 2026-10-12 15:21 UTC (permalink / raw)
To: Marco Elver
Cc: Alexander Potapenko, Boqun Feng, Miguel Ojeda, Gary Guo,
kasan-dev, linux-kernel, Jonathan Corbet, Shuah Khan,
Randy Dunlap, Andrew Morton, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Nathan Chancellor,
Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt,
Asahi Lina, Yury Norov, Eliot Courtney, Joel Fernandes,
workflows, linux-doc, rust-for-linux, linux-kbuild, llvm
On Mon, Oct 12, 2026 at 5:16 PM Marco Elver <elver@google.com> wrote:
>
> Oops. I guess we'll make a v2.
Please also take the chance to use the kernel vertical imports style:
https://docs.kernel.org/rust/coding-guidelines.html#imports
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-12 15:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 13:39 [PATCH 1/2] kbuild: rust: enable KCSAN support Marco Elver
2026-10-12 13:39 ` [PATCH 2/2] rust: kcsan: add KUnit test for data race detection Marco Elver
2026-10-12 15:03 ` Alexander Potapenko
2026-10-12 15:15 ` Marco Elver
2026-10-12 15:21 ` Miguel Ojeda
2026-10-12 14:17 ` [PATCH 1/2] kbuild: rust: enable KCSAN support Miguel Ojeda
2026-10-12 14:37 ` Marco Elver
2026-10-12 14:52 ` Boqun Feng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®