From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 184B23B19AA for ; Thu, 15 Oct 2026 14:57:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.70 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792076254; cv=none; b=CctTk9WcCQpCb2+x+CZha4vxZ2Z92CC/KV/3p6yQAZkJWuSR5zwCBiXEU4UhkYhhbUHDnnUc+Mt95NEmrANdCjKwGjcV23GmYue2j2zFc6cWMkLyJ4Gcx6c8doSmw/32kzWKlp+CiObBexk0dpts09gE8BJQ2ju92c8vxYuI01w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792076254; c=relaxed/simple; bh=nbtf2aJFUaL/4iH/qLfpXzTeoJ6Tlhbj6DaOj27+188=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=c4ITdmmgtIpPzTN34DGmqqriGO0n7s2SSrfnd6f/g2QHFKxIcuHBJ6y86Jz/sZl0Z+/aEpPcPgU/zO8EH5iCu12LWinyvjBM4nKjZn5mDn+2G1PYnQn77mPYV+R91ZmcxE3lgjGK8i5yuq3OmZnytHk6zEcnlco+8YT0yxr3rt4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--elver.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=EZasvRAj; arc=none smtp.client-ip=209.85.128.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--elver.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EZasvRAj" Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4a01b112fa2so32249815e9.1 for ; Thu, 15 Oct 2026 07:57:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1792076250; x=1792681050; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:mime-version:date:from :to:cc:subject:date:message-id:reply-to:content-type; bh=gOPLD1Nk0xD9uDIf10OzE40FWH2sqAvdDlcLSS3lQok=; b=EZasvRAjos5Z9twr/kI65YM9wdYqGfB5UoPJL2pol/ju2uoTKdBPr1nyQUP/ZLLMIH MBnG3IlODF05yBX1GwZnYJyGhJrnycv6DNblJkwzq6+/QaCwQph7gA1Z1xwFj6WXVcef W+raxletovlSkMJaiylCjoiSQKMYcaZ5XmQT/jk294q+1UgkPGArMzrVkyjoJec0N+tc /HaDgv+NV1EuwfpLLJtOorWdwscXBr4aPN1447opaOPfFN6R51vLspa4th4Xc24J3BqZ 1Mjs8Rt01sA+voKP7UkAyrGoDlmYdL5WZqdP9FsFWko60LE0zw/gH0WHPloWplgHccUx UI9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792076250; x=1792681050; h=content-type:cc:to:from:subject:message-id:mime-version:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=gOPLD1Nk0xD9uDIf10OzE40FWH2sqAvdDlcLSS3lQok=; b=z3ZvHqN4HRVRq5WdlWvwDdp0gPJfURs3QOeJq99M1tySGiiKgR+S6ljLzuznrSDgsP ROEwT2fkBqlIpyo+eyzSd2najfB4fLdkQsM+KeVKRjUZDg24Z//bnBM7qCEuxveA6smN dhjM51SBS4OBZwAzfND5WNLNd49nXdBO5aFU9f485jz6HMUPCSeYCvp+n5UM+cuDBDin 3fBkz54PjvjBHQz7Ygu1jcdoqxkcQclsAibq11FrmqpNKqhu3PJKOpgDfVg3I3N5c0Qo VSjAgSg5cKMoGVr+tMAMF7277gBU+R8eRKNs5b8MKRYdZ9gX3jzPs3FnX7ednTjFgzux Cbpw== X-Forwarded-Encrypted: i=1; AKwUvBz9Otds91QUm7SyTfDQQyE7uvFg5pAKbOY2fGxCbQZ3z0ZsvJP73V2KW8z5toE9TGubM+5KOgc4sX0=@vger.kernel.org X-Gm-Message-State: AFq9FYKuGaYrxo4d4l7jfAemk0jsyuT8jsM5NXe3cKUsp4EhqoVfQ9K/ jgK3t7skgDBiwI7A3+8FCEsDaSIdPvutPHup0r9A4hgAb6wtCpW6kTeaVjdHa7B1GURPPCMAC0j 1TA== X-Received: from wmbgx18.prod.google.com ([2002:a05:600c:8592:b0:4a1:7fbd:344d]) (user=elver job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3f16:b0:4a0:2150:55fb with SMTP id 5b1f17b1804b1-4a18e44395bmr382529505e9.4.1792076250083; Thu, 15 Oct 2026 07:57:30 -0700 (PDT) Date: Thu, 15 Oct 2026 14:56:14 +0000 Precedence: bulk X-Mailing-List: workflows@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.56.0.385.gd3acb90ef8-goog Message-ID: <20261015145714.3327543-1-elver@google.com> Subject: [PATCH v2 1/2] kbuild: rust: enable KCSAN support From: Marco Elver To: elver@google.com Cc: Alexander Potapenko , Boqun Feng , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, Dmitry Vyukov , Jonathan Corbet , Shuah Khan , Randy Dunlap , Andrew Morton , Miguel Ojeda , Boqun Feng , Gary Guo , "=?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?=" , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , "=?UTF-8?q?Onur=20=C3=96zkan?=" , Nathan Chancellor , Nicolas Schier , Nick Desaulniers , Bill Wendling , Justin Stitt , Asahi Lina , Lorenzo Stoakes , Yury Norov , David Gow , Joel Fernandes , Alvin Sun , Josh Poimboeuf , Petr Mladek , workflows@vger.kernel.org, linux-doc@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kbuild@vger.kernel.org, llvm@lists.linux.dev Content-Type: text/plain; charset="UTF-8" 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). Unlike Clang and GCC, an equivalent to -fno-optimize-sibling-calls is omitted for Rust because rustc provides no corresponding option. While disabling tail-call optimizations helps preserve complete stacks traces in reports, it is optional and not required for KCSAN to function. With this enabled we can detect data races in kernel Rust code and between Rust and C code. Acked-by: Miguel Ojeda Acked-by: Boqun Feng Signed-off-by: Marco Elver --- v2: * Add note on -fno-optimize-sibling-calls to commit message. --- 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_.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 . +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