Extend the ModuleParam trait with from_setup_arg(), which constructs a parameter value from a raw C string pointer received via a __setup callback during early boot.
The default implementation converts the pointer to a CStr and delegates to try_from_param_arg(), which handles the parse-from-string path used by integer types. StringParam overrides this method to store the raw pointer directly without parsing, since the pointer originates from static_command_line and remains valid for the kernel's lifetime. Also add ModuleParamAccess::set_value() to allow the __setup callback generated by the module! macro to populate the SetOnce container with first-write-wins semantics. Signed-off-by: Matthew Wood <[email protected]> --- rust/kernel/module_param.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/rust/kernel/module_param.rs b/rust/kernel/module_param.rs index 54379a2bba51..5e14dbe03865 100644 --- a/rust/kernel/module_param.rs +++ b/rust/kernel/module_param.rs @@ -45,6 +45,21 @@ unsafe impl Sync for ObsKernelParam {} pub trait ModuleParam: Sized + Copy { /// Parse a parameter argument into the parameter value. fn try_from_param_arg(arg: &BStr) -> Result<Self>; + + /// Create a parameter value from a raw `__setup` callback argument. + /// + /// Default implementation: parse the null-terminated C string via + /// [`ModuleParam::try_from_param_arg`]. `StringParam` overrides this to store the pointer + /// directly. + /// + /// # Safety + /// + /// `val` must point to a valid null-terminated string. + unsafe fn from_setup_arg(val: *const c_char) -> Result<Self> { + // SAFETY: Caller guarantees `val` points to a valid null-terminated string. + let cstr = unsafe { CStr::from_char_ptr(val) }; + Self::try_from_param_arg(cstr.as_ref()) + } } /// Set the module parameter from a string. @@ -226,6 +241,12 @@ fn try_from_param_arg(_arg: &BStr) -> Result<Self> { // when using PARAM_OPS_STRING. Err(EINVAL) } + + unsafe fn from_setup_arg(val: *const c_char) -> Result<Self> { + // SAFETY: Caller guarantees `val` points to a valid null-terminated string. + // The pointer comes from `static_command_line` which is valid for the kernel's lifetime. + Ok(unsafe { StringParam::from_ptr(val) }) + } } /// A wrapper for kernel parameters. @@ -266,6 +287,14 @@ pub fn value(&self) -> &T { pub const fn as_void_ptr(&self) -> *mut c_void { core::ptr::from_ref(self).cast_mut().cast() } + + /// Set the parameter value directly. + /// + /// Returns `true` if successfully set, `false` if already populated + /// (first-write-wins semantics via [`SetOnce`]). + pub fn set_value(&self, val: T) -> bool { + self.value.populate(val) + } } #[doc(hidden)] -- 2.52.0

