From nobody Sun Nov 24 11:38:30 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F5971D9A56 for ; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816347; cv=none; b=CjgGHFo+Knjk1C3iIMWJXBUd8NE1rCtAHB6VeOw7f6xIQQAEcnw5KPcBMUIF/QNzhtgj/CQzA/hELT39fTR1cciYX1NNmyuij6tEv2wrPotqJWmL6Vjkw9B1RlubkYzpu7cOXsdPPuK2AALO2BYRPADyB2q9yKJiwgkoSfuuWck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816347; c=relaxed/simple; bh=5LtmxxV+wE/QnxntSa4QcyvSJphuOBGVxPPJRnEE3Q0=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=DJd8vxs5lENgw2r6Rl2TAPFZgJtuClIGfLyKQOgNHQYh1EVoFaBgmV8RAx5oWi7REtzv8tMiORyc+jU8i9yw0djwbrBjVNymRWpJRkV7gQBRavk/2TBSONTcaU7hZ31DPLNX0ZSzTva0S15XJBtkHbaj9wlXP7VW+npz3gLSSuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B165C4CED6; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1t8KOi-00000000WiV-3eZk; Tue, 05 Nov 2024 09:19:08 -0500 Message-ID: <20241105141908.720348374@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 05 Nov 2024 09:18:47 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Ard Biesheuvel , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Sean Christopherson , Uros Bizjak , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Ryan Roberts , Fuad Tabba , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Andrew Jones , Alexandre Ghiti , Conor Dooley , Samuel Holland , Huacai Chen , WANG Xuerui , Bibo Mao , Tiezhu Yang , Tianrui Zhao , Boqun Feng , Gary Guo , Alice Ryhl Subject: [for-next][PATCH 1/5] rust: add static_branch_unlikely for static_key_false References: <20241105141846.641050484@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alice Ryhl Add just enough support for static key so that we can use it from tracepoints. Tracepoints rely on `static_branch_unlikely` with a `struct static_key_false`, so we add the same functionality to Rust. This patch only provides a generic implementation without code patching (matching the one used when CONFIG_JUMP_LABEL is disabled). Later patches add support for inline asm implementations that use runtime patching. When CONFIG_JUMP_LABEL is unset, `static_key_count` is a static inline function, so a Rust helper is defined for `static_key_count` in this case. If Rust is compiled with LTO, this call should get inlined. The helper can be eliminated once we have the necessary inline asm to make atomic operations from Rust. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Josh Poimboeuf Cc: Jason Baron Cc: Ard Biesheuvel Cc: Miguel Ojeda Cc: Alex Gaynor Cc: Wedson Almeida Filho Cc: " =3D?utf-8?q?Bj=3DC3=3DB6rn_Roy_Baron?=3D " Cc: Benno Lossin Cc: Andreas Hindborg Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Sean Christopherson Cc: Uros Bizjak Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: Mark Rutland Cc: Ryan Roberts Cc: Fuad Tabba Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Anup Patel Cc: Andrew Jones Cc: Alexandre Ghiti Cc: Conor Dooley Cc: Samuel Holland Cc: Huacai Chen Cc: WANG Xuerui Cc: Bibo Mao Cc: Tiezhu Yang Cc: Andrew Morton Cc: Tianrui Zhao Link: https://lore.kernel.org/20241030-tracepoint-v12-1-eec7f0f8ad22@google= .com Reviewed-by: Boqun Feng Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl Signed-off-by: Steven Rostedt (Google) --- rust/bindings/bindings_helper.h | 1 + rust/helpers/helpers.c | 1 + rust/helpers/jump_label.c | 14 ++++++++++++++ rust/kernel/jump_label.rs | 30 ++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 1 + 5 files changed, 47 insertions(+) create mode 100644 rust/helpers/jump_label.c create mode 100644 rust/kernel/jump_label.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index ae82e9c941af..e0846e7e93e6 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 30f40149f3a9..17e1b60d178f 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -12,6 +12,7 @@ #include "build_assert.c" #include "build_bug.c" #include "err.c" +#include "jump_label.c" #include "kunit.c" #include "mutex.c" #include "page.c" diff --git a/rust/helpers/jump_label.c b/rust/helpers/jump_label.c new file mode 100644 index 000000000000..fc1f1e0df08e --- /dev/null +++ b/rust/helpers/jump_label.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright (C) 2024 Google LLC. + */ + +#include + +#ifndef CONFIG_JUMP_LABEL +int rust_helper_static_key_count(struct static_key *key) +{ + return static_key_count(key); +} +#endif diff --git a/rust/kernel/jump_label.rs b/rust/kernel/jump_label.rs new file mode 100644 index 000000000000..4b7655b2a022 --- /dev/null +++ b/rust/kernel/jump_label.rs @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Logic for static keys. +//! +//! C header: [`include/linux/jump_label.h`](srctree/include/linux/jump_la= bel.h). + +/// Branch based on a static key. +/// +/// Takes three arguments: +/// +/// * `key` - the path to the static variable containing the `static_key`. +/// * `keytyp` - the type of `key`. +/// * `field` - the name of the field of `key` that contains the `static_k= ey`. +/// +/// # Safety +/// +/// The macro must be used with a real static key defined by C. +#[macro_export] +macro_rules! static_branch_unlikely { + ($key:path, $keytyp:ty, $field:ident) =3D> {{ + let _key: *const $keytyp =3D ::core::ptr::addr_of!($key); + let _key: *const $crate::bindings::static_key_false =3D ::core::pt= r::addr_of!((*_key).$field); + let _key: *const $crate::bindings::static_key =3D _key.cast(); + + $crate::bindings::static_key_count(_key.cast_mut()) > 0 + }}; +} +pub use static_branch_unlikely; diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index b5f4b3ce6b48..708ff817ccc3 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -36,6 +36,7 @@ pub mod firmware; pub mod init; pub mod ioctl; +pub mod jump_label; #[cfg(CONFIG_KUNIT)] pub mod kunit; pub mod list; --=20 2.45.2 From nobody Sun Nov 24 11:38:30 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2891D1D9A6F for ; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; cv=none; b=JPH2dkUxbovlZTnQuwtxFvOKEKsIIJEVQGiPtdAvgBe/EAgSZKxxSW6aDd/DlmQQCtNc5z2RSXk9QukNCDtfRIilNV4AitraX1BJDZVlyMnMl0VFSvxHaw8m8kTbZo6zXG5lt4ppQcFSyUQYQyPCx6kxjSVlX/xX1a6VKthmVkw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; c=relaxed/simple; bh=gNJ62xxKfYeeEork0uX5M1URk4jHB+bBlYaHKmwT9Fk=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=shQnhXkhQ9ynG3ybeIfZr0XYHKalDF/bCDybDUaKQh128I2FIH7s5CVzPlcIPJ4y3FFVB/wEHu55fpXbSTrQ7R+LtS8Dexy/tuJyrgQsBkx37Q43jHi/5W/kixAn1q+mVhjTkUSRTjcl65R4lRLXpOHJZ9fU8RXLvP4UcJSTSe8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8A40C4CEDD; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1t8KOj-00000000Wiz-0BLV; Tue, 05 Nov 2024 09:19:09 -0500 Message-ID: <20241105141908.891241681@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 05 Nov 2024 09:18:48 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Ard Biesheuvel , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Sean Christopherson , Uros Bizjak , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Ryan Roberts , Fuad Tabba , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Andrew Jones , Alexandre Ghiti , Conor Dooley , Samuel Holland , Huacai Chen , WANG Xuerui , Bibo Mao , Tiezhu Yang , Tianrui Zhao , Carlos Llamas , Gary Guo , Boqun Feng , Alice Ryhl Subject: [for-next][PATCH 2/5] rust: add tracepoint support References: <20241105141846.641050484@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alice Ryhl Make it possible to have Rust code call into tracepoints defined by C code. It is still required that the tracepoint is declared in a C header, and that this header is included in the input to bindgen. Instead of calling __DO_TRACE directly, the exported rust_do_trace_ function calls an inline helper function. This is because the `cond` argument does not exist at the callsite of DEFINE_RUST_DO_TRACE. __DECLARE_TRACE always emits an inline static and an extern declaration that is only used when CREATE_RUST_TRACE_POINTS is set. These should not end up in the final binary so it is not a problem that they sometimes are emitted without a user. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Josh Poimboeuf Cc: Jason Baron Cc: Ard Biesheuvel Cc: Miguel Ojeda Cc: Alex Gaynor Cc: Wedson Almeida Filho Cc: " =3D?utf-8?q?Bj=3DC3=3DB6rn_Roy_Baron?=3D " Cc: Benno Lossin Cc: Andreas Hindborg Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Sean Christopherson Cc: Uros Bizjak Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: Mark Rutland Cc: Ryan Roberts Cc: Fuad Tabba Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Anup Patel Cc: Andrew Jones Cc: Alexandre Ghiti Cc: Conor Dooley Cc: Samuel Holland Cc: Huacai Chen Cc: WANG Xuerui Cc: Bibo Mao Cc: Tiezhu Yang Cc: Andrew Morton Cc: Tianrui Zhao Link: https://lore.kernel.org/20241030-tracepoint-v12-2-eec7f0f8ad22@google= .com Reviewed-by: Carlos Llamas Reviewed-by: Gary Guo Reviewed-by: Boqun Feng Signed-off-by: Alice Ryhl Signed-off-by: Steven Rostedt (Google) --- include/linux/tracepoint.h | 28 ++++++++++++++++++- include/trace/define_trace.h | 12 ++++++++ rust/bindings/bindings_helper.h | 1 + rust/kernel/lib.rs | 1 + rust/kernel/tracepoint.rs | 49 +++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/tracepoint.rs diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 0dc67fad706c..84c4924e499f 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -225,6 +225,18 @@ static inline struct tracepoint *tracepoint_ptr_deref(= tracepoint_ptr_t *p) preempt_enable_notrace(); \ } while (0) =20 +/* + * Declare an exported function that Rust code can call to trigger this + * tracepoint. This function does not include the static branch; that is d= one + * in Rust to avoid a function call when the tracepoint is disabled. + */ +#define DEFINE_RUST_DO_TRACE(name, proto, args) +#define __DEFINE_RUST_DO_TRACE(name, proto, args) \ + notrace void rust_do_trace_##name(proto) \ + { \ + __rust_do_trace_##name(args); \ + } + /* * Make sure the alignment of the structure in the __tracepoints section w= ill * not add unwanted padding between the beginning of the section and the @@ -240,6 +252,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(t= racepoint_ptr_t *p) extern int __traceiter_##name(data_proto); \ DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ extern struct tracepoint __tracepoint_##name; \ + extern void rust_do_trace_##name(proto); \ static inline int \ register_trace_##name(void (*probe)(data_proto), void *data) \ { \ @@ -271,6 +284,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(= tracepoint_ptr_t *p) =20 #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(da= ta_proto)) \ + static inline void __rust_do_trace_##name(proto) \ + { \ + __DO_TRACE(name, \ + TP_ARGS(args), \ + TP_CONDITION(cond), 0); \ + } \ static inline void trace_##name(proto) \ { \ if (static_branch_unlikely(&__tracepoint_##name.key)) \ @@ -285,6 +304,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(= tracepoint_ptr_t *p) =20 #define __DECLARE_TRACE_SYSCALL(name, proto, args, cond, data_proto) \ __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(da= ta_proto)) \ + static inline void __rust_do_trace_##name(proto) \ + { \ + __DO_TRACE(name, \ + TP_ARGS(args), \ + TP_CONDITION(cond), 1); \ + } \ static inline void trace_##name(proto) \ { \ if (static_branch_unlikely(&__tracepoint_##name.key)) \ @@ -339,7 +364,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(t= racepoint_ptr_t *p) void __probestub_##_name(void *__data, proto) \ { \ } \ - DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); + DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); \ + DEFINE_RUST_DO_TRACE(_name, TP_PROTO(proto), TP_ARGS(args)) =20 #define DEFINE_TRACE(name, proto, args) \ DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args)); diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index ff5fa17a6259..0557626b6f6a 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -76,6 +76,13 @@ #define DECLARE_TRACE(name, proto, args) \ DEFINE_TRACE(name, PARAMS(proto), PARAMS(args)) =20 +/* If requested, create helpers for calling these tracepoints from Rust. */ +#ifdef CREATE_RUST_TRACE_POINTS +#undef DEFINE_RUST_DO_TRACE +#define DEFINE_RUST_DO_TRACE(name, proto, args) \ + __DEFINE_RUST_DO_TRACE(name, PARAMS(proto), PARAMS(args)) +#endif + #undef TRACE_INCLUDE #undef __TRACE_INCLUDE =20 @@ -134,6 +141,11 @@ # undef UNDEF_TRACE_INCLUDE_PATH #endif =20 +#ifdef CREATE_RUST_TRACE_POINTS +# undef DEFINE_RUST_DO_TRACE +# define DEFINE_RUST_DO_TRACE(name, proto, args) +#endif + /* We may be processing more files */ #define CREATE_TRACE_POINTS =20 diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index e0846e7e93e6..752572e638a6 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include =20 diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 708ff817ccc3..55f81f49024e 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -54,6 +54,7 @@ pub mod sync; pub mod task; pub mod time; +pub mod tracepoint; pub mod types; pub mod uaccess; pub mod workqueue; diff --git a/rust/kernel/tracepoint.rs b/rust/kernel/tracepoint.rs new file mode 100644 index 000000000000..c6e80aa99e8e --- /dev/null +++ b/rust/kernel/tracepoint.rs @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Logic for tracepoints. + +/// Declare the Rust entry point for a tracepoint. +/// +/// This macro generates an unsafe function that calls into C, and its saf= ety requirements will be +/// whatever the relevant C code requires. To document these safety requir= ements, you may add +/// doc-comments when invoking the macro. +#[macro_export] +macro_rules! declare_trace { + ($($(#[$attr:meta])* $pub:vis unsafe fn $name:ident($($argname:ident := $argtyp:ty),* $(,)?);)*) =3D> {$( + $( #[$attr] )* + #[inline(always)] + $pub unsafe fn $name($($argname : $argtyp),*) { + #[cfg(CONFIG_TRACEPOINTS)] + { + // SAFETY: It's always okay to query the static key for a = tracepoint. + let should_trace =3D unsafe { + $crate::macros::paste! { + $crate::jump_label::static_branch_unlikely!( + $crate::bindings::[< __tracepoint_ $name >], + $crate::bindings::tracepoint, + key + ) + } + }; + + if should_trace { + $crate::macros::paste! { + // SAFETY: The caller guarantees that it is okay t= o call this tracepoint. + unsafe { $crate::bindings::[< rust_do_trace_ $name= >]($($argname),*) }; + } + } + } + + #[cfg(not(CONFIG_TRACEPOINTS))] + { + // If tracepoints are disabled, insert a trivial use of ea= ch argument + // to avoid unused argument warnings. + $( let _unused =3D $argname; )* + } + } + )*} +} + +pub use declare_trace; --=20 2.45.2 From nobody Sun Nov 24 11:38:30 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2897A1D9A72 for ; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; cv=none; b=YvIYPSezelPoXIIUYlRWeCSqz4KFfZCBodnT9qYon1plU8memoU2kmzw8YCZ1Qrjssmer2XcxXSYoKPzrGzLI3AXNgs0CDCS2HKmie8RXFXxba2N7ZYEJRMahk6X09llM4ToDsREB1Tt96XHHKkG/3LaZz0MAgAVJSDrE2QsHac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; c=relaxed/simple; bh=FpeOgWoddCSb5ohVW3hKk9mc0HLZxwfZgTUmuC4DI0k=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=BP2Q31w4dUQVA7p1kn+gQeFdurDNwHYsY0L3VvWiw5rQErb43Pw+hlp9pFfcI7BOP+J4VTpZ+lqJQ05G8BiPYR4OS9uoUNeLzAXfI7ppS05SoZYvFjQF8ONt1gYuKU5Nzd4KdRuYSi7gsv2+62MklZL3KnNA08ZFOREREzmfeTo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC373C4CEDE; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1t8KOj-00000000WjT-0v8H; Tue, 05 Nov 2024 09:19:09 -0500 Message-ID: <20241105141909.064103958@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 05 Nov 2024 09:18:49 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Ard Biesheuvel , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Sean Christopherson , Uros Bizjak , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Ryan Roberts , Fuad Tabba , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Andrew Jones , Alexandre Ghiti , Conor Dooley , Samuel Holland , Huacai Chen , WANG Xuerui , Bibo Mao , Tiezhu Yang , Tianrui Zhao , Boqun Feng , Alice Ryhl Subject: [for-next][PATCH 3/5] rust: samples: add tracepoint to Rust sample References: <20241105141846.641050484@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alice Ryhl This updates the Rust printing sample to invoke a tracepoint. This ensures that we have a user in-tree from the get-go even though the patch is being merged before its real user. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Josh Poimboeuf Cc: Jason Baron Cc: Ard Biesheuvel Cc: Miguel Ojeda Cc: Alex Gaynor Cc: Wedson Almeida Filho Cc: Gary Guo Cc: " =3D?utf-8?q?Bj=3DC3=3DB6rn_Roy_Baron?=3D " Cc: Benno Lossin Cc: Andreas Hindborg Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Sean Christopherson Cc: Uros Bizjak Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: Mark Rutland Cc: Ryan Roberts Cc: Fuad Tabba Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Anup Patel Cc: Andrew Jones Cc: Alexandre Ghiti Cc: Conor Dooley Cc: Samuel Holland Cc: Huacai Chen Cc: WANG Xuerui Cc: Bibo Mao Cc: Tiezhu Yang Cc: Andrew Morton Cc: Tianrui Zhao Link: https://lore.kernel.org/20241030-tracepoint-v12-3-eec7f0f8ad22@google= .com Reviewed-by: Boqun Feng Signed-off-by: Alice Ryhl Signed-off-by: Steven Rostedt (Google) --- MAINTAINERS | 1 + include/trace/events/rust_sample.h | 31 ++++++++++++++++++++++++++++++ rust/bindings/bindings_helper.h | 1 + samples/rust/Makefile | 3 ++- samples/rust/rust_print.rs | 18 +++++++++++++++++ samples/rust/rust_print_events.c | 8 ++++++++ 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 include/trace/events/rust_sample.h create mode 100644 samples/rust/rust_print_events.c diff --git a/MAINTAINERS b/MAINTAINERS index a097afd76ded..a9b71411d77a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20223,6 +20223,7 @@ C: zulip://rust-for-linux.zulipchat.com P: https://rust-for-linux.com/contributing T: git https://github.com/Rust-for-Linux/linux.git rust-next F: Documentation/rust/ +F: include/trace/events/rust_sample.h F: rust/ F: samples/rust/ F: scripts/*rust* diff --git a/include/trace/events/rust_sample.h b/include/trace/events/rust= _sample.h new file mode 100644 index 000000000000..dbc80ca2e465 --- /dev/null +++ b/include/trace/events/rust_sample.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Tracepoints for `samples/rust/rust_print.rs`. + * + * Copyright (C) 2024 Google, Inc. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM rust_sample + +#if !defined(_RUST_SAMPLE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _RUST_SAMPLE_TRACE_H + +#include + +TRACE_EVENT(rust_sample_loaded, + TP_PROTO(int magic_number), + TP_ARGS(magic_number), + TP_STRUCT__entry( + __field(int, magic_number) + ), + TP_fast_assign( + __entry->magic_number =3D magic_number; + ), + TP_printk("magic=3D%d", __entry->magic_number) +); + +#endif /* _RUST_SAMPLE_TRACE_H */ + +/* This part must be outside protection */ +#include diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 752572e638a6..b072c197ce9e 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -23,6 +23,7 @@ #include #include #include +#include =20 /* `bindgen` gets confused at certain things. */ const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN =3D ARCH_SLAB_MINALIGN; diff --git a/samples/rust/Makefile b/samples/rust/Makefile index 03086dabbea4..f29280ec4820 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +ccflags-y +=3D -I$(src) # needed for trace events =20 obj-$(CONFIG_SAMPLE_RUST_MINIMAL) +=3D rust_minimal.o -obj-$(CONFIG_SAMPLE_RUST_PRINT) +=3D rust_print.o +obj-$(CONFIG_SAMPLE_RUST_PRINT) +=3D rust_print.o rust_print_events.o =20 subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS) +=3D hostprogs diff --git a/samples/rust/rust_print.rs b/samples/rust/rust_print.rs index 6eabb0d79ea3..6d14b08cac1c 100644 --- a/samples/rust/rust_print.rs +++ b/samples/rust/rust_print.rs @@ -69,6 +69,8 @@ fn init(_module: &'static ThisModule) -> Result { =20 arc_print()?; =20 + trace::trace_rust_sample_loaded(42); + Ok(RustPrint) } } @@ -78,3 +80,19 @@ fn drop(&mut self) { pr_info!("Rust printing macros sample (exit)\n"); } } + +mod trace { + use core::ffi::c_int; + + kernel::declare_trace! { + /// # Safety + /// + /// Always safe to call. + unsafe fn rust_sample_loaded(magic: c_int); + } + + pub(crate) fn trace_rust_sample_loaded(magic: i32) { + // SAFETY: Always safe to call. + unsafe { rust_sample_loaded(magic as c_int) } + } +} diff --git a/samples/rust/rust_print_events.c b/samples/rust/rust_print_eve= nts.c new file mode 100644 index 000000000000..a9169ff0edf1 --- /dev/null +++ b/samples/rust/rust_print_events.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2024 Google LLC + */ + +#define CREATE_TRACE_POINTS +#define CREATE_RUST_TRACE_POINTS +#include --=20 2.45.2 From nobody Sun Nov 24 11:38:30 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38A221D9A79 for ; Tue, 5 Nov 2024 14:19:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; cv=none; b=JYTjv+WoKb/MJIBnIJLyNpTbAPJ1Awm4jLWBjCPe9IlAfF8jgrAZ+FjDDxVGKOfuLJKJpwfjQZ27E4w6RsZXkdjcn3Yp1ALjcJgOT6Vm0/7hmXykKyM/X35kneOE9vQAZ+iEE0sQ1aehInX1UlOL5y62tZVDY/S/B2pIQVmCkVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; c=relaxed/simple; bh=l4XOID8bnuKps52BWJR7xCc+TANCTqoi5N4lav6Lt78=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=NaxiG3d29x1PmJr+0hfjjxYEpmI1KkEPTnx56x5sRRhMiOK5DdfaJMugFczjUBdWIn96B1SLapsIFHnlpL9K/k8CQKIwv/36D6k7nOqS8hvtp67A9KNvACVszBhRPvSz6Z/gyNaXKePG+KBaD7NyCrzWkkxFkbkTXONjK/JkjxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3DC0C4CEE0; Tue, 5 Nov 2024 14:19:07 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1t8KOj-00000000Wjx-1eaU; Tue, 05 Nov 2024 09:19:09 -0500 Message-ID: <20241105141909.240243748@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 05 Nov 2024 09:18:50 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Josh Poimboeuf , Jason Baron , Ard Biesheuvel , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Sean Christopherson , Uros Bizjak , Will Deacon , Marc Zyngier , Oliver Upton , Ryan Roberts , Fuad Tabba , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Andrew Jones , Alexandre Ghiti , Conor Dooley , Samuel Holland , Huacai Chen , WANG Xuerui , Bibo Mao , Tiezhu Yang , Tianrui Zhao , Palmer Dabbelt , "Peter Zijlstra (Intel)" , Miguel Ojeda , Catalin Marinas , Alice Ryhl Subject: [for-next][PATCH 4/5] jump_label: adjust inline asm to be consistent References: <20241105141846.641050484@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alice Ryhl To avoid duplication of inline asm between C and Rust, we need to import the inline asm from the relevant `jump_label.h` header into Rust. To make that easier, this patch updates the header files to expose the inline asm via a new ARCH_STATIC_BRANCH_ASM macro. The header files are all updated to define a ARCH_STATIC_BRANCH_ASM that takes the same arguments in a consistent order so that Rust can use the same logic for every architecture. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Josh Poimboeuf Cc: Jason Baron Cc: Ard Biesheuvel Cc: Alex Gaynor Cc: Wedson Almeida Filho Cc: Boqun Feng Cc: Gary Guo Cc: " =3D?utf-8?q?Bj=3DC3=3DB6rn_Roy_Baron?=3D " Cc: Benno Lossin Cc: Andreas Hindborg Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Sean Christopherson Cc: Uros Bizjak Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: Mark Rutland Cc: Ryan Roberts Cc: Fuad Tabba Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Anup Patel Cc: Andrew Jones Cc: Alexandre Ghiti Cc: Conor Dooley Cc: Samuel Holland Cc: Huacai Chen Cc: WANG Xuerui Cc: Bibo Mao Cc: Tiezhu Yang Cc: Andrew Morton Cc: Tianrui Zhao Cc: Palmer Dabbelt Link: https://lore.kernel.org/20241030-tracepoint-v12-4-eec7f0f8ad22@google= .com Suggested-by: Peter Zijlstra (Intel) Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda Acked-by: Peter Zijlstra (Intel) Acked-by: Catalin Marinas Acked-by: Palmer Dabbelt # RISC-V Signed-off-by: Alice Ryhl Signed-off-by: Steven Rostedt (Google) --- arch/arm/include/asm/jump_label.h | 14 ++++--- arch/arm64/include/asm/jump_label.h | 20 ++++++---- arch/loongarch/include/asm/jump_label.h | 16 +++++--- arch/riscv/include/asm/jump_label.h | 50 ++++++++++++++----------- arch/x86/include/asm/jump_label.h | 35 +++++++---------- 5 files changed, 73 insertions(+), 62 deletions(-) diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_= label.h index e4eb54f6cd9f..a35aba7f548c 100644 --- a/arch/arm/include/asm/jump_label.h +++ b/arch/arm/include/asm/jump_label.h @@ -9,13 +9,17 @@ =20 #define JUMP_LABEL_NOP_SIZE 4 =20 +/* This macro is also expanded on the Rust side. */ +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + "1:\n\t" \ + WASM(nop) "\n\t" \ + ".pushsection __jump_table, \"aw\"\n\t" \ + ".word 1b, " label ", " key "\n\t" \ + ".popsection\n\t" \ + static __always_inline bool arch_static_branch(struct static_key *key, boo= l branch) { - asm goto("1:\n\t" - WASM(nop) "\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".word 1b, %l[l_yes], %c0\n\t" - ".popsection\n\t" + asm goto(ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]") : : "i" (&((char *)key)[branch]) : : l_yes); =20 return false; diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/j= ump_label.h index a0a5bbae7229..424ed421cd97 100644 --- a/arch/arm64/include/asm/jump_label.h +++ b/arch/arm64/include/asm/jump_label.h @@ -19,10 +19,14 @@ #define JUMP_TABLE_ENTRY(key, label) \ ".pushsection __jump_table, \"aw\"\n\t" \ ".align 3\n\t" \ - ".long 1b - ., %l["#label"] - .\n\t" \ - ".quad %c0 - .\n\t" \ - ".popsection\n\t" \ - : : "i"(key) : : label + ".long 1b - ., " label " - .\n\t" \ + ".quad " key " - .\n\t" \ + ".popsection\n\t" + +/* This macro is also expanded on the Rust side. */ +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + "1: nop\n\t" \ + JUMP_TABLE_ENTRY(key, label) =20 static __always_inline bool arch_static_branch(struct static_key * const k= ey, const bool branch) @@ -30,8 +34,8 @@ static __always_inline bool arch_static_branch(struct sta= tic_key * const key, char *k =3D &((char *)key)[branch]; =20 asm goto( - "1: nop \n\t" - JUMP_TABLE_ENTRY(k, l_yes) + ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]") + : : "i"(k) : : l_yes ); =20 return false; @@ -43,9 +47,11 @@ static __always_inline bool arch_static_branch_jump(stru= ct static_key * const ke const bool branch) { char *k =3D &((char *)key)[branch]; + asm goto( "1: b %l[l_yes] \n\t" - JUMP_TABLE_ENTRY(k, l_yes) + JUMP_TABLE_ENTRY("%c0", "%l[l_yes]") + : : "i"(k) : : l_yes ); return false; l_yes: diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/inclu= de/asm/jump_label.h index 29acfe3de3fa..8a924bd69d19 100644 --- a/arch/loongarch/include/asm/jump_label.h +++ b/arch/loongarch/include/asm/jump_label.h @@ -13,18 +13,22 @@ =20 #define JUMP_LABEL_NOP_SIZE 4 =20 -#define JUMP_TABLE_ENTRY \ +/* This macro is also expanded on the Rust side. */ +#define JUMP_TABLE_ENTRY(key, label) \ ".pushsection __jump_table, \"aw\" \n\t" \ ".align 3 \n\t" \ - ".long 1b - ., %l[l_yes] - . \n\t" \ - ".quad %0 - . \n\t" \ + ".long 1b - ., " label " - . \n\t" \ + ".quad " key " - . \n\t" \ ".popsection \n\t" =20 +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + "1: nop \n\t" \ + JUMP_TABLE_ENTRY(key, label) + static __always_inline bool arch_static_branch(struct static_key * const k= ey, const bool branch) { asm goto( - "1: nop \n\t" - JUMP_TABLE_ENTRY + ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]") : : "i"(&((char *)key)[branch]) : : l_yes); =20 return false; @@ -37,7 +41,7 @@ static __always_inline bool arch_static_branch_jump(struc= t static_key * const ke { asm goto( "1: b %l[l_yes] \n\t" - JUMP_TABLE_ENTRY + JUMP_TABLE_ENTRY("%0", "%l[l_yes]") : : "i"(&((char *)key)[branch]) : : l_yes); =20 return false; diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/j= ump_label.h index 1c768d02bd0c..87a71cc6d146 100644 --- a/arch/riscv/include/asm/jump_label.h +++ b/arch/riscv/include/asm/jump_label.h @@ -16,21 +16,28 @@ =20 #define JUMP_LABEL_NOP_SIZE 4 =20 +#define JUMP_TABLE_ENTRY(key, label) \ + ".pushsection __jump_table, \"aw\" \n\t" \ + ".align " RISCV_LGPTR " \n\t" \ + ".long 1b - ., " label " - . \n\t" \ + "" RISCV_PTR " " key " - . \n\t" \ + ".popsection \n\t" + +/* This macro is also expanded on the Rust side. */ +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + " .align 2 \n\t" \ + " .option push \n\t" \ + " .option norelax \n\t" \ + " .option norvc \n\t" \ + "1: nop \n\t" \ + " .option pop \n\t" \ + JUMP_TABLE_ENTRY(key, label) + static __always_inline bool arch_static_branch(struct static_key * const k= ey, const bool branch) { asm goto( - " .align 2 \n\t" - " .option push \n\t" - " .option norelax \n\t" - " .option norvc \n\t" - "1: nop \n\t" - " .option pop \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align " RISCV_LGPTR " \n\t" - " .long 1b - ., %l[label] - . \n\t" - " " RISCV_PTR " %0 - . \n\t" - " .popsection \n\t" + ARCH_STATIC_BRANCH_ASM("%0", "%l[label]") : : "i"(&((char *)key)[branch]) : : label); =20 return false; @@ -38,21 +45,20 @@ static __always_inline bool arch_static_branch(struct s= tatic_key * const key, return true; } =20 +#define ARCH_STATIC_BRANCH_JUMP_ASM(key, label) \ + " .align 2 \n\t" \ + " .option push \n\t" \ + " .option norelax \n\t" \ + " .option norvc \n\t" \ + "1: j " label " \n\t" \ + " .option pop \n\t" \ + JUMP_TABLE_ENTRY(key, label) + static __always_inline bool arch_static_branch_jump(struct static_key * co= nst key, const bool branch) { asm goto( - " .align 2 \n\t" - " .option push \n\t" - " .option norelax \n\t" - " .option norvc \n\t" - "1: j %l[label] \n\t" - " .option pop \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align " RISCV_LGPTR " \n\t" - " .long 1b - ., %l[label] - . \n\t" - " " RISCV_PTR " %0 - . \n\t" - " .popsection \n\t" + ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[label]") : : "i"(&((char *)key)[branch]) : : label); =20 return false; diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_= label.h index cbbef32517f0..3f1c1d6c0da1 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -12,35 +12,28 @@ #include #include =20 -#define JUMP_TABLE_ENTRY \ +#define JUMP_TABLE_ENTRY(key, label) \ ".pushsection __jump_table, \"aw\" \n\t" \ _ASM_ALIGN "\n\t" \ ".long 1b - . \n\t" \ - ".long %l[l_yes] - . \n\t" \ - _ASM_PTR "%c0 + %c1 - .\n\t" \ + ".long " label " - . \n\t" \ + _ASM_PTR " " key " - . \n\t" \ ".popsection \n\t" =20 +/* This macro is also expanded on the Rust side. */ #ifdef CONFIG_HAVE_JUMP_LABEL_HACK - -static __always_inline bool arch_static_branch(struct static_key *key, boo= l branch) -{ - asm goto("1:" - "jmp %l[l_yes] # objtool NOPs this \n\t" - JUMP_TABLE_ENTRY - : : "i" (key), "i" (2 | branch) : : l_yes); - - return false; -l_yes: - return true; -} - +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + "1: jmp " label " # objtool NOPs this \n\t" \ + JUMP_TABLE_ENTRY(key " + 2", label) #else /* !CONFIG_HAVE_JUMP_LABEL_HACK */ +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + "1: .byte " __stringify(BYTES_NOP5) "\n\t" \ + JUMP_TABLE_ENTRY(key, label) +#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */ =20 static __always_inline bool arch_static_branch(struct static_key * const k= ey, const bool branch) { - asm goto("1:" - ".byte " __stringify(BYTES_NOP5) "\n\t" - JUMP_TABLE_ENTRY + asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]") : : "i" (key), "i" (branch) : : l_yes); =20 return false; @@ -48,13 +41,11 @@ static __always_inline bool arch_static_branch(struct s= tatic_key * const key, co return true; } =20 -#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */ - static __always_inline bool arch_static_branch_jump(struct static_key * co= nst key, const bool branch) { asm goto("1:" "jmp %l[l_yes]\n\t" - JUMP_TABLE_ENTRY + JUMP_TABLE_ENTRY("%c0 + %c1", "%l[l_yes]") : : "i" (key), "i" (branch) : : l_yes); =20 return false; --=20 2.45.2 From nobody Sun Nov 24 11:38:30 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6276E1DA60F for ; Tue, 5 Nov 2024 14:19:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; cv=none; b=mRpj5hR7/S+rWyGP5+fxmkj2o038M8FC0uPVB0o+KpBb7QOMPuZklK+ZWUUl2ddDlAqUaKoLHIPbM1vX0Fxvw0IyBvnqjqoEwNylzk2paZhxM4g+8VVeG2CT5YcZaG7M5S3CJnG7Nde2ACMwBCXEHFdenDiP+6EHEo/KIxtkXU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730816348; c=relaxed/simple; bh=+hkx74GyN3lyWCzj1lro+jVsT9O8FZAkkm7VJ0l2toM=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=lSyVw/s0OoNJVJPPRFP6PVyXLpVzK4h3SJjQ4kkDqCmKwabYqKktt9OvGfpYdKMLUsMhces6UG1QAKQoty3iIfMHQXxbwAd50qYBM+CuM90cQWnMABGRgB0Cgs2snQSMysqafB2g8GXxr9yahylaPiVIcywNj2aYw1sUELUpMQY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2349BC4CEDA; Tue, 5 Nov 2024 14:19:08 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1t8KOj-00000000WkS-2P8i; Tue, 05 Nov 2024 09:19:09 -0500 Message-ID: <20241105141909.417589373@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 05 Nov 2024 09:18:51 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Josh Poimboeuf , Jason Baron , Ard Biesheuvel , Alex Gaynor , Wedson Almeida Filho , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Sean Christopherson , Uros Bizjak , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Ryan Roberts , Fuad Tabba , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Andrew Jones , Alexandre Ghiti , Conor Dooley , Samuel Holland , Huacai Chen , WANG Xuerui , Bibo Mao , Tiezhu Yang , Tianrui Zhao , "Peter Zijlstra (Intel)" , Miguel Ojeda , Boqun Feng , Alice Ryhl Subject: [for-next][PATCH 5/5] rust: add arch_static_branch References: <20241105141846.641050484@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alice Ryhl To allow the Rust implementation of static_key_false to use runtime code patching instead of the generic implementation, pull in the relevant inline assembly from the jump_label.h header by running the C preprocessor on a .rs.S file. Build rules are added for .rs.S files. Since the relevant inline asm has been adjusted to export the inline asm via the ARCH_STATIC_BRANCH_ASM macro in a consistent way, the Rust side does not need architecture specific code to pull in the asm. It is not possible to use the existing C implementation of arch_static_branch via a Rust helper because it passes the argument `key` to inline assembly as an 'i' parameter. Any attempt to add a C helper for this function will fail to compile because the value of `key` must be known at compile-time. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Josh Poimboeuf Cc: Jason Baron Cc: Ard Biesheuvel Cc: Alex Gaynor Cc: Wedson Almeida Filho Cc: Gary Guo Cc: " =3D?utf-8?q?Bj=3DC3=3DB6rn_Roy_Baron?=3D " Cc: Benno Lossin Cc: Andreas Hindborg Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Sean Christopherson Cc: Uros Bizjak Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: Mark Rutland Cc: Ryan Roberts Cc: Fuad Tabba Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Anup Patel Cc: Andrew Jones Cc: Alexandre Ghiti Cc: Conor Dooley Cc: Samuel Holland Cc: Huacai Chen Cc: WANG Xuerui Cc: Bibo Mao Cc: Tiezhu Yang Cc: Andrew Morton Cc: Tianrui Zhao Link: https://lore.kernel.org/20241030-tracepoint-v12-5-eec7f0f8ad22@google= .com Suggested-by: Peter Zijlstra (Intel) Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda Reviewed-by: Boqun Feng Signed-off-by: Alice Ryhl Signed-off-by: Steven Rostedt (Google) --- rust/Makefile | 6 ++++ rust/kernel/.gitignore | 3 ++ rust/kernel/arch_static_branch_asm.rs.S | 7 ++++ rust/kernel/jump_label.rs | 46 ++++++++++++++++++++++++- rust/kernel/lib.rs | 35 +++++++++++++++++++ scripts/Makefile.build | 9 ++++- 6 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 rust/kernel/.gitignore create mode 100644 rust/kernel/arch_static_branch_asm.rs.S diff --git a/rust/Makefile b/rust/Makefile index b5e0a73b78f3..bc2a9071dd29 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -36,6 +36,8 @@ always-$(CONFIG_RUST_KERNEL_DOCTESTS) +=3D doctests_kerne= l_generated_kunit.c obj-$(CONFIG_RUST_KERNEL_DOCTESTS) +=3D doctests_kernel_generated.o obj-$(CONFIG_RUST_KERNEL_DOCTESTS) +=3D doctests_kernel_generated_kunit.o =20 +always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) +=3D kernel/arch_sta= tic_branch_asm.rs + # Avoids running `$(RUSTC)` for the sysroot when it may not be available. ifdef CONFIG_RUST =20 @@ -424,4 +426,8 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(= obj)/build_error.o \ $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE +$(call if_changed_rule,rustc_library) =20 +ifdef CONFIG_JUMP_LABEL +$(obj)/kernel.o: $(obj)/kernel/arch_static_branch_asm.rs +endif + endif # CONFIG_RUST diff --git a/rust/kernel/.gitignore b/rust/kernel/.gitignore new file mode 100644 index 000000000000..d082731007c6 --- /dev/null +++ b/rust/kernel/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +/arch_static_branch_asm.rs diff --git a/rust/kernel/arch_static_branch_asm.rs.S b/rust/kernel/arch_sta= tic_branch_asm.rs.S new file mode 100644 index 000000000000..2afb638708db --- /dev/null +++ b/rust/kernel/arch_static_branch_asm.rs.S @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +// Cut here. + +::kernel::concat_literals!(ARCH_STATIC_BRANCH_ASM("{symb} + {off} + {branc= h}", "{l_yes}")) diff --git a/rust/kernel/jump_label.rs b/rust/kernel/jump_label.rs index 4b7655b2a022..2f2df03a3275 100644 --- a/rust/kernel/jump_label.rs +++ b/rust/kernel/jump_label.rs @@ -24,7 +24,51 @@ macro_rules! static_branch_unlikely { let _key: *const $crate::bindings::static_key_false =3D ::core::pt= r::addr_of!((*_key).$field); let _key: *const $crate::bindings::static_key =3D _key.cast(); =20 - $crate::bindings::static_key_count(_key.cast_mut()) > 0 + #[cfg(not(CONFIG_JUMP_LABEL))] + { + $crate::bindings::static_key_count(_key) > 0 + } + + #[cfg(CONFIG_JUMP_LABEL)] + $crate::jump_label::arch_static_branch! { $key, $keytyp, $field, f= alse } }}; } pub use static_branch_unlikely; + +/// Assert that the assembly block evaluates to a string literal. +#[cfg(CONFIG_JUMP_LABEL)] +const _: &str =3D include!(concat!( + env!("OBJTREE"), + "/rust/kernel/arch_static_branch_asm.rs" +)); + +#[macro_export] +#[doc(hidden)] +#[cfg(CONFIG_JUMP_LABEL)] +macro_rules! arch_static_branch { + ($key:path, $keytyp:ty, $field:ident, $branch:expr) =3D> {'my_label: { + $crate::asm!( + include!(concat!(env!("OBJTREE"), "/rust/kernel/arch_static_br= anch_asm.rs")); + l_yes =3D label { + break 'my_label true; + }, + symb =3D sym $key, + off =3D const ::core::mem::offset_of!($keytyp, $field), + branch =3D const $crate::jump_label::bool_to_int($branch), + ); + + break 'my_label false; + }}; +} + +#[cfg(CONFIG_JUMP_LABEL)] +pub use arch_static_branch; + +/// A helper used by inline assembly to pass a boolean to as a `const` par= ameter. +/// +/// Using this function instead of a cast lets you assert that the input i= s a boolean, and not some +/// other type that can also be cast to an integer. +#[doc(hidden)] +pub const fn bool_to_int(b: bool) -> i32 { + b as i32 +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 55f81f49024e..97286b99270e 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -148,3 +148,38 @@ macro_rules! container_of { ptr.sub(offset) as *const $type }} } + +/// Helper for `.rs.S` files. +#[doc(hidden)] +#[macro_export] +macro_rules! concat_literals { + ($( $asm:literal )* ) =3D> { + ::core::concat!($($asm),*) + }; +} + +/// Wrapper around `asm!` configured for use in the kernel. +/// +/// Uses a semicolon to avoid parsing ambiguities, even though this does n= ot match native `asm!` +/// syntax. +// For x86, `asm!` uses intel syntax by default, but we want to use at&t s= yntax in the kernel. +#[cfg(any(target_arch =3D "x86", target_arch =3D "x86_64"))] +#[macro_export] +macro_rules! asm { + ($($asm:expr),* ; $($rest:tt)*) =3D> { + ::core::arch::asm!( $($asm)*, options(att_syntax), $($rest)* ) + }; +} + +/// Wrapper around `asm!` configured for use in the kernel. +/// +/// Uses a semicolon to avoid parsing ambiguities, even though this does n= ot match native `asm!` +/// syntax. +// For non-x86 arches we just pass through to `asm!`. +#[cfg(not(any(target_arch =3D "x86", target_arch =3D "x86_64")))] +#[macro_export] +macro_rules! asm { + ($($asm:expr),* ; $($rest:tt)*) =3D> { + ::core::arch::asm!( $($asm)*, $($rest)* ) + }; +} diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 8f423a1faf50..03ee558fcd4d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -248,12 +248,13 @@ $(obj)/%.lst: $(obj)/%.c FORCE # Compile Rust sources (.rs) # ------------------------------------------------------------------------= --- =20 -rust_allowed_features :=3D new_uninit +rust_allowed_features :=3D asm_const,asm_goto,new_uninit =20 # `--out-dir` is required to avoid temporaries being created by `rustc` in= the # current working directory, which may be not accessible in the out-of-tree # modules case. rust_common_cmd =3D \ + OBJTREE=3D$(abspath $(objtree)) \ RUST_MODFILE=3D$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ -Zallow-features=3D$(rust_allowed_features) \ -Zcrate-attr=3Dno_std \ @@ -303,6 +304,12 @@ quiet_cmd_rustc_ll_rs =3D $(RUSTC_OR_CLIPPY_QUIET) $(q= uiet_modtag) $@ $(obj)/%.ll: $(obj)/%.rs FORCE +$(call if_changed_dep,rustc_ll_rs) =20 +quiet_cmd_rustc_rs_rs_S =3D RSCPP $(quiet_modtag) $@ + cmd_rustc_rs_rs_S =3D $(CPP) $(c_flags) -xc -C -P $< | sed '1,/^\/\/= Cut here.$$/d' >$@ + +$(obj)/%.rs: $(obj)/%.rs.S FORCE + +$(call if_changed_dep,rustc_rs_rs_S) + # Compile assembler sources (.S) # ------------------------------------------------------------------------= --- =20 --=20 2.45.2