linux-modules.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems
@ 2026-01-06 16:11 Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature Kari Argillander
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander, Youseok Yang, Yuheng Su

Still RFC. Not all people for each subsystems are not included yet as
this touch quite lot of things. Introducing new THIS_MODULE and
ThisModule still change configfs in same patch which is not ideal.

So currently we have problem that we are not always filling .owner field
for file_operations. I think we can enable const_refs_to_static already
as that is in 1.78 and is stable in 1.83. So that fits perfecly for us.
This also seems to be quite request feature but I did not found that no
one has ever suggested that we just enable this.

So basic idea is that we will have ThisModule trait which is used kernel
side. Module side we will always use THIS_MODULE. That is completly
private for modules and kernel cannot use it. So this unifies ways of
using cofing ThisModule things. Currently we have THIS_MODULE and also

  module: &' static ThisModule

on init functions. As we anyway need THIS_MODULE just use that.

    Argillander

To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun.feng@gmail.com>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Danilo Krummrich <dakr@kernel.org>

To: Alexandre Courbot <acourbot@nvidia.com>

Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Petr Pavlu <petr.pavlu@suse.com>
Cc: Daniel Gomez <da.gomez@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Aaron Tomlin <atomlin@atomlin.com>

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
Changes in v2:
- Patches are now sepereted properly.
- Removed debugfs changes as that is not so clear to me.
- Remove module parameter and just used THIS_MODULE everywhere.
- Made macro to make THIS_MODULE.
- Doc tests also have THIS_MODULE.
- Link to v1: https://lore.kernel.org/r/20260101-this_module_fix-v1-0-46ae3e5605a0@gmail.com

---
Kari Argillander (11):
      rust: enable const_refs_to_static feature
      rust: add new ThisModule trait and THIS_MODULE impl
      rust: miscdevice: fix use after free because missing .owner
      rust: block: fix missing owner field in block_device_operations
      rust: drm: fix missing owner in file_operations
      rust: driver: make RegistrationOps::register() to use new ThisModule
      rust: phy: make Registration::register() use new ThisModule
      rust: binder: use new THIS_MODULE
      rust: remove module argument from InPlaceModule::init()
      rust: remove kernel::ModuleMetadata
      rust: remove old version of ThisModule

 drivers/android/binder/rust_binder_main.rs |   5 +-
 drivers/block/rnull/configfs.rs            |   2 +-
 drivers/block/rnull/rnull.rs               |   3 +-
 drivers/gpu/drm/nova/driver.rs             |   2 +
 drivers/gpu/drm/tyr/driver.rs              |   2 +
 drivers/gpu/nova-core/nova_core.rs         |   2 +-
 lib/find_bit_benchmark_rust.rs             |   3 +-
 rust/kernel/auxiliary.rs                   |  16 +--
 rust/kernel/block/mq.rs                    |   1 +
 rust/kernel/block/mq/gen_disk.rs           |  30 +-----
 rust/kernel/block/mq/operations.rs         |  30 ++++++
 rust/kernel/configfs.rs                    |  49 ++++-----
 rust/kernel/driver.rs                      |  31 +++---
 rust/kernel/drm/device.rs                  |   2 +-
 rust/kernel/drm/driver.rs                  |   4 +
 rust/kernel/drm/gem/mod.rs                 |   5 +-
 rust/kernel/firmware.rs                    |   4 +-
 rust/kernel/i2c.rs                         |  11 +-
 rust/kernel/lib.rs                         | 161 ++++++++++++++++++++++++-----
 rust/kernel/miscdevice.rs                  |   5 +
 rust/kernel/net/phy.rs                     |  29 ++++--
 rust/kernel/pci.rs                         |  15 +--
 rust/kernel/platform.rs                    |  12 +--
 rust/kernel/prelude.rs                     |   2 +-
 rust/kernel/sync/lock/global.rs            |   4 +-
 rust/kernel/usb.rs                         |  13 +--
 rust/macros/lib.rs                         |   4 +-
 rust/macros/module.rs                      |  24 +----
 samples/rust/rust_configfs.rs              |   2 +-
 samples/rust/rust_debugfs_scoped.rs        |   2 +-
 samples/rust/rust_driver_auxiliary.rs      |   8 +-
 samples/rust/rust_driver_faux.rs           |   2 +-
 samples/rust/rust_minimal.rs               |   2 +-
 samples/rust/rust_misc_device.rs           |   3 +-
 samples/rust/rust_print_main.rs            |   2 +-
 scripts/rustdoc_test_gen.rs                |   2 +
 36 files changed, 298 insertions(+), 196 deletions(-)
---
base-commit: 6cd6c12031130a349a098dbeb19d8c3070d2dfbe
change-id: 20251230-this_module_fix-a390bff24897

Best regards,
-- 
Kari Argillander <kari.argillander@gmail.com>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 02/11] rust: add new ThisModule trait and THIS_MODULE impl Kari Argillander
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

Enable the const_refs_to_static Rust feature to allow taking
references to static items in const contexts. This is required for
using ThisModule when constructing static Rust structures.

The Rust support already relies on features available in Rust 1.83, and
const_refs_to_static has been available since Rust 1.78.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 rust/kernel/lib.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 6d637e2fed1b..510d4bfc7c2b 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -36,6 +36,7 @@
 #![feature(const_option)]
 #![feature(const_ptr_write)]
 #![feature(const_refs_to_cell)]
+#![feature(const_refs_to_static)]
 //
 // Expected to become stable.
 #![feature(arbitrary_self_types)]

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 02/11] rust: add new ThisModule trait and THIS_MODULE impl
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 03/11] rust: miscdevice: fix use after free because missing .owner Kari Argillander
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

To make clear separation between module crates and kernel crate we
introduce ThisModule trait which is meant to be used by kernel space.
THIS_MODULE is meant to be used by modules. So kernel create will be
unable to even accidentally use THIS_MODULE.

As ThisModule is trait we can pass that around in const context. This is
needed so that we can read ownership information in const context when
we create example file_operations structs for modules.

New ThisModule will also eventually replace kernel::ModuleMetadata trait
and for this reason it also have NAME field.

To make transition smooth use mod this_module so we can have two
ThisModule same time. Also some functionality is added to THIS_MODULE
temporarily so that we do not have to change everything at once.

Also examples will need THIS_MODULE so also define that in docs.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/block/rnull/configfs.rs |   2 +-
 rust/kernel/configfs.rs         |  46 ++++++------
 rust/kernel/lib.rs              | 159 ++++++++++++++++++++++++++++++++++++++++
 rust/macros/module.rs           |  16 +---
 scripts/rustdoc_test_gen.rs     |   2 +
 5 files changed, 188 insertions(+), 37 deletions(-)

diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index 2f5a7da03af5..7223ee7c3032 100644
--- a/drivers/block/rnull/configfs.rs
+++ b/drivers/block/rnull/configfs.rs
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 
-use super::{NullBlkDevice, THIS_MODULE};
+use super::NullBlkDevice;
 use kernel::{
     block::mq::gen_disk::{GenDisk, GenDiskBuilder},
     c_str,
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 466fb7f40762..908cb98d404f 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -110,16 +110,21 @@
 //! [C documentation]: srctree/Documentation/filesystems/configfs.rst
 //! [`rust_configfs.rs`]: srctree/samples/rust/rust_configfs.rs
 
-use crate::alloc::flags;
-use crate::container_of;
-use crate::page::PAGE_SIZE;
-use crate::prelude::*;
-use crate::str::CString;
-use crate::sync::Arc;
-use crate::sync::ArcBorrow;
-use crate::types::Opaque;
-use core::cell::UnsafeCell;
-use core::marker::PhantomData;
+use crate::{
+    alloc::flags,
+    container_of,
+    page::PAGE_SIZE,
+    prelude::*,
+    str::CString,
+    sync::Arc,
+    sync::ArcBorrow,
+    this_module::ThisModule,
+    types::Opaque, //
+};
+use core::{
+    cell::UnsafeCell,
+    marker::PhantomData, //
+};
 
 /// A configfs subsystem.
 ///
@@ -744,8 +749,7 @@ macro_rules! impl_item_type {
     ($tpe:ty) => {
         impl<Data> ItemType<$tpe, Data> {
             #[doc(hidden)]
-            pub const fn new_with_child_ctor<const N: usize, Child>(
-                owner: &'static ThisModule,
+            pub const fn new_with_child_ctor<const N: usize, Child, TM: ThisModule>(
                 attributes: &'static AttributeList<N, Data>,
             ) -> Self
             where
@@ -754,7 +758,7 @@ pub const fn new_with_child_ctor<const N: usize, Child>(
             {
                 Self {
                     item_type: Opaque::new(bindings::config_item_type {
-                        ct_owner: owner.as_ptr(),
+                        ct_owner: TM::OWNER.as_ptr(),
                         ct_group_ops: GroupOperationsVTable::<Data, Child>::vtable_ptr().cast_mut(),
                         ct_item_ops: ItemOperationsVTable::<$tpe, Data>::vtable_ptr().cast_mut(),
                         ct_attrs: core::ptr::from_ref(attributes).cast_mut().cast(),
@@ -765,13 +769,12 @@ pub const fn new_with_child_ctor<const N: usize, Child>(
             }
 
             #[doc(hidden)]
-            pub const fn new<const N: usize>(
-                owner: &'static ThisModule,
+            pub const fn new<const N: usize, TM: ThisModule>(
                 attributes: &'static AttributeList<N, Data>,
             ) -> Self {
                 Self {
                     item_type: Opaque::new(bindings::config_item_type {
-                        ct_owner: owner.as_ptr(),
+                        ct_owner: TM::OWNER.as_ptr(),
                         ct_group_ops: core::ptr::null_mut(),
                         ct_item_ops: ItemOperationsVTable::<$tpe, Data>::vtable_ptr().cast_mut(),
                         ct_attrs: core::ptr::from_ref(attributes).cast_mut().cast(),
@@ -875,8 +878,7 @@ fn as_ptr(&self) -> *const bindings::config_item_type {
 ///         = kernel::configfs::ItemType::<
 ///                 configfs::Subsystem<Configuration>,
 ///                 Configuration
-///                 >::new_with_child_ctor::<N,Child>(
-///             &THIS_MODULE,
+///                 >::new_with_child_ctor::<N, Child, crate::THIS_MODULE>(
 ///             &CONFIGURATION_ATTRS
 ///         );
 ///
@@ -1019,8 +1021,8 @@ macro_rules! configfs_attrs {
                     const [<$no_child:upper>]: bool = true;
 
                     static [< $data:upper _TPE >] : $crate::configfs::ItemType<$container, $data>  =
-                        $crate::configfs::ItemType::<$container, $data>::new::<N>(
-                            &THIS_MODULE, &[<$ data:upper _ATTRS >]
+                        $crate::configfs::ItemType::<$container, $data>::new::<N, crate::THIS_MODULE>(
+                            &[<$ data:upper _ATTRS >]
                         );
                 )?
 
@@ -1028,8 +1030,8 @@ macro_rules! configfs_attrs {
                     static [< $data:upper _TPE >]:
                         $crate::configfs::ItemType<$container, $data>  =
                             $crate::configfs::ItemType::<$container, $data>::
-                            new_with_child_ctor::<N, $child>(
-                                &THIS_MODULE, &[<$ data:upper _ATTRS >]
+                            new_with_child_ctor::<N, $child, crate::THIS_MODULE>(
+                                &[<$ data:upper _ATTRS >]
                             );
                 )?
 
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 510d4bfc7c2b..2ccd75f68f03 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -233,6 +233,165 @@ pub const fn as_ptr(&self) -> *mut bindings::module {
     }
 }
 
+pub mod this_module {
+    //! Access to the module identity and ownership information.
+    //!
+    //! This module provides the Rust equivalent of the kernel’s `THIS_MODULE`
+    //! symbol from the [C API](srctree/include/linux/init.h).
+    //!
+    //! # For driver creators
+    //!
+    //! If you see ThisModule you need to pass THIS_NODULE for it so it can
+    //! track module ownership.
+    //!
+    //! Each Rust module defines its own `THIS_MODULE` using the
+    //! [`create_this_module`] macro. The generated `THIS_MODULE` identifies the
+    //! owning kernel module and expose some metadata about it.
+    //!
+    //! # For abstraction creators
+    //!
+    //! Many times C-apis expect a `struct module *` pointer so they can
+    //! increase the module reference count. This is because module could be
+    //! unloaded while example file operations are in progress. Many times
+    //! structs which needs owner fields should also be const. For this reason
+    //! ThisModule is usually passes as a type parameter `TM` to abstractions
+    //! which need to know the module owner. In vtables ThisModule is usually
+    //! used as name.
+    //!
+    //! ## Example
+    //!
+    //! ```
+    //! # use kernel::{bindings, this_module::ThisModule};
+    //! # use core::marker::PhantomData;
+    //!
+    //! // Example function signature which needs ThisModule.
+    //! pub fn create_device<TM: ThisModule>() {}
+    //!
+    //! // Example of a vtable which uses ThisModule.
+    //! #[vtable]
+    //! pub trait MyStruct {
+    //!     type ThisModule: ThisModule;
+    //! }
+    //!
+    //! pub(crate) struct MyStructVTable<T: MyStruct>(PhantomData<T>);
+    //!
+    //! impl<T: MyStruct> MyStructVTable<T> {
+    //!     const FOPS: bindings::file_operations = bindings::file_operations {
+    //!         owner: T::ThisModule::OWNER.as_ptr(),
+    //!         ..pin_init::zeroed()
+    //!     };
+    //! }
+    //! ```
+
+    /// See [`this_module`]
+    pub trait ThisModule {
+        /// Wrapper around the owning `struct module` pointer.
+        ///
+        /// This is null for built-in code and non-null for loadable modules.
+        const OWNER: ModuleWrapper;
+        /// Name of the module.
+        const NAME: &'static kernel::str::CStr;
+    }
+
+    /// Wrapper around a pointer to `struct module`.
+    ///
+    /// This type exists as a workaround for the lack of `const fn` methods in
+    /// traits. It allows the module pointer to be stored as an associated
+    /// constant while still providing a `const` accessor.
+    pub struct ModuleWrapper {
+        ptr: *mut bindings::module,
+    }
+
+    impl ModuleWrapper {
+        /// Get the raw pointer to the underlying `struct module`.
+        ///
+        /// TODO: Should be only available for kernel create.
+        pub const fn as_ptr(&self) -> *mut bindings::module {
+            self.ptr
+        }
+
+        /// Only meant to be used from [`create_this_module`].
+        ///
+        /// # Safety
+        ///
+        /// - Only modules are allowed to create non null `ModuleWrapper`s.
+        /// - The non null pointer must point to a valid `struct module`
+        ///   provided by the kernel.
+        #[doc(hidden)]
+        pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> Self {
+            ModuleWrapper { ptr }
+        }
+    }
+
+    /// Creates the `THIS_MODULE` definition for a Rust module.
+    ///
+    /// This macro is an internal building block and is not intended to be used
+    /// directly by module authors. It is invoked by [`macros::module::module`]
+    /// and by kernel doctests.
+    ///
+    /// A macro is required so that `cfg(MODULE)` is evaluated in the context of
+    /// the consuming crate, and to prevent accidental use of THIS_MODULE from
+    /// within the kernel crate itself.
+    #[macro_export]
+    #[doc(hidden)]
+    macro_rules! create_this_module {
+        ($name:literal) => {
+            /// THIS_MODULE for module `{name}`. See [`kernel::this_module`].
+            #[allow(non_camel_case_types)]
+            pub struct THIS_MODULE;
+
+            impl ::kernel::this_module::ThisModule for THIS_MODULE {
+                #[cfg(not(MODULE))]
+                /// SAFETY: TODO
+                const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {
+                    ::kernel::this_module::ModuleWrapper::from_ptr(::core::ptr::null_mut())
+                };
+
+                #[cfg(MODULE)]
+                // SAFETY:
+                // - `__this_module` is constructed by the kernel at module load time.
+                const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {
+                    extern "C" {
+                        static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
+                    }
+
+                    ::kernel::this_module::ModuleWrapper::from_ptr(__this_module.get())
+                };
+
+                const NAME: &'static ::kernel::str::CStr = $crate::c_str!($name);
+            }
+
+            impl THIS_MODULE {
+                /// Returns the name of this module.
+                pub const fn name() -> &'static ::kernel::str::CStr {
+                    $crate::c_str!($name)
+                }
+
+                // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+                // SAFETY: `__this_module` is constructed by the kernel at load time and
+                // will not be freed until the module is unloaded.
+                const ThisModule: ::kernel::ThisModule = unsafe {{
+                    ::kernel::ThisModule::from_ptr(
+                        <Self as ::kernel::this_module::ThisModule>::OWNER.as_ptr()
+                    )
+                }};
+    
+                /// Gets a pointer to the underlying `struct module`.
+                // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+                pub const fn as_ptr(&self) -> *mut ::kernel::bindings::module {{
+                    Self::ThisModule.as_ptr()
+                }}
+
+                /// Gets a reference to the underlying `ThisModule`.
+                /// TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+                pub const fn as_ref(&self) -> &'static ::kernel::ThisModule {{
+                    &Self::ThisModule
+                }}
+            }
+        };
+    }
+}
+
 #[cfg(not(testlib))]
 #[panic_handler]
 fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 80cb9b16f5aa..1bcd703735fe 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -371,20 +371,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
             /// Used by the printing macros, e.g. [`info!`].
             const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
 
-            // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
-            // freed until the module is unloaded.
-            #[cfg(MODULE)]
-            static THIS_MODULE: ::kernel::ThisModule = unsafe {{
-                extern \"C\" {{
-                    static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
-                }}
+            ::kernel::create_this_module!(\"{name}\");
 
-                ::kernel::ThisModule::from_ptr(__this_module.get())
-            }};
-            #[cfg(not(MODULE))]
-            static THIS_MODULE: ::kernel::ThisModule = unsafe {{
-                ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
-            }};
 
             /// The `LocalModule` type is the type of the module created by `module!`,
             /// `module_pci_driver!`, `module_platform_driver!`, etc.
@@ -502,7 +490,7 @@ mod __module_init {{
                     /// This function must only be called once.
                     unsafe fn __init() -> ::kernel::ffi::c_int {{
                         let initer =
-                            <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
+                            <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE.as_ref());
                         // SAFETY: No data race, since `__MOD` can only be accessed by this module
                         // and there only `__init` and `__exit` access it. These functions are only
                         // called once and `__exit` cannot be called before or during `__init`.
diff --git a/scripts/rustdoc_test_gen.rs b/scripts/rustdoc_test_gen.rs
index 6fd9f5c84e2e..089e38b49cdd 100644
--- a/scripts/rustdoc_test_gen.rs
+++ b/scripts/rustdoc_test_gen.rs
@@ -232,6 +232,8 @@ macro_rules! assert_eq {{
 
 const __LOG_PREFIX: &[u8] = b"rust_doctests_kernel\0";
 
+::kernel::create_this_module!("rust_doctests_kernel");
+
 {rust_tests}
 "#
     )

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 03/11] rust: miscdevice: fix use after free because missing .owner
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 02/11] rust: add new ThisModule trait and THIS_MODULE impl Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 04/11] rust: block: fix missing owner field in block_device_operations Kari Argillander
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander, Youseok Yang

Currently if miscdevice driver is compiled as module it can cause use
after free when unloading. To reproduce problem with Rust sample driver
we can do:

    tail -f /dev/rust-misc-device
    # And same time as device is open
    sudo rmmod rust_misc_device_module

This will crash system. Fix is to have .owner field filled with module
information. We pass this owner information through vtable.

Reported-by: Youseok Yang <ileixe@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1182
Fixes: f893691e7426 ("rust: miscdevice: add base miscdevice abstraction")
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 rust/kernel/miscdevice.rs        | 5 +++++
 samples/rust/rust_misc_device.rs | 1 +
 2 files changed, 6 insertions(+)

diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index ba64c8a858f0..d4b0c35c4b60 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -18,6 +18,7 @@
     mm::virt::VmaNew,
     prelude::*,
     seq_file::SeqFile,
+    this_module::ThisModule,
     types::{ForeignOwnable, Opaque},
 };
 use core::{marker::PhantomData, pin::Pin};
@@ -112,6 +113,9 @@ fn drop(self: Pin<&mut Self>) {
 /// Trait implemented by the private data of an open misc device.
 #[vtable]
 pub trait MiscDevice: Sized {
+    /// Module ownership for this device, provided via `THIS_MODULE`.
+    type ThisModule: ThisModule;
+
     /// What kind of pointer should `Self` be wrapped in.
     type Ptr: ForeignOwnable + Send + Sync;
 
@@ -388,6 +392,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
     }
 
     const VTABLE: bindings::file_operations = bindings::file_operations {
+        owner: T::ThisModule::OWNER.as_ptr(),
         open: Some(Self::open),
         release: Some(Self::release),
         mmap: if T::HAS_MMAP { Some(Self::mmap) } else { None },
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 49dd5814e1ab..464e3026e6e3 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -155,6 +155,7 @@ struct RustMiscDevice {
 
 #[vtable]
 impl MiscDevice for RustMiscDevice {
+    type ThisModule = THIS_MODULE;
     type Ptr = Pin<KBox<Self>>;
 
     fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Self>>> {

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 04/11] rust: block: fix missing owner field in block_device_operations
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (2 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 03/11] rust: miscdevice: fix use after free because missing .owner Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 05/11] rust: drm: fix missing owner in file_operations Kari Argillander
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

Kernel has now enabled "const_refs_to_static" feature. We can fix TODO
item now. Fix this by defining owner in vtable so we can read it from
there.  As this table needs to be const we need to define it in
operations so we do not need pass THIS_MODULE alongside with
GenDiskBuilder::build().

This will probably fix some use after free.

Fixes: 3253aba3408a ("rust: block: introduce `kernel::block::mq` module")
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/block/rnull/rnull.rs       |  1 +
 rust/kernel/block/mq.rs            |  1 +
 rust/kernel/block/mq/gen_disk.rs   | 30 ++++--------------------------
 rust/kernel/block/mq/operations.rs | 30 ++++++++++++++++++++++++++++++
 4 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs
index a9d5e575a2c4..862369ab9b5c 100644
--- a/drivers/block/rnull/rnull.rs
+++ b/drivers/block/rnull/rnull.rs
@@ -74,6 +74,7 @@ struct QueueData {
 
 #[vtable]
 impl Operations for NullBlkDevice {
+    type ThisModule = THIS_MODULE;
     type QueueData = KBox<QueueData>;
 
     #[inline(always)]
diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs
index 1fd0d54dd549..0c8e9e316952 100644
--- a/rust/kernel/block/mq.rs
+++ b/rust/kernel/block/mq.rs
@@ -68,6 +68,7 @@
 //!
 //! #[vtable]
 //! impl Operations for MyBlkDevice {
+//!     type ThisModule = THIS_MODULE;
 //!     type QueueData = ();
 //!
 //!     fn queue_rq(_queue_data: (), rq: ARef<Request<Self>>, _is_last: bool) -> Result {
diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_disk.rs
index 1ce815c8cdab..4d5d378577ec 100644
--- a/rust/kernel/block/mq/gen_disk.rs
+++ b/rust/kernel/block/mq/gen_disk.rs
@@ -7,7 +7,7 @@
 
 use crate::{
     bindings,
-    block::mq::{Operations, TagSet},
+    block::mq::{operations::OperationsVTable, Operations, TagSet},
     error::{self, from_err_ptr, Result},
     fmt::{self, Write},
     prelude::*,
@@ -126,32 +126,10 @@ pub fn build<T: Operations>(
             )
         })?;
 
-        const TABLE: bindings::block_device_operations = bindings::block_device_operations {
-            submit_bio: None,
-            open: None,
-            release: None,
-            ioctl: None,
-            compat_ioctl: None,
-            check_events: None,
-            unlock_native_capacity: None,
-            getgeo: None,
-            set_read_only: None,
-            swap_slot_free_notify: None,
-            report_zones: None,
-            devnode: None,
-            alternative_gpt_sector: None,
-            get_unique_id: None,
-            // TODO: Set to THIS_MODULE. Waiting for const_refs_to_static feature to
-            // be merged (unstable in rustc 1.78 which is staged for linux 6.10)
-            // <https://github.com/rust-lang/rust/issues/119618>
-            owner: core::ptr::null_mut(),
-            pr_ops: core::ptr::null_mut(),
-            free_disk: None,
-            poll_bio: None,
-        };
-
         // SAFETY: `gendisk` is a valid pointer as we initialized it above
-        unsafe { (*gendisk).fops = &TABLE };
+        unsafe {
+            (*gendisk).fops = OperationsVTable::<T>::build_block_device_operations();
+        }
 
         let mut writer = NullTerminatedFormatter::new(
             // SAFETY: `gendisk` points to a valid and initialized instance. We
diff --git a/rust/kernel/block/mq/operations.rs b/rust/kernel/block/mq/operations.rs
index 8ad46129a52c..0f8f616590fb 100644
--- a/rust/kernel/block/mq/operations.rs
+++ b/rust/kernel/block/mq/operations.rs
@@ -10,6 +10,7 @@
     error::{from_result, Result},
     prelude::*,
     sync::{aref::ARef, Refcount},
+    this_module::ThisModule,
     types::ForeignOwnable,
 };
 use core::marker::PhantomData;
@@ -28,6 +29,9 @@
 /// [module level documentation]: kernel::block::mq
 #[macros::vtable]
 pub trait Operations: Sized {
+    /// Module ownership for this device, provided via `THIS_MODULE`.
+    type ThisModule: ThisModule;
+
     /// Data associated with the `struct request_queue` that is allocated for
     /// the `GenDisk` associated with this `Operations` implementation.
     type QueueData: ForeignOwnable;
@@ -280,7 +284,33 @@ impl<T: Operations> OperationsVTable<T> {
         show_rq: None,
     };
 
+    const BLOCK_OPS: bindings::block_device_operations = bindings::block_device_operations {
+        submit_bio: None,
+        open: None,
+        release: None,
+        ioctl: None,
+        compat_ioctl: None,
+        check_events: None,
+        unlock_native_capacity: None,
+        getgeo: None,
+        set_read_only: None,
+        swap_slot_free_notify: None,
+        report_zones: None,
+        devnode: None,
+        alternative_gpt_sector: None,
+        get_unique_id: None,
+        owner: T::ThisModule::OWNER.as_ptr(),
+        pr_ops: core::ptr::null_mut(),
+        free_disk: None,
+        poll_bio: None,
+    };
+
     pub(crate) const fn build() -> &'static bindings::blk_mq_ops {
         &Self::VTABLE
     }
+
+    pub(crate) const fn build_block_device_operations() -> &'static bindings::block_device_operations
+    {
+        &Self::BLOCK_OPS
+    }
 }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 05/11] rust: drm: fix missing owner in file_operations
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (3 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 04/11] rust: block: fix missing owner field in block_device_operations Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 06/11] rust: driver: make RegistrationOps::register() to use new ThisModule Kari Argillander
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

Fix missing .owner field in file_operations. This has been previosly
left out because Rust feature `const_refs_to_static` has not been
enabled. Now that it is we can make define owner even in const context.

This should probably fix use-after-free problems in situations where
file is opened and module driver is unloaded during that.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/gpu/drm/nova/driver.rs | 2 ++
 drivers/gpu/drm/tyr/driver.rs  | 2 ++
 rust/kernel/drm/device.rs      | 2 +-
 rust/kernel/drm/driver.rs      | 4 ++++
 rust/kernel/drm/gem/mod.rs     | 5 +++--
 5 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index b1af0a099551..7ce505802716 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -14,6 +14,7 @@
 
 use crate::file::File;
 use crate::gem::NovaObject;
+use crate::THIS_MODULE;
 
 pub(crate) struct NovaDriver {
     #[expect(unused)]
@@ -65,6 +66,7 @@ fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<S
 
 #[vtable]
 impl drm::Driver for NovaDriver {
+    type ThisModule = THIS_MODULE;
     type Data = NovaData;
     type File = File;
     type Object = gem::Object<NovaObject>;
diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index f0da58932702..11932d3f03ff 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -25,6 +25,7 @@
 use crate::gpu;
 use crate::gpu::GpuInfo;
 use crate::regs;
+use crate::THIS_MODULE;
 
 pub(crate) type IoMem = kernel::io::mem::IoMem<SZ_2M>;
 
@@ -179,6 +180,7 @@ fn drop(self: Pin<&mut Self>) {
 
 #[vtable]
 impl drm::Driver for TyrDriver {
+    type ThisModule = THIS_MODULE;
     type Data = TyrData;
     type File = File;
     type Object = drm::gem::Object<TyrObject>;
diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 3ce8f62a0056..a740c87933d0 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -92,7 +92,7 @@ impl<T: drm::Driver> Device<T> {
         fops: &Self::GEM_FOPS,
     };
 
-    const GEM_FOPS: bindings::file_operations = drm::gem::create_fops();
+    const GEM_FOPS: bindings::file_operations = drm::gem::create_fops::<T::ThisModule>();
 
     /// Create a new `drm::Device` for a `drm::Driver`.
     pub fn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> {
diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
index f30ee4c6245c..a157db2ea02b 100644
--- a/rust/kernel/drm/driver.rs
+++ b/rust/kernel/drm/driver.rs
@@ -9,6 +9,7 @@
     error::{to_result, Result},
     prelude::*,
     sync::aref::ARef,
+    this_module::ThisModule,
 };
 use macros::vtable;
 
@@ -99,6 +100,9 @@ pub trait AllocImpl: super::private::Sealed + drm::gem::IntoGEMObject {
 /// drm_driver` to be registered in the DRM subsystem.
 #[vtable]
 pub trait Driver {
+    /// Module ownership for this device, provided via `THIS_MODULE`.
+    type ThisModule: ThisModule;
+
     /// Context data associated with the DRM driver
     type Data: Sync + Send;
 
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index bdaac839dacc..9980cebec96b 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -11,6 +11,7 @@
     error::{to_result, Result},
     prelude::*,
     sync::aref::{ARef, AlwaysRefCounted},
+    this_module::ThisModule,
     types::Opaque,
 };
 use core::{ops::Deref, ptr::NonNull};
@@ -292,10 +293,10 @@ impl<T: DriverObject> AllocImpl for Object<T> {
     };
 }
 
-pub(super) const fn create_fops() -> bindings::file_operations {
+pub(super) const fn create_fops<M: ThisModule>() -> bindings::file_operations {
     let mut fops: bindings::file_operations = pin_init::zeroed();
 
-    fops.owner = core::ptr::null_mut();
+    fops.owner = M::OWNER.as_ptr();
     fops.open = Some(bindings::drm_open);
     fops.release = Some(bindings::drm_release);
     fops.unlocked_ioctl = Some(bindings::drm_ioctl);

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 06/11] rust: driver: make RegistrationOps::register() to use new ThisModule
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (4 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 05/11] rust: drm: fix missing owner in file_operations Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 07/11] rust: phy: make Registration::register() " Kari Argillander
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

New version of ThisModule is trait which can be passed in const context.
To have unified way to pass THIS_MODULE to abstactions have const
parameter which can be used to get owner and name.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 rust/kernel/auxiliary.rs              | 16 ++++++++--------
 rust/kernel/driver.rs                 | 29 +++++++++++++----------------
 rust/kernel/i2c.rs                    | 11 ++++-------
 rust/kernel/pci.rs                    | 15 +++++----------
 rust/kernel/platform.rs               | 12 ++++--------
 rust/kernel/usb.rs                    | 13 ++++---------
 samples/rust/rust_driver_auxiliary.rs |  6 +++---
 7 files changed, 41 insertions(+), 61 deletions(-)

diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index 56f3c180e8f6..102b0349af16 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -11,8 +11,8 @@
     driver,
     error::{from_result, to_result, Result},
     prelude::*,
+    this_module::ThisModule,
     types::Opaque,
-    ThisModule,
 };
 use core::{
     marker::PhantomData,
@@ -28,14 +28,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::auxiliary_driver;
 
-    unsafe fn register(
-        adrv: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result {
+    unsafe fn register<TM: ThisModule>(adrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct auxiliary_driver` on initialization.
         unsafe {
-            (*adrv.get()).name = name.as_char_ptr();
+            (*adrv.get()).name = TM::NAME.as_char_ptr();
             (*adrv.get()).probe = Some(Self::probe_callback);
             (*adrv.get()).remove = Some(Self::remove_callback);
             (*adrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -43,7 +39,11 @@ unsafe fn register(
 
         // SAFETY: `adrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr())
+            bindings::__auxiliary_driver_register(
+                adrv.get(),
+                TM::OWNER.as_ptr(),
+                TM::NAME.as_char_ptr(),
+            )
         })
     }
 
diff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs
index 649d06468f41..dc7522c4ebda 100644
--- a/rust/kernel/driver.rs
+++ b/rust/kernel/driver.rs
@@ -94,10 +94,14 @@
 //! [`device_id`]: kernel::device_id
 //! [`module_driver`]: kernel::module_driver
 
-use crate::error::{Error, Result};
-use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule};
-use core::pin::Pin;
-use pin_init::{pin_data, pinned_drop, PinInit};
+use crate::{
+    acpi,
+    device,
+    of,
+    prelude::*,
+    this_module::ThisModule,
+    types::Opaque, //
+};
 
 /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform,
 /// Amba, etc.) to provide the corresponding subsystem specific implementation to register /
@@ -122,11 +126,7 @@ pub unsafe trait RegistrationOps {
     ///
     /// On success, `reg` must remain pinned and valid until the matching call to
     /// [`RegistrationOps::unregister`].
-    unsafe fn register(
-        reg: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result;
+    unsafe fn register<TM: ThisModule>(reg: &Opaque<Self::RegType>) -> Result;
 
     /// Unregisters a driver previously registered with [`RegistrationOps::register`].
     ///
@@ -159,7 +159,7 @@ unsafe impl<T: RegistrationOps> Send for Registration<T> {}
 
 impl<T: RegistrationOps> Registration<T> {
     /// Creates a new instance of the registration object.
-    pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Self, Error> {
+    pub fn new<TM: ThisModule>() -> impl PinInit<Self, Error> {
         try_pin_init!(Self {
             reg <- Opaque::try_ffi_init(|ptr: *mut T::RegType| {
                 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write.
@@ -170,7 +170,7 @@ pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Sel
                 let drv = unsafe { &*(ptr as *const Opaque<T::RegType>) };
 
                 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`.
-                unsafe { T::register(drv, name, module) }
+                unsafe { T::register::<TM>(drv) }
             }),
         })
     }
@@ -202,13 +202,10 @@ struct DriverModule {
 
         impl $crate::InPlaceModule for DriverModule {
             fn init(
-                module: &'static $crate::ThisModule
+                _module: &'static $crate::ThisModule
             ) -> impl ::pin_init::PinInit<Self, $crate::error::Error> {
                 $crate::try_pin_init!(Self {
-                    _driver <- $crate::driver::Registration::new(
-                        <Self as $crate::ModuleMetadata>::NAME,
-                        module,
-                    ),
+                    _driver <- $crate::driver::Registration::new::<crate::THIS_MODULE>(),
                 })
             }
         }
diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs
index 491e6cc25cf4..b23a26a445cd 100644
--- a/rust/kernel/i2c.rs
+++ b/rust/kernel/i2c.rs
@@ -16,6 +16,7 @@
     error::*,
     of,
     prelude::*,
+    this_module::ThisModule,
     types::{
         AlwaysRefCounted,
         Opaque, //
@@ -97,11 +98,7 @@ macro_rules! i2c_device_table {
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::i2c_driver;
 
-    unsafe fn register(
-        idrv: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result {
+    unsafe fn register<TM: ThisModule>(idrv: &Opaque<Self::RegType>) -> Result {
         build_assert!(
             T::ACPI_ID_TABLE.is_some() || T::OF_ID_TABLE.is_some() || T::I2C_ID_TABLE.is_some(),
             "At least one of ACPI/OF/Legacy tables must be present when registering an i2c driver"
@@ -124,7 +121,7 @@ unsafe fn register(
 
         // SAFETY: It's safe to set the fields of `struct i2c_client` on initialization.
         unsafe {
-            (*idrv.get()).driver.name = name.as_char_ptr();
+            (*idrv.get()).driver.name = TM::NAME.as_char_ptr();
             (*idrv.get()).probe = Some(Self::probe_callback);
             (*idrv.get()).remove = Some(Self::remove_callback);
             (*idrv.get()).shutdown = Some(Self::shutdown_callback);
@@ -134,7 +131,7 @@ unsafe fn register(
         }
 
         // SAFETY: `idrv` is guaranteed to be a valid `RegType`.
-        to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) })
+        to_result(unsafe { bindings::i2c_register_driver(TM::OWNER.as_ptr(), idrv.get()) })
     }
 
     unsafe fn unregister(idrv: &Opaque<Self::RegType>) {
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 82e128431f08..88a5416fb44b 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -18,9 +18,8 @@
         to_result, //
     },
     prelude::*,
-    str::CStr,
-    types::Opaque,
-    ThisModule, //
+    this_module::ThisModule,
+    types::Opaque, //
 };
 use core::{
     marker::PhantomData,
@@ -55,14 +54,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::pci_driver;
 
-    unsafe fn register(
-        pdrv: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result {
+    unsafe fn register<TM: ThisModule>(pdrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct pci_driver` on initialization.
         unsafe {
-            (*pdrv.get()).name = name.as_char_ptr();
+            (*pdrv.get()).name = TM::NAME.as_char_ptr();
             (*pdrv.get()).probe = Some(Self::probe_callback);
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -70,7 +65,7 @@ unsafe fn register(
 
         // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::__pci_register_driver(pdrv.get(), module.0, name.as_char_ptr())
+            bindings::__pci_register_driver(pdrv.get(), TM::OWNER.as_ptr(), TM::NAME.as_char_ptr())
         })
     }
 
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index bddb593cee7b..a4678af3b891 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -13,8 +13,8 @@
     irq::{self, IrqRequest},
     of,
     prelude::*,
+    this_module::ThisModule,
     types::Opaque,
-    ThisModule,
 };
 
 use core::{
@@ -31,11 +31,7 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::platform_driver;
 
-    unsafe fn register(
-        pdrv: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result {
+    unsafe fn register<TM: ThisModule>(pdrv: &Opaque<Self::RegType>) -> Result {
         let of_table = match T::OF_ID_TABLE {
             Some(table) => table.as_ptr(),
             None => core::ptr::null(),
@@ -48,7 +44,7 @@ unsafe fn register(
 
         // SAFETY: It's safe to set the fields of `struct platform_driver` on initialization.
         unsafe {
-            (*pdrv.get()).driver.name = name.as_char_ptr();
+            (*pdrv.get()).driver.name = TM::NAME.as_char_ptr();
             (*pdrv.get()).probe = Some(Self::probe_callback);
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).driver.of_match_table = of_table;
@@ -56,7 +52,7 @@ unsafe fn register(
         }
 
         // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
-        to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) })
+        to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), TM::OWNER.as_ptr()) })
     }
 
     unsafe fn unregister(pdrv: &Opaque<Self::RegType>) {
diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs
index d10b65e9fb6a..e7e07360f953 100644
--- a/rust/kernel/usb.rs
+++ b/rust/kernel/usb.rs
@@ -11,9 +11,8 @@
     driver,
     error::{from_result, to_result, Result},
     prelude::*,
-    str::CStr,
+    this_module::ThisModule,
     types::{AlwaysRefCounted, Opaque},
-    ThisModule,
 };
 use core::{
     marker::PhantomData,
@@ -32,14 +31,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::usb_driver;
 
-    unsafe fn register(
-        udrv: &Opaque<Self::RegType>,
-        name: &'static CStr,
-        module: &'static ThisModule,
-    ) -> Result {
+    unsafe fn register<TM: ThisModule>(udrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct usb_driver` on initialization.
         unsafe {
-            (*udrv.get()).name = name.as_char_ptr();
+            (*udrv.get()).name = TM::NAME.as_char_ptr();
             (*udrv.get()).probe = Some(Self::probe_callback);
             (*udrv.get()).disconnect = Some(Self::disconnect_callback);
             (*udrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -47,7 +42,7 @@ unsafe fn register(
 
         // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr())
+            bindings::usb_register_driver(udrv.get(), TM::OWNER.as_ptr(), TM::NAME.as_char_ptr())
         })
     }
 
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 1e4fb23cfcb0..28a25e540298 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -111,10 +111,10 @@ struct SampleModule {
 }
 
 impl InPlaceModule for SampleModule {
-    fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
+    fn init(_module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
         try_pin_init!(Self {
-            _pci_driver <- driver::Registration::new(MODULE_NAME, module),
-            _aux_driver <- driver::Registration::new(MODULE_NAME, module),
+            _pci_driver <- driver::Registration::new::<THIS_MODULE>(),
+            _aux_driver <- driver::Registration::new::<THIS_MODULE>(),
         })
     }
 }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 07/11] rust: phy: make Registration::register() use new ThisModule
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (5 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 06/11] rust: driver: make RegistrationOps::register() to use new ThisModule Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 08/11] rust: binder: use new THIS_MODULE Kari Argillander
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

Switch `Registration::register()` to take the owning module via the
`ThisModule` abstraction instead of an explicit module parameter.

The function is now generic over `TM: ThisModule`, allowing the module
owner to be resolved at compile time through `TM::OWNER`. This unifies
the way `THIS_MODULE` is passed to Rust abstractions and avoids
threading module pointers manually through the API.

This also removes redundant parameters and prevents accidental
mismatches between the registered drivers and their owning module.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 rust/kernel/net/phy.rs | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index bf6272d87a7b..b6c99bf7e97b 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -6,8 +6,17 @@
 //!
 //! C headers: [`include/linux/phy.h`](srctree/include/linux/phy.h).
 
-use crate::{device_id::RawDeviceId, error::*, prelude::*, types::Opaque};
-use core::{marker::PhantomData, ptr::addr_of_mut};
+use crate::{
+    device_id::RawDeviceId,
+    error::*,
+    prelude::*,
+    this_module::ThisModule,
+    types::Opaque, //
+};
+use core::{
+    marker::PhantomData,
+    ptr::addr_of_mut, //
+};
 
 pub mod reg;
 
@@ -648,10 +657,7 @@ unsafe impl Send for Registration {}
 
 impl Registration {
     /// Registers a PHY driver.
-    pub fn register(
-        module: &'static crate::ThisModule,
-        drivers: Pin<&'static mut [DriverVTable]>,
-    ) -> Result<Self> {
+    pub fn register<TM: ThisModule>(drivers: Pin<&'static mut [DriverVTable]>) -> Result<Self> {
         if drivers.is_empty() {
             return Err(code::EINVAL);
         }
@@ -659,7 +665,11 @@ pub fn register(
         // the `drivers` slice are initialized properly. `drivers` will not be moved.
         // So it's just an FFI call.
         to_result(unsafe {
-            bindings::phy_drivers_register(drivers[0].0.get(), drivers.len().try_into()?, module.0)
+            bindings::phy_drivers_register(
+                drivers[0].0.get(),
+                drivers.len().try_into()?,
+                TM::OWNER.as_ptr(),
+            )
         })?;
         // INVARIANT: The `drivers` slice is successfully registered to the kernel via `phy_drivers_register`.
         Ok(Registration { drivers })
@@ -891,12 +901,11 @@ struct Module {
                 [$($crate::net::phy::create_phy_driver::<$driver>()),+];
 
             impl $crate::Module for Module {
-                fn init(module: &'static $crate::ThisModule) -> Result<Self> {
+                fn init(_module: &'static $crate::ThisModule) -> Result<Self> {
                     // SAFETY: The anonymous constant guarantees that nobody else can access
                     // the `DRIVERS` static. The array is used only in the C side.
                     let drivers = unsafe { &mut DRIVERS };
-                    let mut reg = $crate::net::phy::Registration::register(
-                        module,
+                    let mut reg = $crate::net::phy::Registration::register::<crate::THIS_MODULE>(
                         ::core::pin::Pin::static_mut(drivers),
                     )?;
                     Ok(Module { _reg: reg })

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 08/11] rust: binder: use new THIS_MODULE
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (6 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 07/11] rust: phy: make Registration::register() " Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 09/11] rust: remove module argument from InPlaceModule::init() Kari Argillander
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

We have new THIS_MODULE. ThisModule is now crate. This is ugly for
reason that drivers should not use as_ptr() directly. Currently binder
still needs it so ugly cast is totally ok.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/android/binder/rust_binder_main.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index d84c3c360be0..fc921c0e1116 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -21,6 +21,7 @@
     sync::poll::PollTable,
     sync::Arc,
     task::Pid,
+    this_module::ThisModule,
     transmute::AsBytes,
     types::ForeignOwnable,
     uaccess::UserSliceWriter,
@@ -319,7 +320,7 @@ unsafe impl<T> Sync for AssertSync<T> {}
     let zeroed_ops = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
 
     let ops = kernel::bindings::file_operations {
-        owner: THIS_MODULE.as_ptr(),
+        owner: <THIS_MODULE as ThisModule>::OWNER.as_ptr(),
         poll: Some(rust_binder_poll),
         unlocked_ioctl: Some(rust_binder_ioctl),
         #[cfg(CONFIG_COMPAT)]

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 09/11] rust: remove module argument from InPlaceModule::init()
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (7 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 08/11] rust: binder: use new THIS_MODULE Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 10/11] rust: remove kernel::ModuleMetadata Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 11/11] rust: remove old version of ThisModule Kari Argillander
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander, Yuheng Su

InPlaceModule::init() has ThisModule argument. However modules always
have THIS_MODULE made by module! macro. So it is unnecessary to pass
same information through this function. End goal is to make idea of
THIS_MODULE simpler. Driver getting this THIS_MODULE from multiple
places is confusing. So let's just stick with THIS_MODULE as that also
works in const context very easily.

Reported-by: Yuheng Su <gipsyh.icu@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/720
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/android/binder/rust_binder_main.rs | 2 +-
 drivers/block/rnull/rnull.rs               | 2 +-
 lib/find_bit_benchmark_rust.rs             | 3 +--
 rust/kernel/configfs.rs                    | 3 +--
 rust/kernel/driver.rs                      | 4 +---
 rust/kernel/firmware.rs                    | 2 +-
 rust/kernel/lib.rs                         | 8 ++++----
 rust/kernel/net/phy.rs                     | 2 +-
 rust/kernel/sync/lock/global.rs            | 4 ++--
 rust/macros/lib.rs                         | 4 ++--
 rust/macros/module.rs                      | 2 +-
 samples/rust/rust_configfs.rs              | 2 +-
 samples/rust/rust_debugfs_scoped.rs        | 2 +-
 samples/rust/rust_driver_auxiliary.rs      | 2 +-
 samples/rust/rust_driver_faux.rs           | 2 +-
 samples/rust/rust_minimal.rs               | 2 +-
 samples/rust/rust_misc_device.rs           | 2 +-
 samples/rust/rust_print_main.rs            | 2 +-
 18 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index fc921c0e1116..8b865112e60c 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -291,7 +291,7 @@ fn ptr_align(value: usize) -> Option<usize> {
 struct BinderModule {}
 
 impl kernel::Module for BinderModule {
-    fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         // SAFETY: The module initializer never runs twice, so we only call this once.
         unsafe { crate::context::CONTEXTS.init() };
 
diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs
index 862369ab9b5c..a9be1b2187f4 100644
--- a/drivers/block/rnull/rnull.rs
+++ b/drivers/block/rnull/rnull.rs
@@ -36,7 +36,7 @@ struct NullBlkModule {
 }
 
 impl kernel::InPlaceModule for NullBlkModule {
-    fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
+    fn init() -> impl PinInit<Self, Error> {
         pr_info!("Rust null_blk loaded\n");
 
         try_pin_init!(Self {
diff --git a/lib/find_bit_benchmark_rust.rs b/lib/find_bit_benchmark_rust.rs
index 6bdc51de2f30..5c231569d887 100644
--- a/lib/find_bit_benchmark_rust.rs
+++ b/lib/find_bit_benchmark_rust.rs
@@ -7,7 +7,6 @@
 use kernel::error::{code, Result};
 use kernel::prelude::module;
 use kernel::time::{Instant, Monotonic};
-use kernel::ThisModule;
 use kernel::{pr_cont, pr_err};
 
 const BITMAP_LEN: usize = 4096 * 8 * 10;
@@ -88,7 +87,7 @@ fn find_bit_test() {
 }
 
 impl kernel::Module for Benchmark {
-    fn init(_module: &'static ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         find_bit_test();
         // Return error so test module can be inserted again without rmmod.
         Err(code::EINVAL)
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 908cb98d404f..2af63f7daef2 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -27,7 +27,6 @@
 //! use kernel::new_mutex;
 //! use kernel::page::PAGE_SIZE;
 //! use kernel::sync::Mutex;
-//! use kernel::ThisModule;
 //!
 //! #[pin_data]
 //! struct RustConfigfs {
@@ -36,7 +35,7 @@
 //! }
 //!
 //! impl kernel::InPlaceModule for RustConfigfs {
-//!     fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
+//!     fn init() -> impl PinInit<Self, Error> {
 //!         pr_info!("Rust configfs sample (init)\n");
 //!
 //!         let item_type = configfs_attrs! {
diff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs
index dc7522c4ebda..de77f95d7fe0 100644
--- a/rust/kernel/driver.rs
+++ b/rust/kernel/driver.rs
@@ -201,9 +201,7 @@ struct DriverModule {
         }
 
         impl $crate::InPlaceModule for DriverModule {
-            fn init(
-                _module: &'static $crate::ThisModule
-            ) -> impl ::pin_init::PinInit<Self, $crate::error::Error> {
+            fn init() -> impl ::pin_init::PinInit<Self, $crate::error::Error> {
                 $crate::try_pin_init!(Self {
                     _driver <- $crate::driver::Registration::new::<crate::THIS_MODULE>(),
                 })
diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
index 71168d8004e2..11372a8f7be4 100644
--- a/rust/kernel/firmware.rs
+++ b/rust/kernel/firmware.rs
@@ -157,7 +157,7 @@ unsafe impl Sync for Firmware {}
 /// # struct MyModule;
 /// #
 /// # impl kernel::Module for MyModule {
-/// #     fn init(_module: &'static ThisModule) -> Result<Self> {
+/// #     fn init() -> Result<Self> {
 /// #         Ok(Self)
 /// #     }
 /// # }
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 2ccd75f68f03..e7bc52a6ad42 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -175,7 +175,7 @@ pub trait Module: Sized + Sync + Send {
     /// should do.
     ///
     /// Equivalent to the `module_init` macro in the C API.
-    fn init(module: &'static ThisModule) -> error::Result<Self>;
+    fn init() -> error::Result<Self>;
 }
 
 /// A module that is pinned and initialised in-place.
@@ -183,13 +183,13 @@ pub trait InPlaceModule: Sync + Send {
     /// Creates an initialiser for the module.
     ///
     /// It is called when the module is loaded.
-    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>;
+    fn init() -> impl pin_init::PinInit<Self, error::Error>;
 }
 
 impl<T: Module> InPlaceModule for T {
-    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error> {
+    fn init() -> impl pin_init::PinInit<Self, error::Error> {
         let initer = move |slot: *mut Self| {
-            let m = <Self as Module>::init(module)?;
+            let m = <Self as Module>::init()?;
 
             // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
             unsafe { slot.write(m) };
diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index b6c99bf7e97b..7d467d42e951 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -901,7 +901,7 @@ struct Module {
                 [$($crate::net::phy::create_phy_driver::<$driver>()),+];
 
             impl $crate::Module for Module {
-                fn init(_module: &'static $crate::ThisModule) -> Result<Self> {
+                fn init() -> Result<Self> {
                     // SAFETY: The anonymous constant guarantees that nobody else can access
                     // the `DRIVERS` static. The array is used only in the C side.
                     let drivers = unsafe { &mut DRIVERS };
diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
index eab48108a4ae..7fde464462d1 100644
--- a/rust/kernel/sync/lock/global.rs
+++ b/rust/kernel/sync/lock/global.rs
@@ -203,7 +203,7 @@ pub fn get_mut(&mut self) -> &mut T {
 /// }
 ///
 /// impl kernel::Module for MyModule {
-///     fn init(_module: &'static ThisModule) -> Result<Self> {
+///     fn init() -> Result<Self> {
 ///         // SAFETY: Called exactly once.
 ///         unsafe { MY_COUNTER.init() };
 ///
@@ -243,7 +243,7 @@ pub fn get_mut(&mut self) -> &mut T {
 /// }
 ///
 /// impl kernel::Module for MyModule {
-///     fn init(_module: &'static ThisModule) -> Result<Self> {
+///     fn init() -> Result<Self> {
 ///         // SAFETY: Called exactly once.
 ///         unsafe { MY_MUTEX.init() };
 ///
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index b38002151871..d22a93696209 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -80,7 +80,7 @@
 /// struct MyModule(i32);
 ///
 /// impl kernel::Module for MyModule {
-///     fn init(_module: &'static ThisModule) -> Result<Self> {
+///     fn init() -> Result<Self> {
 ///         let foo: i32 = 42;
 ///         pr_info!("I contain:  {}\n", foo);
 ///         pr_info!("i32 param is:  {}\n", module_parameters::my_parameter.read());
@@ -114,7 +114,7 @@
 /// struct MyDeviceDriverModule;
 ///
 /// impl kernel::Module for MyDeviceDriverModule {
-///     fn init(_module: &'static ThisModule) -> Result<Self> {
+///     fn init() -> Result<Self> {
 ///         Ok(Self)
 ///     }
 /// }
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 1bcd703735fe..7473a377a3bd 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -490,7 +490,7 @@ mod __module_init {{
                     /// This function must only be called once.
                     unsafe fn __init() -> ::kernel::ffi::c_int {{
                         let initer =
-                            <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE.as_ref());
+                            <{type_} as ::kernel::InPlaceModule>::init();
                         // SAFETY: No data race, since `__MOD` can only be accessed by this module
                         // and there only `__init` and `__exit` access it. These functions are only
                         // called once and `__exit` cannot be called before or during `__init`.
diff --git a/samples/rust/rust_configfs.rs b/samples/rust/rust_configfs.rs
index 0ccc7553ef39..f34260793677 100644
--- a/samples/rust/rust_configfs.rs
+++ b/samples/rust/rust_configfs.rs
@@ -42,7 +42,7 @@ fn new() -> impl PinInit<Self, Error> {
 }
 
 impl kernel::InPlaceModule for RustConfigfs {
-    fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
+    fn init() -> impl PinInit<Self, Error> {
         pr_info!("Rust configfs sample (init)\n");
 
         // Define a subsystem with the data type `Configuration`, two
diff --git a/samples/rust/rust_debugfs_scoped.rs b/samples/rust/rust_debugfs_scoped.rs
index 6a575a15a2c2..75897e02766b 100644
--- a/samples/rust/rust_debugfs_scoped.rs
+++ b/samples/rust/rust_debugfs_scoped.rs
@@ -134,7 +134,7 @@ fn init_control(base_dir: &Dir, dyn_dirs: Dir) -> impl PinInit<Scope<ModuleData>
 }
 
 impl kernel::Module for RustScopedDebugFs {
-    fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         let base_dir = Dir::new(c"rust_scoped_debugfs");
         let dyn_dirs = base_dir.subdir(c"dynamic");
         Ok(Self {
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 28a25e540298..7b729687811d 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -111,7 +111,7 @@ struct SampleModule {
 }
 
 impl InPlaceModule for SampleModule {
-    fn init(_module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
+    fn init() -> impl PinInit<Self, Error> {
         try_pin_init!(Self {
             _pci_driver <- driver::Registration::new::<THIS_MODULE>(),
             _aux_driver <- driver::Registration::new::<THIS_MODULE>(),
diff --git a/samples/rust/rust_driver_faux.rs b/samples/rust/rust_driver_faux.rs
index 5330b77ea986..2653b2ec3338 100644
--- a/samples/rust/rust_driver_faux.rs
+++ b/samples/rust/rust_driver_faux.rs
@@ -21,7 +21,7 @@ struct SampleModule {
 }
 
 impl Module for SampleModule {
-    fn init(_module: &'static ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         pr_info!("Initialising Rust Faux Device Sample\n");
 
         let reg = faux::Registration::new(c"rust-faux-sample-device", None)?;
diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs
index 8eb9583571d7..c024f8083499 100644
--- a/samples/rust/rust_minimal.rs
+++ b/samples/rust/rust_minimal.rs
@@ -23,7 +23,7 @@ struct RustMinimal {
 }
 
 impl kernel::Module for RustMinimal {
-    fn init(_module: &'static ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         pr_info!("Rust minimal sample (init)\n");
         pr_info!("Am I built-in? {}\n", !cfg!(MODULE));
         pr_info!(
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 464e3026e6e3..709adf4a6026 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -128,7 +128,7 @@ struct RustMiscDeviceModule {
 }
 
 impl kernel::InPlaceModule for RustMiscDeviceModule {
-    fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
+    fn init() -> impl PinInit<Self, Error> {
         pr_info!("Initialising Rust Misc Device Sample\n");
 
         let options = MiscDeviceOptions {
diff --git a/samples/rust/rust_print_main.rs b/samples/rust/rust_print_main.rs
index 4095c72afeab..de1bf7b80153 100644
--- a/samples/rust/rust_print_main.rs
+++ b/samples/rust/rust_print_main.rs
@@ -59,7 +59,7 @@ fn arc_dyn_print(arc: &Arc<dyn Display>) {
 }
 
 impl kernel::Module for RustPrint {
-    fn init(_module: &'static ThisModule) -> Result<Self> {
+    fn init() -> Result<Self> {
         pr_info!("Rust printing macros sample (init)\n");
 
         pr_emerg!("Emergency message (level 0) without args\n");

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 10/11] rust: remove kernel::ModuleMetadata
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (8 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 09/11] rust: remove module argument from InPlaceModule::init() Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  2026-01-06 16:11 ` [PATCH RFC v2 11/11] rust: remove old version of ThisModule Kari Argillander
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

We have all information available also in THIS_MODULE. Use that instead.
This way we do not need to do ugly casts from driver struct.

Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 drivers/gpu/nova-core/nova_core.rs    | 2 +-
 rust/kernel/firmware.rs               | 2 +-
 rust/kernel/lib.rs                    | 6 ------
 rust/macros/module.rs                 | 8 --------
 samples/rust/rust_driver_auxiliary.rs | 2 +-
 5 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index b98a1c03f13d..fbfbcc9446c0 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -19,7 +19,7 @@
 mod util;
 mod vbios;
 
-pub(crate) const MODULE_NAME: &kernel::str::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+pub(crate) const MODULE_NAME: &kernel::str::CStr = THIS_MODULE::name();
 
 kernel::module_pci_driver! {
     type: driver::NovaCore,
diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
index 11372a8f7be4..42bae71f6af1 100644
--- a/rust/kernel/firmware.rs
+++ b/rust/kernel/firmware.rs
@@ -206,7 +206,7 @@ macro_rules! module_firmware {
             const __MODULE_FIRMWARE_PREFIX: &'static $crate::str::CStr = if cfg!(MODULE) {
                 c""
             } else {
-                <LocalModule as $crate::ModuleMetadata>::NAME
+                crate::THIS_MODULE::name()
             };
 
             #[link_section = ".modinfo"]
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index e7bc52a6ad42..dec1d05ebe7b 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -201,12 +201,6 @@ fn init() -> impl pin_init::PinInit<Self, error::Error> {
     }
 }
 
-/// Metadata attached to a [`Module`] or [`InPlaceModule`].
-pub trait ModuleMetadata {
-    /// The name of the module as specified in the `module!` macro.
-    const NAME: &'static crate::str::CStr;
-}
-
 /// Equivalent to `THIS_MODULE` in the C API.
 ///
 /// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 7473a377a3bd..97635aed1598 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -374,14 +374,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
             ::kernel::create_this_module!(\"{name}\");
 
 
-            /// The `LocalModule` type is the type of the module created by `module!`,
-            /// `module_pci_driver!`, `module_platform_driver!`, etc.
-            type LocalModule = {type_};
-
-            impl ::kernel::ModuleMetadata for {type_} {{
-                const NAME: &'static ::kernel::str::CStr = c\"{name}\";
-            }}
-
             // Double nested modules, since then nobody can access the public items inside.
             mod __module_init {{
                 mod __module_init {{
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 7b729687811d..528866b953aa 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -18,7 +18,7 @@
 use core::any::TypeId;
 use pin_init::PinInit;
 
-const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+const MODULE_NAME: &CStr = THIS_MODULE::name();
 const AUXILIARY_NAME: &CStr = c"auxiliary";
 
 struct AuxiliaryDriver;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v2 11/11] rust: remove old version of ThisModule
  2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
                   ` (9 preceding siblings ...)
  2026-01-06 16:11 ` [PATCH RFC v2 10/11] rust: remove kernel::ModuleMetadata Kari Argillander
@ 2026-01-06 16:11 ` Kari Argillander
  10 siblings, 0 replies; 12+ messages in thread
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Alexandre Courbot
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Kari Argillander

There are now users anymore which use old ThisModule. Also new
ThisModule did have couple quirks which where there only to probide
fucntionality what old ThisModule provided. Those also are not needed
anymore.

Closes: https://github.com/Rust-for-Linux/linux/issues/212
Closes: https://github.com/Rust-for-Linux/linux/issues/1176
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
 rust/kernel/lib.rs     | 47 -----------------------------------------------
 rust/kernel/prelude.rs |  2 +-
 2 files changed, 1 insertion(+), 48 deletions(-)

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index dec1d05ebe7b..e709f85ec4b5 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -201,32 +201,6 @@ fn init() -> impl pin_init::PinInit<Self, error::Error> {
     }
 }
 
-/// Equivalent to `THIS_MODULE` in the C API.
-///
-/// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
-pub struct ThisModule(*mut bindings::module);
-
-// SAFETY: `THIS_MODULE` may be used from all threads within a module.
-unsafe impl Sync for ThisModule {}
-
-impl ThisModule {
-    /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
-    ///
-    /// # Safety
-    ///
-    /// The pointer must be equal to the right `THIS_MODULE`.
-    pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
-        ThisModule(ptr)
-    }
-
-    /// Access the raw pointer for this module.
-    ///
-    /// It is up to the user to use it correctly.
-    pub const fn as_ptr(&self) -> *mut bindings::module {
-        self.0
-    }
-}
-
 pub mod this_module {
     //! Access to the module identity and ownership information.
     //!
@@ -360,27 +334,6 @@ impl THIS_MODULE {
                 pub const fn name() -> &'static ::kernel::str::CStr {
                     $crate::c_str!($name)
                 }
-
-                // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
-                // SAFETY: `__this_module` is constructed by the kernel at load time and
-                // will not be freed until the module is unloaded.
-                const ThisModule: ::kernel::ThisModule = unsafe {{
-                    ::kernel::ThisModule::from_ptr(
-                        <Self as ::kernel::this_module::ThisModule>::OWNER.as_ptr()
-                    )
-                }};
-    
-                /// Gets a pointer to the underlying `struct module`.
-                // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
-                pub const fn as_ptr(&self) -> *mut ::kernel::bindings::module {{
-                    Self::ThisModule.as_ptr()
-                }}
-
-                /// Gets a reference to the underlying `ThisModule`.
-                /// TODO: Temporary to provide functionality old `THIS_MODULE` provided.
-                pub const fn as_ref(&self) -> &'static ::kernel::ThisModule {{
-                    &Self::ThisModule
-                }}
             }
         };
     }
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index 2877e3f7b6d3..66974ec20ef4 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -43,7 +43,7 @@
 
 pub use super::error::{code::*, Error, Result};
 
-pub use super::{str::CStrExt as _, ThisModule};
+pub use super::str::CStrExt as _;
 
 pub use super::init::InPlaceInit;
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-01-06 16:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-06 16:11 [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 02/11] rust: add new ThisModule trait and THIS_MODULE impl Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 03/11] rust: miscdevice: fix use after free because missing .owner Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 04/11] rust: block: fix missing owner field in block_device_operations Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 05/11] rust: drm: fix missing owner in file_operations Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 06/11] rust: driver: make RegistrationOps::register() to use new ThisModule Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 07/11] rust: phy: make Registration::register() " Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 08/11] rust: binder: use new THIS_MODULE Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 09/11] rust: remove module argument from InPlaceModule::init() Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 10/11] rust: remove kernel::ModuleMetadata Kari Argillander
2026-01-06 16:11 ` [PATCH RFC v2 11/11] rust: remove old version of ThisModule Kari Argillander

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).