[PATCH 1/8] rust: module_param: add StringParam type for C string parameters

Matthew Wood posted 8 patches 1 month, 1 week ago
[PATCH 1/8] rust: module_param: add StringParam type for C string parameters
Posted by Matthew Wood 1 month, 1 week ago
Introduce StringParam, a Copy wrapper around *const c_char that
represents a string module parameter whose memory is managed by the
kernel parameter subsystem.

StringParam provides:
  - from_ptr(): construct from a raw C string pointer
  - from_c_str(): construct from a static CStr (for compile-time
    default values)
  - null(): construct an unset/empty parameter
  - as_cstr() / as_bytes(): safe accessors that return None when the
    pointer is null

The type is marked Send + Sync because the underlying pointer is
effectively 'static for the module's lifetime — the kernel guarantees
the string memory remains valid while the module is loaded.

This is a prerequisite for wiring string parameters into the module!
macro in subsequent patches.

Signed-off-by: Matthew Wood <thepacketgeek@gmail.com>
---
 rust/kernel/module_param.rs | 69 +++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/rust/kernel/module_param.rs b/rust/kernel/module_param.rs
index 6a8a7a875643..80fe8643c0ab 100644
--- a/rust/kernel/module_param.rs
+++ b/rust/kernel/module_param.rs
@@ -6,6 +6,7 @@
 
 use crate::prelude::*;
 use crate::str::BStr;
+use crate::str::CStr;
 use bindings;
 use kernel::sync::SetOnce;
 
@@ -106,6 +107,74 @@ fn try_from_param_arg(arg: &BStr) -> Result<Self> {
 impl_int_module_param!(isize);
 impl_int_module_param!(usize);
 
+/// A module parameter that holds a C string pointer.
+///
+/// This type is `Copy` by storing only a raw pointer. The underlying string
+/// memory is managed by the kernel's parameter subsystem.
+///
+/// # Safety
+///
+/// The pointer is only valid while the module is loaded. The kernel ensures
+/// the string memory remains valid for the module's lifetime.
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub struct StringParam {
+    ptr: *const c_char,
+}
+
+impl StringParam {
+    /// Creates a new `StringParam` from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must be valid and point to a null-terminated string,
+    /// or be null for an empty/unset parameter.
+    pub const unsafe fn from_ptr(ptr: *const c_char) -> Self {
+        Self { ptr }
+    }
+
+    /// Creates a `StringParam` from a static `CStr` reference.
+    ///
+    /// Useful for compile-time default values in module parameter declarations.
+    pub const fn from_c_str(s: &'static CStr) -> Self {
+        Self {
+            ptr: crate::str::as_char_ptr_in_const_context(s),
+        }
+    }
+
+    /// Creates a null/empty `StringParam`.
+    pub const fn null() -> Self {
+        Self {
+            ptr: core::ptr::null(),
+        }
+    }
+
+    /// Returns `true` if the parameter is null/unset.
+    pub fn is_null(&self) -> bool {
+        self.ptr.is_null()
+    }
+
+    /// Returns the string as a `CStr` reference, if set.
+    pub fn as_cstr(&self) -> Option<&CStr> {
+        if self.ptr.is_null() {
+            None
+        } else {
+            // SAFETY: pointer validity is checked above
+            Some(unsafe { CStr::from_char_ptr(self.ptr) })
+        }
+    }
+
+    /// Returns the string as bytes, if set.
+    pub fn as_bytes(&self) -> Option<&[u8]> {
+        self.as_cstr().map(|s| s.to_bytes())
+    }
+}
+
+// SAFETY: The pointer is managed by the kernel and is effectively 'static
+// for the module's lifetime.
+unsafe impl Send for StringParam {}
+unsafe impl Sync for StringParam {}
+
 /// A wrapper for kernel parameters.
 ///
 /// This type is instantiated by the [`module!`] macro when module parameters are
-- 
2.52.0

Re: [PATCH 1/8] rust: module_param: add StringParam type for C string parameters
Posted by Petr Pavlu 1 month ago
On 2/27/26 12:47 AM, Matthew Wood wrote:
> Introduce StringParam, a Copy wrapper around *const c_char that
> represents a string module parameter whose memory is managed by the
> kernel parameter subsystem.
> 
> StringParam provides:
>   - from_ptr(): construct from a raw C string pointer
>   - from_c_str(): construct from a static CStr (for compile-time
>     default values)
>   - null(): construct an unset/empty parameter
>   - as_cstr() / as_bytes(): safe accessors that return None when the
>     pointer is null
> 
> The type is marked Send + Sync because the underlying pointer is
> effectively 'static for the module's lifetime — the kernel guarantees
> the string memory remains valid while the module is loaded.

It is correct that module::args is currently valid for the module's
lifetime. However, I wonder if this is still needed and we're not
unnecessarily wasting memory. Since commit e180a6b7759a ("param: fix
charp parameters set via sysfs"), even charp parameters are kmalloc'ed,
unless they end up pointing into static_command_line when the specific
parameters are built into vmlinux and set during boot.

Similarly, if Rust modules eventually need to support parameters set via
sysfs, it will also be necessary to make copies.

-- 
Cheers,
Petr
Re: [PATCH 1/8] rust: module_param: add StringParam type for C string parameters
Posted by Miguel Ojeda 1 month, 1 week ago
On Fri, Feb 27, 2026 at 12:47 AM Matthew Wood <thepacketgeek@gmail.com> wrote:
>
> +/// This type is `Copy` by storing only a raw pointer. The underlying string

Please use intra-doc links where possible/reasonable.

> +/// # Safety
> +///
> +/// The pointer is only valid while the module is loaded. The kernel ensures
> +/// the string memory remains valid for the module's lifetime.
> +#[derive(Copy, Clone)]
> +#[repr(transparent)]
> +pub struct StringParam {

A `# Safety` section for a type? What do you mean here?

I think you may want to establish an invariant instead.

> +            // SAFETY: pointer validity is checked above
> +            Some(unsafe { CStr::from_char_ptr(self.ptr) })

I assume you mean that the non-null implies the validity, but validity
is not really "checked" above. That is why you probably want to have a
proper invariant in the type, so that you can invoke it here etc.

> +unsafe impl Sync for StringParam {}

This is missing a `// SAFETY:` comment -- please double-check
`CLIPPY=1` passes clean.

Cheers,
Miguel