From nobody Tue Oct 7 19:22:17 2025 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 9BEED7E9; Mon, 7 Jul 2025 13:32:02 +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=1751895122; cv=none; b=a0oABNSY7/a1ejXLIpLVp+aZnMAvO/0Bc1vkCkkUJlbqv0gWOnsejoL4Gt+LzArstBAEj5ktb7M54uqqoZDVFFfILeWUsClGsM2y4n29UY5W2ACHDixrphRY7o1bbIQJnTm1JskTkLNwidHGFgqW+PauokpwpRvZ/cPjO8ipgHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895122; c=relaxed/simple; bh=Oicv1zaY1KiQez2F3xOz3tFMueOgAoKspr8/HpnHCEA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tbvhvv2Hm9Sb2ZKq4uSyMRrvEYdpalHnLZTHZzMaBAcEEdwChBvxJvKpEQd9rI+U0zfamIF928jkqUJWWgFnJ/TKvSx1/b1Km5gHy+xsXHGWJ0ws9Fs3k98XtTtET3BOZuxRMAS44oHPlyB2Wgu1K4ga1C/8xdfVID7dS+0jSKQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Kov3HeIU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Kov3HeIU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A3F1C4CEE3; Mon, 7 Jul 2025 13:31:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895122; bh=Oicv1zaY1KiQez2F3xOz3tFMueOgAoKspr8/HpnHCEA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Kov3HeIU+C5qVhA5SoWYLZtbzPdRqIerqiv3o3W5ToAArz9Gf9nAfk9UPmaBKxIOo A5ZF0076DY1WI4EEMZ47vwtJyah9ajNYpjrjLJ5mfaISvm4BUiQZmEypO00fKHnMTc WQg2M0oqieZ8Y3SQmslQGJhOm/oj4V+JRx9Z+Fz6wTmeE8zA/ru6OV4tvV3ALSMhij TW8jh7oDkgpbTfnG5tnRlR0g1Jh/6n1O1E3OjBNAeDTCH7XOUaV7NQLJ+KfpRui1bq BWj1sv750Q8j7V/6xcXqHv4QcoNWMNjMgkTUMnFpe+6Duxaf3HIfpcU6akYZ76Ru7m 20hTdmRwwCUPQ== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:05 +0200 Subject: [PATCH v15 1/7] rust: sync: add `SetOnce` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-1-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=5358; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=Oicv1zaY1KiQez2F3xOz3tFMueOgAoKspr8/HpnHCEA=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8uzVqlbyRCs/KcL2GwyQ1fhSJroQImbn+yOh bTlmrNMEr6JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLswAKCRDhuBo+eShj d8VWEACAJ3x26Gk1uTQPE6NLKy/wpIIq/9IZTv7FfACSd7BC+XgDo3TWxNN30cZiHT8/cF4jRy8 MT2uOStfC4IiVLVsi/+GUH6WX5TJFVNX5wSrfdqUYz4PXlEkAuGacg9cKiyB2pPcz2+QkviZCmP gHQuQd8MT2DEbkIwts8cbv2uIHnZ0M/V8Mm/mIIJm3t3WChuzu2VmXb1oKrmgNKq0IWJkcFhvVN TVwDSpKn7qfynze2Q9pyioouezP4yNVF5TRCns+JIbN7PBBGtmN+1ciEHaxEPPgMqAEhj2WXRB3 6h0gQX/BbjTKsbFA9DFTCaDJCMaOSU+5fi2v7JiZJnoTESuWCc7InNL9yhLKUz37TYbT79J39xz V1p9o0ynjqueScbyc0SW8QUEdBHGnrZwEyez5CFLkFyq68evco1Iq3IjjO6+bXrt7rjryA39JMR flmky1escAmIUDh5O9OcUXZ/4F5NEYhjnTYXgJUZ9CP9UT0ye1tM5saihue5WYZ1CU1JRFtOi7W G8QGaWn1rjvSGUPmRdUM5Q8worY5+6x6TX6NS3JAhpLRevDcvo4zPnOX8Zgn3qoSFqthqIVzY88 w/PVqafIqUTzLa+SBGUJdQIAi6ksfVAkbJ19AqYV+rrLjuo6PdBRUKJcVkjrnCChaCPvB099xMx 4stsum3WPEMSRNg== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Introduce the `SetOnce` type, a container that can only be written once. The container uses an internal atomic to synchronize writes to the internal value. Signed-off-by: Andreas Hindborg Reviewed-by: Alice Ryhl Reviewed-by: Benno Lossin --- rust/kernel/sync.rs | 2 + rust/kernel/sync/set_once.rs | 125 +++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 127 insertions(+) diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs index 81e3a806e57e2..13e6bc7fa87ac 100644 --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -18,6 +18,7 @@ mod locked_by; pub mod poll; pub mod rcu; +mod set_once; =20 pub use arc::{Arc, ArcBorrow, UniqueArc}; pub use completion::Completion; @@ -26,6 +27,7 @@ pub use lock::mutex::{new_mutex, Mutex, MutexGuard}; pub use lock::spinlock::{new_spinlock, SpinLock, SpinLockGuard}; pub use locked_by::LockedBy; +pub use set_once::SetOnce; =20 /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`. #[repr(transparent)] diff --git a/rust/kernel/sync/set_once.rs b/rust/kernel/sync/set_once.rs new file mode 100644 index 0000000000000..e1e31f5faed09 --- /dev/null +++ b/rust/kernel/sync/set_once.rs @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! A container that can be initialized at most once. + +use super::atomic::ordering::Acquire; +use super::atomic::ordering::Relaxed; +use super::atomic::ordering::Release; +use super::atomic::Atomic; +use core::ptr::drop_in_place; +use kernel::types::Opaque; + +/// A container that can be populated at most once. Thread safe. +/// +/// Once the a [`SetOnce`] is populated, it remains populated by the same = object for the +/// lifetime `Self`. +/// +/// # Invariants +/// +/// - `init` may only increase in value. +/// - `init` may only assume values in the range `0..=3D2`. +/// - `init =3D=3D 0` if and only if the container is empty. +/// - `init =3D=3D 1` if and only if being initialized. +/// - `init =3D=3D 2` if and only if the container is populated and valid = for shared access. +/// +/// # Example +/// +/// ``` +/// # use kernel::sync::SetOnce; +/// let value =3D SetOnce::new(); +/// assert_eq!(None, value.as_ref()); +/// +/// let status =3D value.populate(42u8); +/// assert_eq!(true, status); +/// assert_eq!(Some(&42u8), value.as_ref()); +/// assert_eq!(Some(42u8), value.copy()); +/// +/// let status =3D value.populate(101u8); +/// assert_eq!(false, status); +/// assert_eq!(Some(&42u8), value.as_ref()); +/// assert_eq!(Some(42u8), value.copy()); +/// ``` +pub struct SetOnce { + init: Atomic, + value: Opaque, +} + +impl Default for SetOnce { + fn default() -> Self { + Self::new() + } +} + +// TODO: change names + +impl SetOnce { + /// Create a new [`SetOnce`]. + /// + /// The returned instance will be empty. + pub const fn new() -> Self { + // INVARIANT: The container is empty and we initialize `init` to `= 0`. + Self { + value: Opaque::uninit(), + init: Atomic::new(0), + } + } + + /// Get a reference to the contained object. + /// + /// Returns [`None`] if this [`SetOnce`] is empty. + pub fn as_ref(&self) -> Option<&T> { + if self.init.load(Acquire) =3D=3D 2 { + // SAFETY: By the type invariants of `Self`, `self.init =3D=3D= 2` means that `self.value` + // contains a valid value. + Some(unsafe { &*self.value.get() }) + } else { + None + } + } + + /// Populate the [`SetOnce`]. + /// + /// Returns `true` if the [`SetOnce`] was successfully populated. + pub fn populate(&self, value: T) -> bool { + // INVARIANT: If the swap succeeds: + // - We increase `init`. + // - We write the valid value `1` to `init`. + // - Only one thread can succeed in this write, so we have exclus= ive access after the + // write. + if let Ok(0) =3D self.init.cmpxchg(0, 1, Relaxed) { + // SAFETY: By the type invariants of `Self`, the fact that we = succeeded in writing `1` + // to `self.init` means we obtained exclusive access to the co= ntained object. + unsafe { core::ptr::write(self.value.get(), value) }; + // INVARIANT: + // - We increase `init`. + // - We write the valid value `2` to `init`. + // - We release our exclusive access to the contained object = and the object is now + // valid for shared access. + self.init.store(2, Release); + true + } else { + false + } + } + + /// Get a copy of the contained object. + /// + /// Returns [`None`] if the [`SetOnce`] is empty. + pub fn copy(&self) -> Option + where + T: Copy, + { + self.as_ref().copied() + } +} + +impl Drop for SetOnce { + fn drop(&mut self) { + if self.init.load(Acquire) =3D=3D 2 { + // SAFETY: By the type invariants of `Self`, `self.init =3D=3D= 2` means that `self.value` + // contains a valid value. We have exclusive access, as we hol= d a `mut` reference to + // `self`. + unsafe { drop_in_place(self.value.get()) }; + } + } +} --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 78AD0288C2F; Mon, 7 Jul 2025 13:32:13 +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=1751895133; cv=none; b=PZvAvJtLBrY7oo6hcrPAZpMWWQZNygsmfMAXY2JkE9IVJGLJOVF3lqh8y/RjCfn+YtKtdhQKijfuTT1UKHF4YT8Fr0iqsOmLZJ9oD5GEFhbqKql+NVkX1XFg/5ECON89kjOJxQ/vWj9HL3Zc9Vio09rzgWnSOd/Web7zIF13zw4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895133; c=relaxed/simple; bh=xTgqncA4NI+tPjWI9a96IMKRApYDZOqXCThKroirHhA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Cent2Xroh3boRpVWaJdYK/zGYYnNQXRBEwyk9TrC/EQOFUAEYq3zcJ3XYAB7nqWrWBXFCeqRwN97PhrCtMOJg7F94GADtTFzvixxQPHh2/U6ekdx//+Uy0RbVN0W9I/MRXs4a8hE+EiPY4KCScSWvAscl5g/3DmOIFBmLKutMSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sB+vnU69; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sB+vnU69" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 322E1C4CEE3; Mon, 7 Jul 2025 13:32:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895133; bh=xTgqncA4NI+tPjWI9a96IMKRApYDZOqXCThKroirHhA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sB+vnU69HxMSCkoRMbtYyBa6dLZFh4k/qfUsrorPPPOW39E4w4OTFbWm1WrAoOJAG Wi4dehWSoDjIMoE7+1Sn33Lb/KDxqvjxSYpNteE41hVNpF5HIr94Ux3FXW3WHZYZly xu1dDruoDVKcJH5ZUXD1uW5Qa9Yqb0afGsJ4A2vWPQEQKvyyiHUtBdZpsXvFAtgBxq mECS19F8lWEWP2LFVU2zinvGEC9z5Qozo5J6HuqX/Bei9xbv1eOVecdZYUcc2XS2kA NjeOdbreyK9+vve0wWtJhkHM2Gw6vEBlaik0gtDBmN61JwbxKq3wQRhaGXe7Bfxsku NA6i1UydIQ1PQ== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:06 +0200 Subject: [PATCH v15 2/7] rust: str: add radix prefixed integer parsing functions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-2-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=7157; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=xTgqncA4NI+tPjWI9a96IMKRApYDZOqXCThKroirHhA=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u0YVgXtBaiqfSOIzspRCuo+174uzFTZ5WLn /eP3pdkYraJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLtAAKCRDhuBo+eShj d/65D/9+61la4COScehNwo31TfrUsfGY6NA49ubNGEENCBkOtrgWAxLVPaps+OrPL5YufVKi+9B uTVwWwz25flBGWKWxJOl2KSzCexs9jnrgZKE8UVhnQ89DQzUZBZry5I8wok5+FJrLABUNZwXV0l jkefzdwMOLIBi9NasWsbGbc8c7/1gZZIgz4hLSEQvA8yOKk63o6I8qdjeNXnp8GG3wcbP/1Qwr/ NXTcBZP9RuxKs6U+yjCmbAjRXr2Jze9L1tmZ0iziqQNpM+yf5q+mWocIBxaIyZ9R7+nE6kRJW3y MJfDYUOk/V3V85GmCEG3weA0yJDf2ADQfIBo0jQItUOVGtVc+u9SAtvuuFCveejqilupIXS/8SY VOf2Y2eTVA30kfZCvHkZePjTQBuME+6pbr26Qf0rQ8Onztg+szL+ZRUs9OVD0+sUIrYro2ruJai g+U2R1jzG+axmWGXsY6N2pBdY6HvMohdFDzWI8e1Bl77jRb2sFQcPJ2byP7PlIeIonlqsU2r9+5 3CeeI+aUGcxrH44G0umeSQ4MQisWsUx78a6Eb1ceP28y1tIyjpqVliqqm/UwzmSVZEmolHGw2cK YjGSsZr7yScxkPJggXM5VN/0Yiqvb0fxPMYN++x6uAt61wrC5Jx37lEpJCFA6K+OXSFtK+ptbtr Hz9UZgFzjdSC5dw== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Add the trait `ParseInt` for parsing string representations of integers where the string representations are optionally prefixed by a radix specifier. Implement the trait for the primitive integer types. Tested-by: Daniel Gomez Reviewed-by: Greg Kroah-Hartman Suggested-by: Benno Lossin Signed-off-by: Andreas Hindborg Reviewed-by: Benno Lossin --- rust/kernel/str.rs | 2 + rust/kernel/str/parse_int.rs | 148 +++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 150 insertions(+) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index a927db8e079c3..2b6c8b4a0ae4b 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -8,6 +8,8 @@ =20 use crate::prelude::*; =20 +pub mod parse_int; + /// Byte string without UTF-8 validity guarantee. #[repr(transparent)] pub struct BStr([u8]); diff --git a/rust/kernel/str/parse_int.rs b/rust/kernel/str/parse_int.rs new file mode 100644 index 0000000000000..48eb4c202984c --- /dev/null +++ b/rust/kernel/str/parse_int.rs @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Integer parsing functions. +//! +//! Integer parsing functions for parsing signed and unsigned integers +//! potentially prefixed with `0x`, `0o`, or `0b`. + +use crate::prelude::*; +use crate::str::BStr; +use core::ops::Deref; + +// Make `FromStrRadix` a public type with a private name. This seals +// `ParseInt`, that is, prevents downstream users from implementing the +// trait. +mod private { + use crate::prelude::*; + use crate::str::BStr; + + /// Trait that allows parsing a [`&BStr`] to an integer with a radix. + pub trait FromStrRadix: Sized { + /// Parse `src` to [`Self`] using radix `radix`. + fn from_str_radix(src: &BStr, radix: u32) -> Result; + + /// Tries to convert `value` into [`Self`] and negates the resulti= ng value. + fn from_u64_negated(value: u64) -> Result; + } +} + +/// Extract the radix from an integer literal optionally prefixed with +/// one of `0x`, `0X`, `0o`, `0O`, `0b`, `0B`, `0`. +fn strip_radix(src: &BStr) -> (u32, &BStr) { + match src.deref() { + [b'0', b'x' | b'X', rest @ ..] =3D> (16, rest.as_ref()), + [b'0', b'o' | b'O', rest @ ..] =3D> (8, rest.as_ref()), + [b'0', b'b' | b'B', rest @ ..] =3D> (2, rest.as_ref()), + // NOTE: We are including the leading zero to be able to parse + // literal `0` here. If we removed it as a radix prefix, we would + // not be able to parse `0`. + [b'0', ..] =3D> (8, src), + _ =3D> (10, src), + } +} + +/// Trait for parsing string representations of integers. +/// +/// Strings beginning with `0x`, `0o`, or `0b` are parsed as hex, octal, or +/// binary respectively. Strings beginning with `0` otherwise are parsed as +/// octal. Anything else is parsed as decimal. A leading `+` or `-` is also +/// permitted. Any string parsed by [`kstrtol()`] or [`kstrtoul()`] will be +/// successfully parsed. +/// +/// [`kstrtol()`]: https://docs.kernel.org/core-api/kernel-api.html#c.kstr= tol +/// [`kstrtoul()`]: https://docs.kernel.org/core-api/kernel-api.html#c.kst= rtoul +/// +/// # Examples +/// +/// ``` +/// # use kernel::str::parse_int::ParseInt; +/// # use kernel::b_str; +/// +/// assert_eq!(Ok(0u8), u8::from_str(b_str!("0"))); +/// +/// assert_eq!(Ok(0xa2u8), u8::from_str(b_str!("0xa2"))); +/// assert_eq!(Ok(-0xa2i32), i32::from_str(b_str!("-0xa2"))); +/// +/// assert_eq!(Ok(-0o57i8), i8::from_str(b_str!("-0o57"))); +/// assert_eq!(Ok(0o57i8), i8::from_str(b_str!("057"))); +/// +/// assert_eq!(Ok(0b1001i16), i16::from_str(b_str!("0b1001"))); +/// assert_eq!(Ok(-0b1001i16), i16::from_str(b_str!("-0b1001"))); +/// +/// assert_eq!(Ok(127i8), i8::from_str(b_str!("127"))); +/// assert!(i8::from_str(b_str!("128")).is_err()); +/// assert_eq!(Ok(-128i8), i8::from_str(b_str!("-128"))); +/// assert!(i8::from_str(b_str!("-129")).is_err()); +/// assert_eq!(Ok(255u8), u8::from_str(b_str!("255"))); +/// assert!(u8::from_str(b_str!("256")).is_err()); +/// ``` +pub trait ParseInt: private::FromStrRadix + TryFrom { + /// Parse a string according to the description in [`Self`]. + fn from_str(src: &BStr) -> Result { + match src.deref() { + [b'-', rest @ ..] =3D> { + let (radix, digits) =3D strip_radix(rest.as_ref()); + // 2's complement values range from -2^(b-1) to 2^(b-1)-1. + // So if we want to parse negative numbers as positive and + // later multiply by -1, we have to parse into a larger + // integer. We choose `u64` as sufficiently large. + // + // NOTE: 128 bit integers are not available on all + // platforms, hence the choice of 64 bits. + let val =3D + u64::from_str_radix(core::str::from_utf8(digits).map_e= rr(|_| EINVAL)?, radix) + .map_err(|_| EINVAL)?; + Self::from_u64_negated(val) + } + _ =3D> { + let (radix, digits) =3D strip_radix(src); + Self::from_str_radix(digits, radix).map_err(|_| EINVAL) + } + } + } +} + +macro_rules! impl_parse_int { + ($($ty:ty),*) =3D> { + $( + impl private::FromStrRadix for $ty { + fn from_str_radix(src: &BStr, radix: u32) -> Result { + <$ty>::from_str_radix(core::str::from_utf8(src).map_er= r(|_| EINVAL)?, radix) + .map_err(|_| EINVAL) + } + + fn from_u64_negated(value: u64) -> Result { + const ABS_MIN: u64 =3D { + #[allow(unused_comparisons)] + if <$ty>::MIN < 0 { + 1u64 << (<$ty>::BITS - 1) + } else { + 0 + } + }; + + if value > ABS_MIN { + return Err(EINVAL); + } + + if value =3D=3D ABS_MIN { + return Ok(<$ty>::MIN); + } + + // SAFETY: The above checks guarantee that `value` fit= s into `Self`: + // - if `Self` is unsigned, then `ABS_MIN =3D=3D 0` an= d thus we have returned above + // (either `EINVAL` or `MIN`). + // - if `Self` is signed, then we have that `0 <=3D va= lue < ABS_MIN`. And since + // `ABS_MIN - 1` fits into `Self` by construction, `= value` also does. + let value: Self =3D unsafe { value.try_into().unwrap_u= nchecked() }; + + Ok((!value).wrapping_add(1)) + } + } + + impl ParseInt for $ty {} + )* + }; +} + +impl_parse_int![i8, u8, i16, u16, i32, u32, i64, u64, isize, usize]; --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 0ABA92BCF65; Mon, 7 Jul 2025 13:32:32 +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=1751895153; cv=none; b=Iu7DfOOjjWXQZiVLguu02kjcTwuB/4jaXpgPma2ufKEn8MEPIZYj95Qv+IKd3Q+TAQsRP9kmviR2xUgyMbx0sK/9RYpU5UALO9b+sQIbZdSDzI+2X0247X62EqM9ommZni86vXQc+UDBSdXryiup9KVA5eypCyoGzBqCNmqvPmA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895153; c=relaxed/simple; bh=IaejDxR65nfkpFtQKTy5h1EB3F8o0R9aHHtFm2+Kn0U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PkrgYo1H9tLSIeAczf6dzTozdoB6TX66VjPzrkNUC7sNfd6KZQJkqjG0/OmyK9byA8PEI2iCNp9O5Z762NYMCkbDaY4dup9hiWxy3qzZK6/kFivb0O1V7Z7T08SDtVFMpPJHMD/Lk9I+jDWaQXqmWEgxkwvajKldcwqT2uXsAAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VCRc6Qi5; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VCRc6Qi5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 255FCC4CEE3; Mon, 7 Jul 2025 13:32:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895152; bh=IaejDxR65nfkpFtQKTy5h1EB3F8o0R9aHHtFm2+Kn0U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VCRc6Qi5mCEQW/TK0And5ymZ9U35Mqo/TTcU9pqcRNn2kXfS5v9Wspi6Naz1uVpOz XrakJKJceH2DPwuDi60vb6xhXSfAb2hYrdnWfH8nZ0MRmwp0aMER3FkKnaTuGAUqxA o61ynVPrLl9+Ui27gGVxtb3OWy+QJXF9iz6jMvr2F9KYT9gRTNBL8Y8SSNuoJa5FWf MtfpTk3V2NAC6UltOAUjcXAHIk2MMRo2FnRXPMZIdXX6XEqBhRIG1k0UKio7k0vUGe 8b85XRc1F05MoaY6gRDg2A5jhaq2AUghkbT82dSz8ajyYvfgzZjK+cmjcEKewsYXh4 0fUHJEY4paYGw== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:07 +0200 Subject: [PATCH v15 3/7] rust: introduce module_param module Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-3-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=6945; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=IaejDxR65nfkpFtQKTy5h1EB3F8o0R9aHHtFm2+Kn0U=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u1qxbI1VdAOIpBynkexLMcecjIBLkc92Qi2 fvYhuIlXLmJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLtQAKCRDhuBo+eShj d6tmEACXL7nxGIxDceWvCjdEzYAxsBso+yiA51ayCAmihXfYTJX7FKPeMU1qJuoUZFSXNESyXrp C7sEpG1cA3e034MzuhKizyuUOWeeXjDU2/51/Ba/InZVXXh2tJgJTPAm7jMDceoH4WiB0L4emXo FmveXG9VI4aHWtjxwTjfpkP8u+DSLjIaf+ZTwWdic8nu03O3Fra3miAQTzmg6yPKVJC2CRmvO9S o23ZWapPb0jwYRGQcfupXDWKVkge7HmloOhQyYEaGEDKoe2aXtCZOLUH+1Ycu5V38tXO+BXsBN9 qeZqR4OHIlJIme/sBy1SIOPjciXoCAQMKvMaRdMqDZaHISRLbTypLaFtOhGTuyZ8QBFtjU7SKyn iYUtxGELB6LTtPeXydRhVyGHEo0MdJSuspJGwbgFegMMgdPtJmNcvA74rH2qk2fjF3WilypE9zH 19+O+2S76QjZjREQg4tWdNJ4xBFAn3B1iAD+METAkjUAAFIVkKuO0oUGM9oJfgfpBLLBc3wq9vU XB8UMSEzuh473vVnfFp4IXbCwEEwRVBN0443WoxK6ZYepj8qvm6h3uYSqrq9sOwjrGCsS5kxoxM Ty441xv3l6ytFCIwHTUn+X7ydD3WOSv0Gd5FCvMhq0WLFjgJw/xJ93kpGZwzMQV8PeRZIz1FaWn DD75LkmDSwN7xcQ== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Add types and traits for interfacing the C moduleparam API. Reviewed-by: Benno Lossin Signed-off-by: Andreas Hindborg --- rust/kernel/lib.rs | 1 + rust/kernel/module_param.rs | 181 ++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 182 insertions(+) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 6b4774b2b1c37..2b439ea061850 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -87,6 +87,7 @@ pub mod list; pub mod miscdevice; pub mod mm; +pub mod module_param; #[cfg(CONFIG_NET)] pub mod net; pub mod of; diff --git a/rust/kernel/module_param.rs b/rust/kernel/module_param.rs new file mode 100644 index 0000000000000..9b187ed1d3513 --- /dev/null +++ b/rust/kernel/module_param.rs @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Support for module parameters. +//! +//! C header: [`include/linux/moduleparam.h`](srctree/include/linux/module= param.h) + +use crate::prelude::*; +use crate::str::BStr; +use bindings; +use kernel::sync::SetOnce; + +/// Newtype to make `bindings::kernel_param` [`Sync`]. +#[repr(transparent)] +#[doc(hidden)] +pub struct KernelParam(bindings::kernel_param); + +impl KernelParam { + #[doc(hidden)] + pub const fn new(val: bindings::kernel_param) -> Self { + Self(val) + } +} + +// SAFETY: C kernel handles serializing access to this type. We never acce= ss it +// from Rust module. +unsafe impl Sync for KernelParam {} + +/// Types that can be used for module parameters. +// NOTE: This trait is `Copy` because drop could produce unsoundness durin= g teardown. +pub trait ModuleParam: Sized + Copy { + /// Parse a parameter argument into the parameter value. + fn try_from_param_arg(arg: &BStr) -> Result; +} + +/// Set the module parameter from a string. +/// +/// Used to set the parameter value at kernel initialization, when loading +/// the module or when set through `sysfs`. +/// +/// See `struct kernel_param_ops.set`. +/// +/// # Safety +/// +/// - If `val` is non-null then it must point to a valid null-terminated s= tring that must be valid +/// for reads for the duration of the call. +/// - `param` must be a pointer to a `bindings::kernel_param` initialized = by the rust module macro. +/// The pointee must be valid for reads for the duration of the call. +/// +/// # Note +/// +/// - The safety requirements are satisfied by C API contract when this fu= nction is invoked by the +/// module subsystem C code. +/// - Currently, we only support read-only parameters that are not readabl= e from `sysfs`. Thus, this +/// function is only called at kernel initialization time, or at module = load time, and we have +/// exclusive access to the parameter for the duration of the function. +/// +/// [`module!`]: macros::module +unsafe extern "C" fn set_param(val: *const c_char, param: *const bindin= gs::kernel_param) -> c_int +where + T: ModuleParam, +{ + // NOTE: If we start supporting arguments without values, val _is_ all= owed + // to be null here. + if val.is_null() { + // TODO: Use pr_warn_once available. + crate::pr_warn!("Null pointer passed to `module_param::set_param`"= ); + return EINVAL.to_errno(); + } + + // SAFETY: By function safety requirement, val is non-null, null-termi= nated + // and valid for reads for the duration of this function. + let arg =3D unsafe { CStr::from_char_ptr(val) }; + + crate::error::from_result(|| { + let new_value =3D T::try_from_param_arg(arg)?; + + // SAFETY: By function safety requirements, this access is safe. + let container =3D unsafe { &*((*param).__bindgen_anon_1.arg as *mu= t SetOnce) }; + + container + .populate(new_value) + .then_some(0) + .ok_or(kernel::error::code::EEXIST) + }) +} + +macro_rules! impl_int_module_param { + ($ty:ident) =3D> { + impl ModuleParam for $ty { + fn try_from_param_arg(arg: &BStr) -> Result { + <$ty as crate::str::parse_int::ParseInt>::from_str(arg) + } + } + }; +} + +impl_int_module_param!(i8); +impl_int_module_param!(u8); +impl_int_module_param!(i16); +impl_int_module_param!(u16); +impl_int_module_param!(i32); +impl_int_module_param!(u32); +impl_int_module_param!(i64); +impl_int_module_param!(u64); +impl_int_module_param!(isize); +impl_int_module_param!(usize); + +/// A wrapper for kernel parameters. +/// +/// This type is instantiated by the [`module!`] macro when module paramet= ers are +/// defined. You should never need to instantiate this type directly. +/// +/// Note: This type is `pub` because it is used by module crates to access +/// parameter values. +pub struct ModuleParamAccess { + value: SetOnce, + default: T, +} + +// SAFETY: We only create shared references to the contents of this contai= ner, +// so if `T` is `Sync`, so is `ModuleParamAccess`. +unsafe impl Sync for ModuleParamAccess {} + +impl ModuleParamAccess { + #[doc(hidden)] + pub const fn new(default: T) -> Self { + Self { + value: SetOnce::new(), + default, + } + } + + /// Get a shared reference to the parameter value. + // Note: When sysfs access to parameters are enabled, we have to pass = in a + // held lock guard here. + pub fn value(&self) -> &T { + self.value.as_ref().unwrap_or(&self.default) + } + + /// Get a mutable pointer to `self`. + /// + /// NOTE: In most cases it is not safe deref the returned pointer. + pub const fn as_void_ptr(&self) -> *mut c_void { + core::ptr::from_ref(self).cast_mut().cast() + } +} + +#[doc(hidden)] +/// Generate a static [`kernel_param_ops`](srctree/include/linux/modulepar= am.h) struct. +/// +/// # Examples +/// +/// ```ignore +/// make_param_ops!( +/// /// Documentation for new param ops. +/// PARAM_OPS_MYTYPE, // Name for the static. +/// MyType // A type which implements [`ModuleParam`]. +/// ); +/// ``` +macro_rules! make_param_ops { + ($ops:ident, $ty:ty) =3D> { + #[doc(hidden)] + pub static $ops: $crate::bindings::kernel_param_ops =3D $crate::bi= ndings::kernel_param_ops { + flags: 0, + set: Some(set_param::<$ty>), + get: None, + free: None, + }; + }; +} + +make_param_ops!(PARAM_OPS_I8, i8); +make_param_ops!(PARAM_OPS_U8, u8); +make_param_ops!(PARAM_OPS_I16, i16); +make_param_ops!(PARAM_OPS_U16, u16); +make_param_ops!(PARAM_OPS_I32, i32); +make_param_ops!(PARAM_OPS_U32, u32); +make_param_ops!(PARAM_OPS_I64, i64); +make_param_ops!(PARAM_OPS_U64, u64); +make_param_ops!(PARAM_OPS_ISIZE, isize); +make_param_ops!(PARAM_OPS_USIZE, usize); --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 86D212BE040; Mon, 7 Jul 2025 13:32:24 +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=1751895144; cv=none; b=JSfSXuoOGoMBvA1lcrxbNMZNrKpaP1lwrefnyU4aC+o7CwTuQIhHofXYK2rDK9WLvHsmYaD6NKVv0soX/PSEruhYw1s7UuQWUBXfWa1BfCe//eOj+Fb0KiPJ9+9o8tqktp1BRTE4Gt9svuIxkDmQRrYTe+NnLGA9JFGKt/KPIV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895144; c=relaxed/simple; bh=K4Z3grvB4L1O4ywtrXjL9L/tEi3YiQY6qMjemNcyFag=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZXacgac4hMnPLjFnKfT7VVYMuy30HgOm+sFHPopXwZ9Sh6fJUPvqFZeQIt3Hx+xSCQB2bGEFffvqI8XVnoGad6LCCcV2jDbaAsHhLHMcZF8PU/t3ntdkNzP1ALkSLiSvsqLyCN05JnsDkI3j4aWYTI05jzP56t1/eZVDEHudE1w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l1M1QsEl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="l1M1QsEl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5628EC4CEF4; Mon, 7 Jul 2025 13:32:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895144; bh=K4Z3grvB4L1O4ywtrXjL9L/tEi3YiQY6qMjemNcyFag=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=l1M1QsElj1rPW6jMlIh3sGwhN5SxBfnnyGzuewvpLIjivXNpOL4QRl2XRlhP8jBF5 cwCRONh7u7fTN4cwVDejoJBSvLVJpxPUOfcGnFpWHd6Gl406Kf6Oyg3m2JulXRsvvU Rftohr/HsZ4KKDk2Rc9QtgPTvUOmBehAcTPUR6zJ3sFTilp9amSr20/FcaPF+F/3o0 eIjQjGvaVbhB3T/nwd1Tdiupt4w11CVXKbpbwZuC+ImhFObCua1GASo3yj9osksBdN AFDvP1w7eowJf4iXGvXtY9WZyCo6p8SUpDPeVqZDwAPZWlrKMqC0oEUnbanQA7L6RB /HGdvCyfSDtJQ== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:08 +0200 Subject: [PATCH v15 4/7] rust: module: use a reference in macros::module::module Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-4-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2065; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=K4Z3grvB4L1O4ywtrXjL9L/tEi3YiQY6qMjemNcyFag=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u26QT6k4TYweeunaG0ffSARQJFEd+K26YXc DtehNvVllyJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLtgAKCRDhuBo+eShj d2ZZD/9MjlHI0Kidi/nqGDLQpApOrjM30pa9+dUCYMTpbNmdJgjxYrOJMeALAdh7+QMD76V+OrS eDjQ3BvavJBBgLTa30pM/P1hgM2dzJFhNa2Li92mRLoaB1HMJ5rbyFnf7IJSqMs1lfZmGcDpURk zJHhW3Y7mxPmvRM8M50Ohffz9jR721uAZnJYRQjeDomaUw9FlwFuG2BKfHPRmfTaxi7Dq7StvUv 3y46oGGsyoc5/WnkoJFSfGpNppSRYekN8GQZK+0rh6pPyC8A5KbT0LGdtmtvOMraSgJvw5BGKPf +Rj1zxlZj13NWBF9dPALjgcJfn04tfyPqEkmQSOJEtqrK/AcjyGakfTuWStV1vF+ZJxnTGP8NKi LrB/y63JluNKtksIKJgQQ0Wt/D1FcgEr+yMOXJn8C8lV4rfjO9k0YdTuQSsHZ1RSFT9XU6kK8H4 V0NtDqX1DeIxhpw1GH2Ok1uEqENqTxZVLuIq4ijXs7KkMGoI1ehfMWoALvYU+vbI1d2kbmT/eT0 2GZy27QxpxKZjI70mPlLATpDeJzKO6WV8sOFbTQxhumAEAJTH/e4Elw8ri0q/v4MhiPpQQUd+6M fdUKrCT60mMXK6OS8XoV5/Dn4ibxNaffpO7kB9NlzwtqtQza21UTG9FnkqliPITW68ShvxEb0gD WkXFsdWSxJjrO5A== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 When we add parameter support to the module macro, we want to be able to pass a reference to `ModuleInfo` to a helper function. That is not possible when we move out of the local `modinfo`. So change the function to access the local via reference rather than value. Reviewed-by: Benno Lossin Signed-off-by: Andreas Hindborg --- rust/macros/module.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 2ddd2eeb28521..1a867a1e787ed 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -179,26 +179,26 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { // Rust does not allow hyphens in identifiers, use underscore instead. let ident =3D info.name.replace('-', "_"); let mut modinfo =3D ModInfoBuilder::new(ident.as_ref()); - if let Some(author) =3D info.author { - modinfo.emit("author", &author); + if let Some(author) =3D &info.author { + modinfo.emit("author", author); } - if let Some(authors) =3D info.authors { + if let Some(authors) =3D &info.authors { for author in authors { - modinfo.emit("author", &author); + modinfo.emit("author", author); } } - if let Some(description) =3D info.description { - modinfo.emit("description", &description); + if let Some(description) =3D &info.description { + modinfo.emit("description", description); } modinfo.emit("license", &info.license); - if let Some(aliases) =3D info.alias { + if let Some(aliases) =3D &info.alias { for alias in aliases { - modinfo.emit("alias", &alias); + modinfo.emit("alias", alias); } } - if let Some(firmware) =3D info.firmware { + if let Some(firmware) =3D &info.firmware { for fw in firmware { - modinfo.emit("firmware", &fw); + modinfo.emit("firmware", fw); } } =20 --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 109E529AB1D; Mon, 7 Jul 2025 13:32: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=1751895128; cv=none; b=Nunxcm+i+XqnkFGYmzELRtGlxYLIy8KIsS6ze2Yl442XhGzfvPO75sB+kO+OSXdAP91FiqktYLAUoAfaV08zJEPvqb9CuAValAVPBMbSE572CFbRR3CGku/lxm6+h6gDvaaJoMDpUcy399T8mQnKwcXauPElvgKVjWXHp0Isxuc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895128; c=relaxed/simple; bh=2YIwwnFSN+fDOy0TmIgAKz1LQndsAk+izFq3MdUVAOE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I2w/WDJV0yVQdFn5b3y7CIneRNEFfxskPFvSOwayOmOMmJNRrvP973pKzKQ56MBZtNciK/Kvs/lkwUvLGWhO3UdIFpx98di0hTM+lwJr/DjzOzQBfrq/xS7nHvJVbaJq8LcSwEHzz3Uka5XsRDbbCAw6pH2snUVwIxo0OEIzZeU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eUeFLERV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eUeFLERV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A39A1C4CEF4; Mon, 7 Jul 2025 13:32:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895127; bh=2YIwwnFSN+fDOy0TmIgAKz1LQndsAk+izFq3MdUVAOE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eUeFLERVlY2Lz8CDJ68r2ONcfhKseuXe3tRbNb7SrY6a66wKxfTxMNQv27VpF+q1I +/M5kiK+wmQ6ZPHidPAgkN3bU+gUWyhVhwCQP7eM+gdpPv5dh10pq/TTm3cbA5R343 PBmhFjNw7yGwFe2s/+eGpeRvrOEDkn4ws+r23AbeyFjItOQiAmX2W3gO+OvjrMWQFU jGsbbGhL+cetoMsnV+grRFLeBXLemq6jY720i1B+QPO+VUQ+QTxslAtRZAdl757Ose msmRtYYrSaHujDsaepJAXWljWeOSCQV9uy1uEpOJEYFzoVHiI9W+9Xgjtw5MTjrosS 5F6w4mgvAxlWQ== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:09 +0200 Subject: [PATCH v15 5/7] rust: module: update the module macro with module parameter support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-5-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=13520; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=2YIwwnFSN+fDOy0TmIgAKz1LQndsAk+izFq3MdUVAOE=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u3QgQakqkaGtZFh1bxTyECSwDoUc6xm5eQf MWOc/16csmJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLtwAKCRDhuBo+eShj d64PD/4mux3V8xSdg4KgCDnv0BDFmC51T8cvXH9GW37JYImXkPD8uo8e+RD0Vtvz/8ePBpxejUp +eZJ2lwIrB2FO414K3xUT8gcv1uCiYoHrIICoUzdWafiDYlK2y9HsWW8SBtIe80SF9wCYZwwnj5 N+pSGxs4bJEKGKfuK+sNNcIQwK63Fn+xc3RivpAbMiCnpBqAHPlktnMDyrUMelWhuidGP8uunt0 Q4KAZ8klSMNnOHj9d2ftK5hVeX4v1H2f2Wae72Mg0giIq4EnCttWnBufvazSP0LZ7hR27vEw9gm BuH/p3szLa6gHaBReIonGP1QPo/JmOrkwiB7+l+Zlq8MuxIqlG6yr42uHWPD9tzMl0T66fzP5L+ NbrwKjjrXNxzmcPuqAEGXF/dugjbVPPccdYZhd6DQIednjtdi6uiyQuIy/RAQaO6DBBQUaMRQfr YuISOnoqNxY+zXyYHR9gCM6kVZntVucjA2eqDlHkIRWer9stg/I8jEcg1EszJbeJ6058mKphMpm Hve6cm8M0vfOUKhvQY8zJsrcEVzbV1isnVCOio+JIbClUt2q0/Bb5Nm8W4CBbzatUfk+yAjfP7n 4kj7H7XZptvxYhNG0KKNfipGbXaemgzemgr0wAwxBHQq3wSHCHtrH0TFqaU9aazdCdg+5puEBJi o6K7B4af66KSe2g== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Allow module parameters to be declared in the rust `module!` macro. Reviewed-by: Benno Lossin Signed-off-by: Andreas Hindborg --- rust/macros/helpers.rs | 25 +++++++ rust/macros/lib.rs | 31 +++++++++ rust/macros/module.rs | 178 +++++++++++++++++++++++++++++++++++++++++++++= +--- 3 files changed, 224 insertions(+), 10 deletions(-) diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs index e2602be402c10..365d7eb499c08 100644 --- a/rust/macros/helpers.rs +++ b/rust/macros/helpers.rs @@ -10,6 +10,17 @@ pub(crate) fn try_ident(it: &mut token_stream::IntoIter)= -> Option { } } =20 +pub(crate) fn try_sign(it: &mut token_stream::IntoIter) -> Option { + let peek =3D it.clone().next(); + match peek { + Some(TokenTree::Punct(punct)) if punct.as_char() =3D=3D '-' =3D> { + let _ =3D it.next(); + Some(punct.as_char()) + } + _ =3D> None, + } +} + pub(crate) fn try_literal(it: &mut token_stream::IntoIter) -> Option { if let Some(TokenTree::Literal(literal)) =3D it.next() { Some(literal.to_string()) @@ -103,3 +114,17 @@ pub(crate) fn file() -> String { proc_macro::Span::call_site().file() } } + +/// Parse a token stream of the form `expected_name: "value",` and return = the +/// string in the position of "value". +/// +/// # Panics +/// +/// - On parse error. +pub(crate) fn expect_string_field(it: &mut token_stream::IntoIter, expecte= d_name: &str) -> String { + assert_eq!(expect_ident(it), expected_name); + assert_eq!(expect_punct(it), ':'); + let string =3D expect_string(it); + assert_eq!(expect_punct(it), ','); + string +} diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs index fa847cf3a9b5f..2fb520dc930af 100644 --- a/rust/macros/lib.rs +++ b/rust/macros/lib.rs @@ -28,6 +28,30 @@ /// The `type` argument should be a type which implements the [`Module`] /// trait. Also accepts various forms of kernel metadata. /// +/// The `params` field describe module parameters. Each entry has the form +/// +/// ```ignore +/// parameter_name: type { +/// default: default_value, +/// description: "Description", +/// } +/// ``` +/// +/// `type` may be one of +/// +/// - [`i8`] +/// - [`u8`] +/// - [`i8`] +/// - [`u8`] +/// - [`i16`] +/// - [`u16`] +/// - [`i32`] +/// - [`u32`] +/// - [`i64`] +/// - [`u64`] +/// - [`isize`] +/// - [`usize`] +/// /// C header: [`include/linux/moduleparam.h`](srctree/include/linux/module= param.h) /// /// [`Module`]: ../kernel/trait.Module.html @@ -44,6 +68,12 @@ /// description: "My very own kernel module!", /// license: "GPL", /// alias: ["alternate_module_name"], +/// params: { +/// my_parameter: i64 { +/// default: 1, +/// description: "This parameter has a default of 1", +/// }, +/// }, /// } /// /// struct MyModule(i32); @@ -52,6 +82,7 @@ /// fn init(_module: &'static ThisModule) -> Result { /// let foo: i32 =3D 42; /// pr_info!("I contain: {}\n", foo); +/// pr_info!("i32 param is: {}\n", module_parameters::my_paramete= r.read()); /// Ok(Self(foo)) /// } /// } diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 1a867a1e787ed..c1400597774a5 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -26,6 +26,7 @@ struct ModInfoBuilder<'a> { module: &'a str, counter: usize, buffer: String, + param_buffer: String, } =20 impl<'a> ModInfoBuilder<'a> { @@ -34,10 +35,11 @@ fn new(module: &'a str) -> Self { module, counter: 0, buffer: String::new(), + param_buffer: String::new(), } } =20 - fn emit_base(&mut self, field: &str, content: &str, builtin: bool) { + fn emit_base(&mut self, field: &str, content: &str, builtin: bool, par= am: bool) { let string =3D if builtin { // Built-in modules prefix their modinfo strings by `module.`. format!( @@ -51,8 +53,14 @@ fn emit_base(&mut self, field: &str, content: &str, buil= tin: bool) { format!("{field}=3D{content}\0") }; =20 + let buffer =3D if param { + &mut self.param_buffer + } else { + &mut self.buffer + }; + write!( - &mut self.buffer, + buffer, " {cfg} #[doc(hidden)] @@ -75,20 +83,119 @@ fn emit_base(&mut self, field: &str, content: &str, bu= iltin: bool) { self.counter +=3D 1; } =20 - fn emit_only_builtin(&mut self, field: &str, content: &str) { - self.emit_base(field, content, true) + fn emit_only_builtin(&mut self, field: &str, content: &str, param: boo= l) { + self.emit_base(field, content, true, param) } =20 - fn emit_only_loadable(&mut self, field: &str, content: &str) { - self.emit_base(field, content, false) + fn emit_only_loadable(&mut self, field: &str, content: &str, param: bo= ol) { + self.emit_base(field, content, false, param) } =20 fn emit(&mut self, field: &str, content: &str) { - self.emit_only_builtin(field, content); - self.emit_only_loadable(field, content); + self.emit_internal(field, content, false); + } + + fn emit_internal(&mut self, field: &str, content: &str, param: bool) { + self.emit_only_builtin(field, content, param); + self.emit_only_loadable(field, content, param); + } + + fn emit_param(&mut self, field: &str, param: &str, content: &str) { + let content =3D format!("{param}:{content}", param =3D param, cont= ent =3D content); + self.emit_internal(field, &content, true); + } + + fn emit_params(&mut self, info: &ModuleInfo) { + let Some(params) =3D &info.params else { + return; + }; + + for param in params { + let ops =3D param_ops_path(¶m.ptype); + + // Note: The spelling of these fields is dictated by the user = space + // tool `modinfo`. + self.emit_param("parmtype", ¶m.name, ¶m.ptype); + self.emit_param("parm", ¶m.name, ¶m.description); + + write!( + self.param_buffer, + " + pub(crate) static {param_name}: + ::kernel::module_param::ModuleParamAccess<{param_type}= > =3D + ::kernel::module_param::ModuleParamAccess::new({pa= ram_default}); + + const _: () =3D {{ + #[link_section =3D \"__param\"] + #[used] + static __{module_name}_{param_name}_struct: + ::kernel::module_param::KernelParam =3D + ::kernel::module_param::KernelParam::new( + ::kernel::bindings::kernel_param {{ + name: if ::core::cfg!(MODULE) {{ + ::kernel::c_str!(\"{param_name}\").as_= bytes_with_nul() + }} else {{ + ::kernel::c_str!(\"{module_name}.{para= m_name}\") + .as_bytes_with_nul() + }}.as_ptr(), + // SAFETY: `__this_module` is constructed = by the kernel at load + // time and will not be freed until the mo= dule is unloaded. + #[cfg(MODULE)] + mod_: unsafe {{ + core::ptr::from_ref(&::kernel::binding= s::__this_module) + .cast_mut() + }}, + #[cfg(not(MODULE))] + mod_: ::core::ptr::null_mut(), + ops: core::ptr::from_ref(&{ops}), + perm: 0, // Will not appear in sysfs + level: -1, + flags: 0, + __bindgen_anon_1: ::kernel::bindings::kern= el_param__bindgen_ty_1 {{ + arg: {param_name}.as_void_ptr() + }}, + }} + ); + }}; + ", + module_name =3D info.name, + param_type =3D param.ptype, + param_default =3D param.default, + param_name =3D param.name, + ops =3D ops, + ) + .unwrap(); + } + } +} + +fn param_ops_path(param_type: &str) -> &'static str { + match param_type { + "i8" =3D> "::kernel::module_param::PARAM_OPS_I8", + "u8" =3D> "::kernel::module_param::PARAM_OPS_U8", + "i16" =3D> "::kernel::module_param::PARAM_OPS_I16", + "u16" =3D> "::kernel::module_param::PARAM_OPS_U16", + "i32" =3D> "::kernel::module_param::PARAM_OPS_I32", + "u32" =3D> "::kernel::module_param::PARAM_OPS_U32", + "i64" =3D> "::kernel::module_param::PARAM_OPS_I64", + "u64" =3D> "::kernel::module_param::PARAM_OPS_U64", + "isize" =3D> "::kernel::module_param::PARAM_OPS_ISIZE", + "usize" =3D> "::kernel::module_param::PARAM_OPS_USIZE", + t =3D> panic!("Unsupported parameter type {}", t), } } =20 +fn expect_param_default(param_it: &mut token_stream::IntoIter) -> String { + assert_eq!(expect_ident(param_it), "default"); + assert_eq!(expect_punct(param_it), ':'); + let sign =3D try_sign(param_it); + let default =3D try_literal(param_it).expect("Expected default param v= alue"); + assert_eq!(expect_punct(param_it), ','); + let mut value =3D sign.map(String::from).unwrap_or_default(); + value.push_str(&default); + value +} + #[derive(Debug, Default)] struct ModuleInfo { type_: String, @@ -99,6 +206,50 @@ struct ModuleInfo { description: Option, alias: Option>, firmware: Option>, + params: Option>, +} + +#[derive(Debug)] +struct Parameter { + name: String, + ptype: String, + default: String, + description: String, +} + +fn expect_params(it: &mut token_stream::IntoIter) -> Vec { + let params =3D expect_group(it); + assert_eq!(params.delimiter(), Delimiter::Brace); + let mut it =3D params.stream().into_iter(); + let mut parsed =3D Vec::new(); + + loop { + let param_name =3D match it.next() { + Some(TokenTree::Ident(ident)) =3D> ident.to_string(), + Some(_) =3D> panic!("Expected Ident or end"), + None =3D> break, + }; + + assert_eq!(expect_punct(&mut it), ':'); + let param_type =3D expect_ident(&mut it); + let group =3D expect_group(&mut it); + assert_eq!(group.delimiter(), Delimiter::Brace); + assert_eq!(expect_punct(&mut it), ','); + + let mut param_it =3D group.stream().into_iter(); + let param_default =3D expect_param_default(&mut param_it); + let param_description =3D expect_string_field(&mut param_it, "desc= ription"); + expect_end(&mut param_it); + + parsed.push(Parameter { + name: param_name, + ptype: param_type, + default: param_default, + description: param_description, + }) + } + + parsed } =20 impl ModuleInfo { @@ -114,6 +265,7 @@ fn parse(it: &mut token_stream::IntoIter) -> Self { "license", "alias", "firmware", + "params", ]; const REQUIRED_KEYS: &[&str] =3D &["type", "name", "license"]; let mut seen_keys =3D Vec::new(); @@ -140,6 +292,7 @@ fn parse(it: &mut token_stream::IntoIter) -> Self { "license" =3D> info.license =3D expect_string_ascii(it), "alias" =3D> info.alias =3D Some(expect_string_array(it)), "firmware" =3D> info.firmware =3D Some(expect_string_array= (it)), + "params" =3D> info.params =3D Some(expect_params(it)), _ =3D> panic!("Unknown key \"{key}\". Valid keys are: {EXP= ECTED_KEYS:?}."), } =20 @@ -205,7 +358,9 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { // Built-in modules also export the `file` modinfo string. let file =3D std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE= environmental variable"); - modinfo.emit_only_builtin("file", &file); + modinfo.emit_only_builtin("file", &file, false); + + modinfo.emit_params(&info); =20 format!( " @@ -369,15 +524,18 @@ unsafe fn __exit() {{ __MOD.assume_init_drop(); }} }} - {modinfo} }} }} + mod module_parameters {{ + {params} + }} ", type_ =3D info.type_, name =3D info.name, ident =3D ident, modinfo =3D modinfo.buffer, + params =3D modinfo.param_buffer, initcall_section =3D ".initcall6.init" ) .parse() --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 21D467E9; Mon, 7 Jul 2025 13:31:50 +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=1751895112; cv=none; b=azJoY+04A8X6siEdH13flZA3+V7lrv7uG5+dgFOZxYOr4cxIQG+D2rxyNFIJ96aIi/fO+ZJVThd6k8CLzhme4Nzd4LYoa/rDvPQxxthLyQi+hyy6zw8Nz2kCvMKL8GxtyNxxxA8J9flxu7QmZnq39f3oDgdGz23thY8FdgH6gIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895112; c=relaxed/simple; bh=4Rj9VzFcMjV2b2FKGGXgH+pSxDEnRIoZbc9nYVS6Nl0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BXoAbdQfNijCvlcYwPkELvpt06KkCbTu60/xM9AL4vCLBuNshw87zw0H23DsZvYrXTSZxiej8/kJXvHBBfgGXNHskvoRLf5jSM63O/bJx8t+BGj/ylRRUVlLuZQfUY7dGAaycjTCh/av4E4UShrP8mEYBNa7sCpVwK6l+rb2Q78= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=vBTiuLAL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="vBTiuLAL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C1683C4CEE3; Mon, 7 Jul 2025 13:31:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895110; bh=4Rj9VzFcMjV2b2FKGGXgH+pSxDEnRIoZbc9nYVS6Nl0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=vBTiuLALarVF0Dt1NF2pO9KbF2zrU1dKcEeY7MLjPwarJS7TpzSVEvJBOcssY60m1 MaAoF5M0Pjcu1or+17Uho/JG7lKFgAdpdnK0uWXh0dvzw0yPzQ1vBd/zsCXedIyvYq TlEjJnaIWEpvFG+sY7puPE2h3r5yGPwlg3BJVA+WLdtH98pj7dM2TDfBUt59T1K/s+ F4d4efCocsPrK2Gcsz7ms0GghVvys1GjidWhDJY+TjgcB5od9ipizCYT1WSWKK3jl+ DLzLiUrAdJFivBtIxTu0IOxoqdGqbVzN+PvwwD+BnlUhXfefNuCt/aAHf1CqGzgOU9 R6yJ65dWDUzZg== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:10 +0200 Subject: [PATCH v15 6/7] rust: samples: add a module parameter to the rust_minimal sample Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-6-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1268; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=4Rj9VzFcMjV2b2FKGGXgH+pSxDEnRIoZbc9nYVS6Nl0=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u4LFemyRPjAmVKu3zSjovuiQLeEyy8Yu++T kDM3pzk4AeJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLuAAKCRDhuBo+eShj d2gVEACuKT0KcPyN2Jwv1F3/qNbhhCQ9WHRJqZcOa50EQzdxQ5VyYAAPlAiJIPNBAPP3Ksmjfwn 4cGn0X9PVIosA95n8rkqrOJQdnbqBmfQdTQugVuOLRs0huNINSa/HTFw1b28ncXRhWR1eJ4McMN YxIut2wR6FoIxnvkgI1Zyd2OLXYsgBPmpD0ccKZAwGlTQa9BF+TIX+baKoB5FeYc32ZsOErrLTB SJbLbrq8nKPR0POCN4Sl3YKdVmZA+RGCWM8agn/VbFFSaU3+Gaphq0/VM+/tgYaK9fZARQpivK6 rv28Nd3danlAx2f2xLJQ/m3za0GboZVlLltUhlU2l/HNrJTpZYHxEo1oAT1NrGEEGv6V6E2lFbM r5vaBYbNK9yzJMbX0Lv6/IQllxNJD8M6O2/RklhYKHZ1J4CPQd59dX4gObAKkNglaxGKOA3TlL2 jlDGQru09k+38Djr4x75axmGPVxlCQHEyVsjitwWeIenp9SYW5nZdu6MLQrBsUp2UnGmw04pXsP f7wlpyEYdTjFm7Pa2g7fWpvxgrLzbj+X5oRDC4BXzsea9Kx+YnB7tIAGzcd2X6S32OM5VIV9lzW eaYRN9UEIBnKdTHhypS2ZaUTkf4rZz8I78Oai/wrkOcUnMDpfkK+mikU+fSzcGeUbTubljilHHF nqNavY1zff/ri1A== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Showcase the rust module parameter support by adding a module parameter to the `rust_minimal` sample. Reviewed-by: Benno Lossin Signed-off-by: Andreas Hindborg --- samples/rust/rust_minimal.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs index 1fc7a1be6b6d7..8eb9583571d72 100644 --- a/samples/rust/rust_minimal.rs +++ b/samples/rust/rust_minimal.rs @@ -10,6 +10,12 @@ authors: ["Rust for Linux Contributors"], description: "Rust minimal sample", license: "GPL", + params: { + test_parameter: i64 { + default: 1, + description: "This parameter has a default of 1", + }, + }, } =20 struct RustMinimal { @@ -20,6 +26,10 @@ impl kernel::Module for RustMinimal { fn init(_module: &'static ThisModule) -> Result { pr_info!("Rust minimal sample (init)\n"); pr_info!("Am I built-in? {}\n", !cfg!(MODULE)); + pr_info!( + "test_parameter: {}\n", + *module_parameters::test_parameter.value() + ); =20 let mut numbers =3D KVec::new(); numbers.push(72, GFP_KERNEL)?; --=20 2.47.2 From nobody Tue Oct 7 19:22:17 2025 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 39E8F194C96; Mon, 7 Jul 2025 13:32:18 +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=1751895140; cv=none; b=fhKvbdr8Lf2qgXHJjPYGHto31n5wg5N0e+zr6L9isDihCTyi3X9fK91gnWY8suL2cz91DHdJpwKbAzbY3wjMON6CNUBLhQotZ1YFrfGj6aNx3t4LR2zIziINtTiE0nujpR36qkhvyOL2xiFuxMPfcX6HLKpwljM74sZmnHR5hFQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751895140; c=relaxed/simple; bh=rC87q+cE6l79VfDDaP1rreH6c58LNoR3ApaI6m+XCGI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DrPh3iQgmkd6m1DJSa1CJwhOcoLRZyV33Ej+MkYsHS0NJZgbhC/lYTOkI3oUilZ2jrpVC/UDNm7kMJvaeW76U3vkscQMVlphjuIOTN3WTrHlgAihMT5ckIenkf1IDxe59km237fll5EzU6Ix3SK0r3OSI3u2ZuGhaCBAq7u3lx0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cQFYRUZ0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cQFYRUZ0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA555C4CEE3; Mon, 7 Jul 2025 13:32:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751895138; bh=rC87q+cE6l79VfDDaP1rreH6c58LNoR3ApaI6m+XCGI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cQFYRUZ0d7xeMJx+pkAhzljIkHcsFhaiuUEia7MJvDNM62TgSV86L2JRHMWH2WibL /4wY/yQvKLFkVvetKW4MYWbBTxriwdKSobjp+13FwP0gEN/jgC9gjMPbCQjEJ4qu+/ QY/8ajk2CFPC9Fz/T3ArBzJjQzhrWyjz9WmFZgQob2agn4RNWyFONLwLekfmA/ENol prziF/uZbd3tqd0A6VUtUtc/Cp33Z10jpaThmwZa/k+8SF0PH7eJLIRCCF9FedLFVc knbPRredNHpEthWK4HF75GJx4rnYGa/btQw+z+FlDdojgonxpHikOZqT0muYlZ510S NS35ZwSFvAH0w== From: Andreas Hindborg Date: Mon, 07 Jul 2025 15:29:11 +0200 Subject: [PATCH v15 7/7] modules: add rust modules files to MAINTAINERS Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250707-module-params-v3-v15-7-c1f4269a57b9@kernel.org> References: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> In-Reply-To: <20250707-module-params-v3-v15-0-c1f4269a57b9@kernel.org> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Masahiro Yamada , Nathan Chancellor , Luis Chamberlain , Danilo Krummrich , Benno Lossin , Benno Lossin , Nicolas Schier Cc: Trevor Gross , Adam Bratschi-Kaye , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, Petr Pavlu , Sami Tolvanen , Daniel Gomez , Simona Vetter , Greg KH , Fiona Behrens , Daniel Almeida , linux-modules@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=810; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=rC87q+cE6l79VfDDaP1rreH6c58LNoR3ApaI6m+XCGI=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoa8u5TKlqBMqPIfDfZl1ZoFNEqTp/J/82xBY1+ cZuHse87L6JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaGvLuQAKCRDhuBo+eShj d9whD/4w45JCrbOwOKSgUnzjVKqHh0Uhp+3oRLIMfHq4QC3kAHEDHhzuVLObDeZ4sN530OhF6qZ D7bln8Zxm5/wQDycPyuOu66xdJjHOlbgk/yC+2pp04nx3NFQqNl8QxpeQ1s8TCDpiudvCa33W1T fIs/CyohNVMUXN4zJHuSM+gfYMkW1iroglOEWY2fUN8JMW9nlQ1AXzi6G2i8Ys4AGAr8yGJBCR+ 0a7hL3QMz583YSeJDHod0zsQAskEwqB1aFUBfSCM/eHn0o7x7p6Hp47fZPMR65Vg2VfvwG7dVbp ATT5hPaiNoGiP+NlGZNSP5JTth5m8Nww81LD6s8jtJCz2e2tGA8aHZcKXyPIL0H3k5eLkwR3bcv DxEeStUCR+5Keh4V4qxecNamGCx3oOYzq/MP9bPqeUiEw3hTSQNfAnJhjFxaiNXqTy/Zc42rA7R ug4QJMr38SwmVTagdop5rwZoPTcfqt2AIfUdmKkgLjDda/n8Bt7bCMGolZKLYG0qXLVkfwlrkz0 egAsCyzhR42uiQYnYywe+SzNypt0NWBdbjN4fagtHk2/jeNPa3vvkZRA+smgaNDJxXEPA5Ha80P TGLBz33H5lxN658ue9Zwq4DrnaijNGyRTL5Fi6STDrTiBEBJP5G/3ez1oaguNFb38349Sz8nm6V A/GYL1fT5Ogo+bQ== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 The module subsystem people agreed to maintain rust support for modules [1]. Thus, add entries for relevant files to modules entry in MAINTAINERS. Link: https://lore.kernel.org/all/0d9e596a-5316-4e00-862b-fd77552ae4b5@suse= .com/ [1] Acked-by: Daniel Gomez Signed-off-by: Andreas Hindborg --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d431320ed3b2a..afa385ecc5c4c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16835,6 +16835,8 @@ F: include/linux/module*.h F: kernel/module/ F: lib/test_kmod.c F: lib/tests/module/ +F: rust/kernel/module_param.rs +F: rust/macros/module.rs F: scripts/module* F: tools/testing/selftests/kmod/ F: tools/testing/selftests/module/ --=20 2.47.2