From nobody Fri Oct 10 21:13:59 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 6EA5624678F; Thu, 12 Jun 2025 13:42:00 +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=1749735720; cv=none; b=ISewZUYEvjsaNQLHw8kUYNxeB73Erl9kQE+Vfe26g5uU2vu/3FfNiDDMZfxcffZVOlr7tyjalt1zTOYduDbXceeEuRtDJnlVXxZozUU0jA29TMBPVLHmNOopvIPsSDaqOhGctaCJ+5+/XeBGMAXpboPX1yQrKuyyyK8byhpYGso= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735720; c=relaxed/simple; bh=1Zk5g4c16Y0HV+ODTr1tmXBR2FFrktQueKOUyeJhRoE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Bi4E2YydGLrcIDa6WicVCDbZ9MF5gX1+QoXqNP4pHK5fH31RqeR33qNqLJCG4OpxK1owyN6dA0mJVWsfdCiJFu0DoMhE6jYbwQ82GKQQkz6zqLJHBToJxmIX00pAnSez9o723MxDLRjzkHXvphS1AhlgQwrfsZ0/cZIPOKHPsjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AkQNwO45; 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="AkQNwO45" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 78DF5C4CEEA; Thu, 12 Jun 2025 13:41:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735720; bh=1Zk5g4c16Y0HV+ODTr1tmXBR2FFrktQueKOUyeJhRoE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=AkQNwO45AjGclUDSyhcIjBeG0N+juuS207LArNb59QRcFmmgYp1Mf8uSYvlJlow/0 Q0lHeB5wVMdYliuNKAAp3lCN0fNC/klogrbwXYb2YuQhRNU41g97KdIDlGGwyrrWQH Ltsq2gu/1h1qyGnyQidznRAe/AxBftV6UCEYxtR+GOauKExtLcE2vGcDHCmnPtHGlk uttn4QlPg8gChCLHkIi/bL0jt0Zrl6T2tx0SEwiP1EHvPKJvR2kvV+D0ACMfZRoKQ2 WEddRxM3+3DuEmrVmdxdWz4efQnb0qoGrtEQ837H3fM9LYZ7x0xAjwZeIDXg+ezStN DBWUpFRS02IBQ== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:02 +0200 Subject: [PATCH v13 1/6] 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: <20250612-module-params-v3-v13-1-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=7428; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=1Zk5g4c16Y0HV+ODTr1tmXBR2FFrktQueKOUyeJhRoE=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti2h5MQjr8bdVGbxH+6TaWLZpN63COs78haP paQ8whrZ/yJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYtgAKCRDhuBo+eShj dwWFEACxCR5MqlEOysO50ToQYRiW/Fn4Zzh2S3FkmxKp7/dxGJ8/rNB9LLtsYJH32DzIQQpGl+v GG3ZzD6dnPQfZ1MefbBrxZYuFUqN+SN5qKXPK5kpg9c1APfIJAJ+wc/lGXh5YMYwtQ/L8TSR8/h Hv7gqbKd2RHGuJNQ36uHGm8cUB1hkWFWjPoJOqX0Qfls50Xvt0yhYLf8tdc7enEmzO83W6YI2YD FEypOh7/jNi3QMZQEYrjgZSheeOyDHKwcFMrV/usjVBJPQRVCndfjhINknMnDZqanWTrTgZVe3D lHENkgB023+CkR44R7P1yxHULZurGO2jfL8oHKQxEBVj64xbcbIXiUVDApI28R29/UQtltAOADQ jWT38noiM6TQjf5gfXkE+wg8MjCUhAiLQTWWNUwuNvdBd5OMDSQSA/JNgLIME14cX5MwH+yaAMv fjr0Va1Bn/6jCIP9Ih8Zs22LtLXam5GEM0RoLIA7mT2RoVEnshyrZg+K5Y2ESd6ugmlUPVGU1SF jz+MedZfAozt/WZaWu6Zv2M0eCcVUnAPEyGfSpIw3/52ebWDm7SbjHpM5h38de2COZUZzn6mIZ2 ou6SUGL+8RVB8pnmYztX8EZWrXdh94g25BOOXEXL3TWp914Ii9N7gWnSRcT0NQ8U7qzQqY6STqf 3/Z+4888pNa2G4g== 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 Signed-off-by: Andreas Hindborg --- rust/kernel/str.rs | 2 + rust/kernel/str/parse_int.rs | 171 +++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 173 insertions(+) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index a927db8e079c..2b6c8b4a0ae4 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 000000000000..0754490aec4b --- /dev/null +++ b/rust/kernel/str/parse_int.rs @@ -0,0 +1,171 @@ +// 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::str::BStr; + + /// Trait that allows parsing a [`&BStr`] to an integer with a radix. + /// + /// # Safety + /// + /// The member functions of this trait must be implemented according to + /// their documentation. + /// + /// [`&BStr`]: kernel::str::BStr + // This is required because the `from_str_radix` function on the primi= tive + // integer types is not part of any trait. + pub unsafe trait FromStrRadix: Sized { + /// The minimum value this integer type can assume. + const MIN: Self; + + /// Parse `src` to [`Self`] using radix `radix`. + fn from_str_radix(src: &BStr, radix: u32) -> Result; + + /// Return the absolute value of [`Self::MIN`]. + fn abs_min() -> u64; + + /// Perform bitwise 2's complement on `self`. + /// + /// Note: This function does not make sense for unsigned integers. + fn complement(self) -> Self; + } +} + +/// 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)?; + + if val > Self::abs_min() { + return Err(EINVAL); + } + + if val =3D=3D Self::abs_min() { + return Ok(Self::MIN); + } + + // SAFETY: We checked that `val` will fit in `Self` above. + let val: Self =3D unsafe { val.try_into().unwrap_unchecked= () }; + + Ok(val.complement()) + } + _ =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> { + // SAFETY: We implement the trait according to the documentation. + unsafe impl private::FromStrRadix for $ty { + const MIN: Self =3D <$ty>::MIN; + + fn from_str_radix(src: &BStr, radix: u32) -> Result { + <$ty>::from_str_radix(core::str::from_utf8(src).map_err(|_= | EINVAL)?, radix) + .map_err(|_| EINVAL) + } + + fn abs_min() -> u64 { + #[allow(unused_comparisons)] + if Self::MIN < 0 { + 1u64 << (Self::BITS - 1) + } else { + 0 + } + } + + fn complement(self) -> Self { + (!self).wrapping_add((1 as $ty)) + } + } + + impl ParseInt for $ty {} + }; +} + +impl_parse_int!(i8); +impl_parse_int!(u8); +impl_parse_int!(i16); +impl_parse_int!(u16); +impl_parse_int!(i32); +impl_parse_int!(u32); +impl_parse_int!(i64); +impl_parse_int!(u64); +impl_parse_int!(isize); +impl_parse_int!(usize); --=20 2.47.2 From nobody Fri Oct 10 21:13:59 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 BA95B24337C; Thu, 12 Jun 2025 13:41:49 +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=1749735709; cv=none; b=O0Qlpt4rMugzCYMlrJJOPdM1xnU9aPIGCI3kqMFPqGzmiwMVEfwQPGvcwylrqSZT225jB0tq4nMOa5s+Ip4X/mwmvfv0CuyFMke6mM2MOtkUvk3dnr8BGkcEVKcYzaw+upqhUOCCNVSoTsbOolJGXUZkXSaJG0Mgp9KASqGajYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735709; c=relaxed/simple; bh=8wvcbq9+DnI/RWLQdNcGsjq/+GisGIanDf6U3XseGIs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=l3/ua51Dca2nCg4e4a821H0LgfNrE02X9gCbxefY8WBd/OBlN7B3hm63Q2A6/rq1kl+ZqKDAnI6TWpUoLwtyDKT0M3x6+ad16eRKfZG0g0S08cNghpZUzYmxzfl8hyWgwjU/yTvERSEa06QXEzCiLhBxRjQ4dRhcVHKQeAsDV/c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T9LMk6It; 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="T9LMk6It" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6547BC116B1; Thu, 12 Jun 2025 13:41:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735709; bh=8wvcbq9+DnI/RWLQdNcGsjq/+GisGIanDf6U3XseGIs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=T9LMk6Itp33K9CMrNq08fcThcyfgk4jkE5/GmZzIFJJBIIgZYLsR3AjnEN4v9zvz9 xEkHquR/PV2IchPDGebok8ZkOW4gv2xXUr7sTdGIGuvnUy787UezlMof4AYBxwi80g 1vP+GNWn6bXOhqJscwQjGSwEb4znGoN3pmMUo+2lqlHIxk0f3ySzBdlV6b0kHyphXi eDohr9DD/NfauNqVram++4hIDHohCcjrgE9PTWIk/pyEr1uX58GsmRkVW+4IHxote/ qQmLO97EDi9ICeyeXj5PEIBImrqE4tRlSiVDe2yINTuW1rvhL9zBpInPKzGh7YRDPs 9sDdKFq7LfsLA== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:03 +0200 Subject: [PATCH v13 2/6] 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: <20250612-module-params-v3-v13-2-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=8174; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=8wvcbq9+DnI/RWLQdNcGsjq/+GisGIanDf6U3XseGIs=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti3zN6H0ZNtg4erMbXF67x6t+OCVyAIgQLmR sxj6QFDHamJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYtwAKCRDhuBo+eShj d+9yD/42ZhzXzby4Vkxe4Lkhx3KTkVkiveq7I/cvjYhZXDPCnZGAKc2dtXPC9vd+MjKMyTqTRRJ Qkn/LLqFhA6Rm+8pFaat1J45XNwnVa/5d7e10SHdlXfQj1jpXzvmdmnL6LsIW9fo7Bf0WWcR5Bb fzDP98LxHNPNliR0Qi5VyCXhTXUbt5UXikDhYutE0XpqTR3AgcTexwG7OqXyu8zbuXvzgsaN6Y9 0nuTy9UzYZUGnuO7z5MRzD9tDtjlyGjA6JEeBPcllxzvaUwvWJnVf8qmWVH+VBWtFmLnrQ1is61 o0e2Jb7pLmldPXznlQQ4duMjhr8ZUYBwt159vaEcIdemrYzxum3CZbgQBoQg+J3pZe3PaRH/OaE 30iqspzIXb+up8hDP4keRtYljgmXomSAF+KzK+caqA/Wxwhcf9fwzy5mat+5sVJKf87dLM2kFgZ 3um9wVWRFgrtv+pmCkCyvBdqyJrgu8nnFfXnpmyuatdPi16b/l28QEOyx/fPrCf4aO7t3w6e7x1 pjAEaGDVlQQnXUXd65oXpppUv+NnqSixlAqKwVPMxAdZXn96cgHMEypK5l0vIU1nj6szMQjVScD tGhnXSSFOiSkDPPAK28/93s/FfxW2hso/5DU9bKi6/87jH2foVmaXfE9Xl5ObBhG2tmeQo+hw3K x1j3ilKotq0iIuw== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Add types and traits for interfacing the C moduleparam API. Signed-off-by: Andreas Hindborg --- rust/kernel/lib.rs | 1 + rust/kernel/module_param.rs | 201 ++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 202 insertions(+) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 6b4774b2b1c3..2b439ea06185 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 000000000000..fd167df8e53d --- /dev/null +++ b/rust/kernel/module_param.rs @@ -0,0 +1,201 @@ +// 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; + +/// Newtype to make `bindings::kernel_param` [`Sync`]. +#[repr(transparent)] +#[doc(hidden)] +pub struct RacyKernelParam(pub ::kernel::bindings::kernel_param); + +// SAFETY: C kernel handles serializing access to this type. We never acce= ss it +// from Rust module. +unsafe impl Sync for RacyKernelParam {} + +/// Types that can be used for module parameters. +pub trait ModuleParam: Sized + Copy { + /// The [`ModuleParam`] will be used by the kernel module through this= type. + /// + /// This may differ from `Self` if, for example, `Self` needs to track + /// ownership without exposing it or allocate extra space for other po= ssible + /// parameter values. + // This is required to support string parameters in the future. + type Value: ?Sized; + + /// Parse a parameter argument into the parameter value. + /// + /// `Err(_)` should be returned when parsing of the argument fails. + /// + /// Parameters passed at boot time will be set before [`kmalloc`] is + /// available (even if the module is loaded at a later time). However,= in + /// this case, the argument buffer will be valid for the entire lifeti= me of + /// the kernel. So implementations of this method which need to alloca= te + /// should first check that the allocator is available (with + /// [`crate::bindings::slab_is_available`]) and when it is not availab= le + /// provide an alternative implementation which doesn't allocate. In c= ases + /// where the allocator is not available it is safe to save references= to + /// `arg` in `Self`, but in other cases a copy should be made. + /// + /// [`kmalloc`]: srctree/include/linux/slab.h + fn try_from_param_arg(arg: &'static 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. +/// - `parm` must be a pointer to a `bindings::kernel_param` that is valid= for reads for the +/// duration of the call. +/// - `param.arg` must be a pointer to an initialized `T` that is valid fo= r writes for the duration +/// of the function. +/// +/// # 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 crate::bindings::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 `param` is be valid for= reads. + let old_value =3D unsafe { (*param).__bindgen_anon_1.arg as *mut T= }; + + // SAFETY: By function safety requirements, the target of `old_val= ue` is valid for writes + // and is initialized. + unsafe { *old_value =3D new_value }; + Ok(0) + }) +} + +macro_rules! impl_int_module_param { + ($ty:ident) =3D> { + impl ModuleParam for $ty { + type Value =3D $ty; + + fn try_from_param_arg(arg: &'static 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. +#[repr(transparent)] +pub struct ModuleParamAccess { + data: core::cell::UnsafeCell, +} + +// 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(value: T) -> Self { + Self { + data: core::cell::UnsafeCell::new(value), + } + } + + /// 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 get(&self) -> &T { + // SAFETY: As we only support read only parameters with no sysfs + // exposure, the kernel will not touch the parameter data after mo= dule + // initialization. + unsafe { &*self.data.get() } + } + + /// Get a mutable pointer to the parameter value. + pub const fn as_mut_ptr(&self) -> *mut T { + self.data.get() + } +} + +#[doc(hidden)] +#[macro_export] +/// 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 Fri Oct 10 21:13:59 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 CCF7D245003; Thu, 12 Jun 2025 13:41: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=1749735692; cv=none; b=r1lQi9/AwGjlwjxKGgEDB5m45xKEq8stkoCcW+e5MHK8trNg/uFJbb7etg4wRRLvIUFvv4uSbOl+3h0oxQ4ZhkFh3HTJZ9+sG6RuFDkb27T3U8snRLKUhmgs384BQw5YY1fiTHuyGApq2fVi2wmPWm5Sdihzhl/SK25N4w4RYvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735692; c=relaxed/simple; bh=FcJDCcrrHUp9gsLIJbqgqqM6grbEO+rX6m8nZneNa9k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AmSU92JqyppIGILrjktc02qqgHlRBg7+gB9U2Ph+saznUwUnf+gTf2wpHusJMqpoGsEgnnThG9nC67c12YshWyUDwazZBNzmV9IE6y7MyBii0NvcupAKcSoJcryorerUVtoW58xcVWK0mb3ljFXmMGoKXBF8i2Fp7ok70cAYk+U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YCiqbO8P; 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="YCiqbO8P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B095BC4CEF3; Thu, 12 Jun 2025 13:41:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735692; bh=FcJDCcrrHUp9gsLIJbqgqqM6grbEO+rX6m8nZneNa9k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YCiqbO8PLveVBqUFcYoyGAEepEYbrgPCpWH4ycE+WCBSYfgzHFrF6YNmNgr0WNRiX XKm/GNb3+vFHexghEbAgkxs8sukhA+VcmUecuSsYRbCHlY1rXJeeVd/1L/duUobUk7 fNJAmTqWjGQivzTopTbgeoxZbfEe89zqubJfOw8gO96GS4ewdur3N+yy/E3tk2SyQ4 8lA5OKdlEnTqHDIZjpjxrfc6QxdANMMfjF4LC4E949dv7PGUVnGO04+mUHaTW3XHMv piG5b8DS1Vo3y1XjEZodZ4Z/pwz2obG+X0ZhlTKwwxrqFwSeo2ldVWVcu6bpTdGA0r FrDZlpKKJpyGA== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:04 +0200 Subject: [PATCH v13 3/6] 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: <20250612-module-params-v3-v13-3-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=2016; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=FcJDCcrrHUp9gsLIJbqgqqM6grbEO+rX6m8nZneNa9k=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti4FZoE261+TPEL6dSCS8pxoGIx98Evgi/az snBlhPfm42JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYuAAKCRDhuBo+eShj dwfLD/9/TiGg/g1XSoPWG0udbcnt/WvOWr4IYXnnUFJvjHWcUiwYQo9IhaKXkUPQQybhCL6gFX0 hMBUWknuUVNE328JVeYsBsZtQSs6FWLTyXTywaQeD9UYDH/mqAH8x9CmR8nIH72tiDyq8TqHBG+ 7Yb7w0FcPJKlRpidw5j/YkkU/F3bSs/3l0Et/yEC9FuGlGk8+yp4dnhxVwT9CtSZ/Hiu3+oeBJF QQTTBAIWavwsU4l7hsgWEW8v3ImzZc9JVA/hyiCWuBjMlwP+4K6eyL+MaIK1t8n3JWeQgcAhuIh aSZoo+rlVlh+XSrjPE2/ONyWh0u0JPbm+9HHojYCDMc6fO2NpT6opdqqeVPRHxCg6hRLwTJqfTd q175Hhu2mqToqFyF/5OatMZKk5Ga8A8P020gDVPhySltbEF/bos2OrbP8V4sRPCjxbzPAIINbKL lC4h/u22gQWQUZPjHekzRpCOKA2/n+HZEET54XZdUdudu/5io11RcURbz77Wg7WOU/UfIiaSlWh oYomrfIQLKh/F13rTTAd2RszkU3dC53NuxlVS92RzierfnQSlz9S5+7eE1TgPEaTQ0U8zvoaaKW y8jR9YyWFJXtKZewAPenFeQYuNYWL2yQilimEITOFfmN8Xk++hXNHkp/1Ec9JA/YXRUsF1zQ/G0 wMEL5qBiDs7MnbQ== 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. Signed-off-by: Andreas Hindborg Reviewed-by: Benno Lossin --- 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 2ddd2eeb2852..1a867a1e787e 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 Fri Oct 10 21:13:59 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 96C042F4309; Thu, 12 Jun 2025 13:41:27 +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=1749735687; cv=none; b=OOl9an3quiamvHp0MljdpOminTB3gD3wwjujMi40Z4eezm+9H57L3yKKdfa0QYGU4RCyBF8cb9wKq7ZzeM0J4iTt4d3o4v/yOn5YSLRAPOlDBLl5RTUGhJCK2ayL0Ydil1lO2Dt7Y9qkgblhscLuZWBW8ngIcqIVg0nIOG0f8rE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735687; c=relaxed/simple; bh=PV6kxD2yYHPZ26FVfzuEnik3sz20FWj0rE9Vtm2uxy8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P7hZSXNhGRCvobKqLTWfNjeDzfLKFf7gsJ89Qxj+V/KhpOqpYGaKVRRYMFZkkVoLF1HskrK5bHjmpkPfAx9GBqtR/mAHfYPPjYSAEM+emJxr+rC6+DJrVVeU9XmHuU0AN9hgvSH7KpJRQ1+F+YkN6JyeXC1iBI5OyOjzvKM/vMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ufAG53sx; 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="ufAG53sx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 21B6FC4CEEE; Thu, 12 Jun 2025 13:41:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735687; bh=PV6kxD2yYHPZ26FVfzuEnik3sz20FWj0rE9Vtm2uxy8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ufAG53sxEaPTAMYSxGoTXGvG3L0fUs890KKoFtK/AQniC6EZjPl8RfcH2tbkf6Fec loLE6Zlz2KEyozS/M4SOin2h6zOhjRpzb3KUJ0gzeuNooc6a/6oHyKeW/ItCHC95Zz dnhJscmm9JljcReP3XJZgn+mMecMkBU5Jhtton4B6qZ5715UqDgmZLjSAieJiDSale mGYS7yHj+OsGKHT5DcB0gj4FLp//gU3R4QTOFsnjXDfTx3jCov8iunY4BDvpcHp8Cs WW8wv/dzz+1OWE/9G4ffUFWwWOtPAcffqrUnHvjplvMxUevHZRGLQxWfvGGHq/PTIe qJtu0Uzo6u8jQ== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:05 +0200 Subject: [PATCH v13 4/6] 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: <20250612-module-params-v3-v13-4-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=13358; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=PV6kxD2yYHPZ26FVfzuEnik3sz20FWj0rE9Vtm2uxy8=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti5FGohBiBMOv8QlhTrYQU6PuPYFV3PB2Y5m C30Xck8EHmJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYuQAKCRDhuBo+eShj d3+ED/9ng7KCJ+MRs31DFuu6KCd236y+hiwMoMngxk9DLnC4RNKx3wqBS4u0lJszSYCHkGEQxeK zdgOC30ycl43MmbRKBgRmJVUqPcbTDdmc+g6ZZTu2RryuDnLednVT0zop7/VkrJ0aYACxGBl1kv /qcawxJq9Vn9MNEYbxw/78g0T13ktl5YmdY48j5eB1OTCSWZG7U9gGInBU1fKOOj7mL+8z2t+T9 Zmmjnavo8Mgrx6rqG8GQ/sHNu976pSvMGzrCulO9XvNjkTqlAc46j3OaqkCmiweo2ubT9JrOj5Y HdF55YwOO707YgtgJOAnenWLMv4d8luD5BS1GKQmtu7bNn7CkYdaHhhZSnSG1jgdiEpSUoKpRL3 WmLnMkRlxEiXNRNe9sm1RgbmOK8S+u9ecqCi6suPlsBZLR13KgBFiyMLjXuLskKCK0tdAqSl/+Y LV1TDgmS+kPLwQXwSWWldZaA4Vp9qPcaOosOi2uuHKTJVxy/G7ZubAlSca6kRw89KHHm8cAt/1e Ojo60/4kr9JVgM1f0XS9JO2y2HgzncDNOuTooe8ltnXf2HLFIK9CSspHyBk/2iUFyx6IabnxMb3 DaZ8ppS33S8MvnVio3OpCljLE4kVKC0lMhJ21Ti7O1hP/EKTKo1TIdmJMKCI0rVYjYG3rfOgbA4 77ZQbhG8ZyhiYuw== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Allow module parameters to be declared in the rust `module!` macro. Signed-off-by: Andreas Hindborg --- rust/macros/helpers.rs | 25 +++++++ rust/macros/lib.rs | 31 +++++++++ rust/macros/module.rs | 175 +++++++++++++++++++++++++++++++++++++++++++++= +--- 3 files changed, 221 insertions(+), 10 deletions(-) diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs index e2602be402c1..365d7eb499c0 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 fa847cf3a9b5..2fb520dc930a 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 1a867a1e787e..b2605482822a 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,116 @@ 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_t= ype}> =3D + ::kernel::module_param::ModuleParamAccess::new= ({param_default}); + + #[link_section =3D \"__param\"] + #[used] + static __{module_name}_{param_name}_struct: + ::kernel::module_param::RacyKernelParam =3D + ::kernel::module_param::RacyKernelParam(::kernel::= bindings::kernel_param {{ + name: if cfg!(MODULE) {{ + ::kernel::c_str!(\"{param_name}\").as_byte= s_with_nul() + }} else {{ + ::kernel::c_str!(\"{module_name}.{param_na= me}\").as_bytes_with_nul() + }}.as_ptr(), + // SAFETY: `__this_module` is constructed by t= he kernel at load time + // and will not be freed until the module is u= nloaded. + #[cfg(MODULE)] + mod_: unsafe {{ + (&::kernel::bindings::__this_module + as *const ::kernel::bindings::module) + .cast_mut() + }}, + #[cfg(not(MODULE))] + mod_: ::core::ptr::null_mut(), + ops: &{ops} as *const ::kernel::bindings::kern= el_param_ops, + perm: 0, // Will not appear in sysfs + level: -1, + flags: 0, + __bindgen_anon_1: + ::kernel::bindings::kernel_param__bindgen_= ty_1 {{ + arg: {param_name}.as_mut_ptr().cast() + }}, + }}); + ", + 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 +203,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 +262,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 +289,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 +355,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 +521,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 Fri Oct 10 21:13:59 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 037D4246BD6; Thu, 12 Jun 2025 13:41:55 +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=1749735715; cv=none; b=ua0gIJX0Ewhb7IQH2eAg4Fdov4CHJiOqOmHNG8v5R/1alZ6OJ/ozBuu+Mk33AxPk0OABLLZ9xjdNbKfkQIeOAuHve+ifC9H5hcQ9QT6mdghX+smnKP2imKYdgCLsXucfWCNeYBIi9uj5nQdJdMBbHG2KdXpOWQcZENQnTiLV4WU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735715; c=relaxed/simple; bh=93O4r+kmKDFCOxEuHQOYGOvJph9EXJLBbFPup2aAaiw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pJpaRwpK7bnouCAV+T7pG+QNyjUmO9ZZdBAadiVFcvY/KRphOZI2g2OwAGHrY8GmHqoR9RH7wtN7bQG7R2JiQWcbxfBGslzu5JMecWLTauj7h5OnOipxN2JoBKYF6eIMd8n7Ln2ACeB8aTlzNghhmENLdfL6ktjB4/PITl5e85k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UgUR1uNB; 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="UgUR1uNB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6608C4CEEA; Thu, 12 Jun 2025 13:41:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735714; bh=93O4r+kmKDFCOxEuHQOYGOvJph9EXJLBbFPup2aAaiw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UgUR1uNBDrsb0LYLj6wKDMtlcK9go+5fkWHxGNZrGWWcmVxhmGb4PBQGQEWDzQwf9 TMfpEY4ugwSp5GiWEvNCHrXPP9TgTlfqfaS1b77xFXE3JAny+rBfCF9VTpJgHj6MiO cmER3CsQpJavQxyLCUYucOGLgDzMFX2B0xz1MDI7PKwLoybRZUsqvwOdgsWM/VqzHD hynjsTUVz8ghHnrpftwUDcq3vT4//3bB3OnX4QNYQyrvpNStu3JPMMmFrJggBQKGqC FeJLi7JPCeuxLGEcC5Lv9vqbmOYBuELhi8UUzxihvSIzrnFUhdayMBq/XJZ8SNrBB/ pERZD/fZkylSQ== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:06 +0200 Subject: [PATCH v13 5/6] 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: <20250612-module-params-v3-v13-5-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=1217; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=93O4r+kmKDFCOxEuHQOYGOvJph9EXJLBbFPup2aAaiw=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti6KC9qPLWJ8930ZgrcjFzngIpyDLpikU0UG vLM3onGBEyJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYugAKCRDhuBo+eShj d0B9EACrkqVn40B92a0VhRagql+NDwZY5jE8WoFDiLVLlnJa9t5rb3HCpnYqZFng/dfgUtKWC2M 6SbzbVuaWw/DxtgLGNfiJ2MGzBg6yy1ekiAJbeXhAiIeVkjmAxp8NPgvMPyypK6DAGlnZQ4lRcy 2ngi7ek7CNnASahd3mDl7O4F/n8bgEiJ1XX58iU5nvLSReUiA78I7pEV0c+P+Lwl7fWPwxx40jS QMVOnrmI1/wQiEN+PaEym+l2dAu4P1W89/4sYhJ4Mp7+szLcV50yTPFu6H0AjKdGp56yOuE7F9d ziPEJ67RZhQ1RyTyzV47YxyaItyT8S3lbv9t7+macjEUA/GLv7bzl9CmsP+7eKtN6lpfs0Cdec/ iFqw0/d8YyvhC+HYgMx/3p+K43PlEoNpEqDRdWeeHOgSW0qfGsSd1gm1YAJJMNVPoYQTBsHetCc sPKwfqBcaj5+tOurY0xZJMBF+e8KXD6PYcN1JvklizYTNNVxPY4GDu4ekoECKpvKIMaUJkOVtVn 3MsRxN5xykmQyx859tWDGyYsOIsAdZVicg7p7xN1hAHRd8WqqAhAqzODwpU0HXXnGc6quC6e3q/ +ljVzeoaiSYJz5ntE033FYJFgek6Ff/W6zcXNiMH0duuPvRCOrukDLsHtSgxQql/C7Azm5xDk6y hJ7LvHpnKYyk87g== 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. Signed-off-by: Andreas Hindborg Reviewed-by: Benno Lossin --- 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 1fc7a1be6b6d..c04cc07b3249 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.get() + ); =20 let mut numbers =3D KVec::new(); numbers.push(72, GFP_KERNEL)?; --=20 2.47.2 From nobody Fri Oct 10 21:13:59 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 E561429405; Thu, 12 Jun 2025 13:41:43 +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=1749735704; cv=none; b=jvk1GBWWlaS6D3cZuWC3NsWQ8ZLPolOns2Jy4FOHHGImIeVNgXUCgT9UalbrcG8wAKek/DDkjdaX649h0yS2gIifPzvZTc1xwL7CeIqgWSWiAwS0nBPYY0BnPnUp8R0wFyEvIsTT3di4SNOCWmgkSQ76Atqz3ZUqKXeqfKiBAC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749735704; c=relaxed/simple; bh=PtuTc4hQCwkPkaeEcx5FuCImo6u7nfEiFFeDuVcRi+8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=scS38d9ACMRZD5/NQ1JJmStVPd4sm8Kt54oLAkinRX3Fiu+MIkq15f0F38BsZSCOadIreYCGT79GuRlVEiq6CjU5GOtV2AX014Lr2A9m6vfV4/4gJ595WXx1CBQdwO8Gl/P9kafLIX3kWCDbg/Tu0h383X7gLoLQRg7cHrKRZ6w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Zve+8Us0; 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="Zve+8Us0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD919C4CEF3; Thu, 12 Jun 2025 13:41:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1749735703; bh=PtuTc4hQCwkPkaeEcx5FuCImo6u7nfEiFFeDuVcRi+8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Zve+8Us0w5wjasu/XWomWd5hMM8F6wniPNtUHEY44FW0R+Y3sQrnFv625tpuFP41+ txzXWxSKvH5MV2P+7ZcCrZr8ex2+I2QEvzcNcSaERgNUNr6+8AbRIUu9G3ey4RnbLg 1kWUZM3GgTKHCg9AwhLMEpq8U0dHrIekbnr5dKLzCu48fXl/8iFLLSj5xOH2axaufb i4jG1lnWrxab0PgafLygvevOmtv6cCwPVpgQy94lZ4iggQP8KTlGmL7d1CBwnNqAqW ftbpYZqM49g0a8KAJOFsaaOf0KEteuzhNTePhDLzqUECmusLEM+5MDtB9nbpvlaqm1 iO5u+QlhvW9Mw== From: Andreas Hindborg Date: Thu, 12 Jun 2025 15:40:07 +0200 Subject: [PATCH v13 6/6] 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: <20250612-module-params-v3-v13-6-bc219cd1a3f8@kernel.org> References: <20250612-module-params-v3-v13-0-bc219cd1a3f8@kernel.org> In-Reply-To: <20250612-module-params-v3-v13-0-bc219cd1a3f8@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=808; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=PtuTc4hQCwkPkaeEcx5FuCImo6u7nfEiFFeDuVcRi+8=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoSti7f7BsTFkFbFOskmVS4/+QcJ4aUaQYBbQjc u8+JpR5o2mJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaErYuwAKCRDhuBo+eShj d2pNEACnbI0d469VxHqJtVI1ZNarSPJeilQVW6J6dQh5JvBNAIkcUK5AZEBQsV/OGQG9suT42g7 +Q5LB5BgS8yKbKE2eDWN+zzdqyGzsno/unTxk+KOPXyw3wsnhv9N7WYIL0z0bRYsni2gyWem+1C 2NiVyuU50OBTR/930EnWbhdU6aVJjJSfDT3/RAFWeJXU46RZnB8w+z7fAFyDVI7YfhWxbk/FfyF mydPez6cGLpS8G9VBJVfyx+XvLsCXzELL49z+pNOj46Ah80QTzBbA13CmRYgQOCmi1hDTO3n2W+ lNg4nYZB40m/nqXI2cGpw+F3ECX38Y3z31NPlW8wvoXbafwSGxK2AF3VeeClEVD6f5u7BFZgjM9 T9dvRlj/gymgVtlNYUHI3+bQ6a8xDprgsrJQweiZxlhfukuOV1/oOT2AuYivIar2TMaRwcfml2N V6paR5z9uuI8KU4vF6o1S9K6eal5FfPTloW/pskhaU6h92QFKHohse/H4LMDKWuemYw0qiF2stP vOftpBfMsQwTUolE1kaftrVY0cV72g/7hiGI0V/rbgw7p4SRQB16j2TPEko8WMLwgt9ukl+srfO deEtA9WYjFHYGRk+uPwTjKAMeghe7e+EI4wEOdBzEPGAya0g0czzJDRBnZT4en/YCd3qLDm1Spm cNZlXPvQdrnhYdQ== 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 a92290fffa16..e3f43583c9c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16794,6 +16794,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