NVIDIA GPU driver infrastructure
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions
@ 2026-05-21  7:52 Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

During tyr debugfs development, a kernel NULL pointer dereference was
encountered after `rmmod tyr` while gnome-shell still held /dev/card1 open:

```
  [158827.868132] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
  [158827.868918] Mem abort info:
  [158827.869177]   ESR = 0x0000000086000004
  [158827.869519]   EC = 0x21: IABT (current EL), IL = 32 bits
  [158827.870000]   SET = 0, FnV = 0
  [158827.870281]   EA = 0, S1PTW = 0
  [158827.870571]   FSC = 0x04: level 0 translation fault
  [158827.871043] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000108dec000
  [158827.871623] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
  [158827.872242] Internal error: Oops: 0000000086000004 [#1]  SMP
  [158827.872246] Modules linked in: tyr sunrpc snd_soc_simple_card rk805_pwrkey snd_soc_simple_card_utils rtw88_8822bu display_connector rtw88_usb rtw88_8822b snd_soc_rockchip_i2s_tdm snd_soc_hdmi_codec
  rtw88_core]
  [158827.872337] CPU: 4 UID: 1000 PID: 11276 Comm: gnome-s:disk$0 Tainted: G                 N  7.1.0-rc1+ #331 PREEMPT
  [158827.880534] Tainted: [N]=TEST
  [158827.880535] Hardware name: FriendlyElec NanoPi R6C/NanoPi R6C, BIOS v1.1 04/09/2025
  [158827.880538] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  [158827.880542] pc : 0x0
  [158827.880547] lr : _RNvNtCs257m05FHVbX_3tyr2vm8pt_unmap+0x8c/0x12c [tyr]
  [158827.880578] sp : ffff800083c236b0
  [158827.880579] x29: ffff800083c236d0 x28: ffff00013f8a0000 x27: 0000000000000000
  [158827.880585] x26: 000000000000007c x25: ffff000108e6ed80 x24: 0000000000401000
  [158827.880590] x23: 0000000000000000 x22: 0000000040000000 x21: 0000000000001000
  [158827.880595] x20: ffff00010f778138 x19: 0000000000400000 x18: 00000000ffffffff
  [158827.880600] x17: 000000040044ffff x16: 045000f2b5503510 x15: 0720072007200720
  [158827.880606] x14: 0720072007200720 x13: 0000000000401000 x12: 0000000000400000
  [158827.880611] x11: ffff800083c239d0 x10: ffff000141e4fd88 x9 : 0000000000000000
  [158827.880615] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000400000
  [158827.880620] x5 : ffff00013f8a0000 x4 : 0000000000000000 x3 : 0000000000000001
  [158827.880625] x2 : 0000000000001000 x1 : 0000000000400000 x0 : ffff00010f778138
  [158827.880630] Call trace:
  [158827.880632]  0x0 (P)
  [158827.880635]  _RNvXs6_NtCs257m05FHVbX_3tyr2vmNtB5_9GpuVmDataNtNtNtCsgmSOfgXi5CZ_6kernel3drm5gpuvm11DriverGpuVm13sm_step_unmap+0x3c/0x120 [tyr]
  [158827.891166]  _RNvMs4_NtNtNtCsgmSOfgXi5CZ_6kernel3drm5gpuvm6sm_opsINtB7_5GpuVmNtNtCs257m05FHVbX_3tyr2vm9GpuVmDataE13sm_step_unmapB13_+0x18/0x34 [tyr]
  [158827.891187]  op_unmap_cb+0x78/0xb0
  [158827.891196]  __drm_gpuvm_sm_unmap+0x18c/0x1b4
  [158827.891204]  drm_gpuvm_sm_unmap+0x38/0x4c
  [158827.891209]  _RNvMs5_NtCs257m05FHVbX_3tyr2vmNtB5_2Vm7exec_op+0x1cc/0x254 [tyr]
  [158827.894085]  _RNvMs5_NtCs257m05FHVbX_3tyr2vmNtB5_2Vm11unmap_range+0x124/0x188 [tyr]
  [158827.894105]  _RINvNtCs5hGKnPbRUFW_4core3ptr13drop_in_placeNtNtCs257m05FHVbX_3tyr3gem8KernelBoEBK_+0x44/0xd8 [tyr]
  [158827.894125]  _RINvNtCs5hGKnPbRUFW_4core3ptr13drop_in_placeINtNtNtCsgmSOfgXi5CZ_6kernel5alloc4kvec3VecNtNtCs257m05FHVbX_3tyr2fw7SectionNtNtBL_9allocator7KmallocEEB1r_+0x3c/0x100 [tyr]
  [158827.894147]  _RINvNtCs5hGKnPbRUFW_4core3ptr13drop_in_placeINtNtNtCsgmSOfgXi5CZ_6kernel4sync3arc3ArcNtNtCs257m05FHVbX_3tyr2fw8FirmwareEEB1p_+0x94/0x190 [tyr]
  [158827.894167]  _RNvMs4_NtNtCsgmSOfgXi5CZ_6kernel3drm6deviceINtB5_6DeviceNtNtCs257m05FHVbX_3tyr6driver12TyrDrmDriverE7releaseBW_+0x30/0x98 [tyr]
  [158827.899550]  drm_dev_put.part.0+0x88/0xc0
  [158827.899557]  drm_minor_release+0x18/0x28
  [158827.899562]  drm_release+0x144/0x170
  [158827.899567]  __fput+0xe4/0x30c
  [158827.899573]  ____fput+0x14/0x20
  [158827.899579]  task_work_run+0x7c/0xe8
  [158827.899586]  do_exit+0x2a8/0xac4
  [158827.899590]  do_group_exit+0x34/0x90
  [158827.899594]  get_signal+0xaac/0xabc
  [158827.899599]  arch_do_signal_or_restart+0x90/0x3e8
  [158827.899606]  exit_to_user_mode_loop+0x140/0x1d0
  [158827.899613]  el0_svc+0x2f4/0x2f8
  [158827.899620]  el0t_64_sync_handler+0xa0/0xe4
  [158827.899627]  el0t_64_sync+0x198/0x19c
  [158827.899632] ---[ end trace 0000000000000000 ]---
```

The root cause: `fops.owner` was `NULL` in Rust DRM drivers, so the kernel
never blocked module unloading while file descriptors were open. This leads to
use-after-free when drm_release (or other fops) is called on freed module code. 

The series moves `THIS_MODULE` into the `ModuleMetadata` as a const, threads it
through `#[vtable]` to set `fops.owner` in DRM/miscdevice, and updates configfs
and rnull to use `LocalModule::THIS_MODULE`.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
Changes in v2:
- Merged old `static THIS_MODULE` and v1's `MODULE_PTR` into a single
  `ModuleMetadata::THIS_MODULE` const
- `#[vtable]` macro now auto-inserts `type ThisModule`, removing all per-driver
  manual patches from v1
- Added configfs & rnull usage site updates and doctest `LocalModule` fallback
- Link to v1: https://lore.kernel.org/r/20260519-fix-fops-owner-v1-0-2ded9830da14@linux.dev

---
Alvin Sun (7):
      rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait
      rust: macros: auto-insert ThisModule in #[vtable]
      rust: doctest: add LocalModule fallback for #[vtable] ThisModule
      rust: drm: set fops.owner from driver module pointer
      rust: miscdevice: set fops.owner from driver module pointer
      rust: configfs: use `LocalModule` for `THIS_MODULE`
      block: rnull: use `LocalModule` for `THIS_MODULE`

 drivers/block/rnull/configfs.rs |  6 ++----
 rust/kernel/configfs.rs         |  8 +++++---
 rust/kernel/drm/device.rs       |  3 ++-
 rust/kernel/drm/gem/mod.rs      |  4 ++--
 rust/kernel/lib.rs              |  3 +++
 rust/kernel/miscdevice.rs       |  2 ++
 rust/macros/lib.rs              |  6 ++++++
 rust/macros/module.rs           | 34 +++++++++++++++++-----------------
 rust/macros/vtable.rs           | 38 +++++++++++++++++++++++++++++++++++++-
 scripts/rustdoc_test_gen.rs     | 16 ++++++++++++++++
 10 files changed, 92 insertions(+), 28 deletions(-)
---
base-commit: aa61612ab641d7d62b0b6889f2c7c9251489f6e3
change-id: 20260519-fix-fops-owner-e3a77bb27c6c
prerequisite-change-id: 20260519-miscdev-use-format-9ab7e83b1c11:v3
prerequisite-patch-id: 405b334ff0d48ad350014f05a2321bdbaa025400
prerequisite-patch-id: 604b631c81d5423f4ebb2e12ba2d22e9ce371bfc
prerequisite-patch-id: cb550d94cefe01920e0d3ced2b2bcbecd76f3907
prerequisite-patch-id: 3bc830839742591460cb86d9472c04f4686dc600
prerequisite-patch-id: 571058244bc8c7088638d2e3225713011246c7e9
prerequisite-patch-id: 347c5a3c6dbef9832bfce8419fc23e6e08ba477f
prerequisite-patch-id: 3e202d988b56b88446f7535e90d3f00cf5f15701

Best regards,
-- 
Alvin Sun <alvin.sun@linux.dev>



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

* [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-06-18 12:04   ` Andreas Hindborg
  2026-06-18 14:16   ` Gary Guo
  2026-05-21  7:52 ` [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable] Alvin Sun
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Add a `THIS_MODULE` const to the `ModuleMetadata` trait so that
modules can provide their `ThisModule` pointer usable in const
contexts such as static file_operations.

Move the `THIS_MODULE` static from the `module!` macro into the
`ModuleMetadata` impl, and update `__init` to use
`LocalModule::THIS_MODULE` instead.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 rust/kernel/lib.rs    |  3 +++
 rust/macros/module.rs | 34 +++++++++++++++++-----------------
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index b72b2fbe046d6..f0cf0705d9697 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -184,6 +184,9 @@ fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Erro
 pub trait ModuleMetadata {
     /// The name of the module as specified in the `module!` macro.
     const NAME: &'static crate::str::CStr;
+
+    /// The module's `THIS_MODULE` pointer.
+    const THIS_MODULE: ThisModule;
 }
 
 /// Equivalent to `THIS_MODULE` in the C API.
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 06c18e2075083..b6d7b3299fbf9 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -497,28 +497,28 @@ pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
         /// Used by the printing macros, e.g. [`info!`].
         const __LOG_PREFIX: &[u8] = #name_cstr.to_bytes_with_nul();
 
-        // 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::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.
         type LocalModule = #type_;
 
         impl ::kernel::ModuleMetadata for #type_ {
             const NAME: &'static ::kernel::str::CStr = #name_cstr;
+
+            #[cfg(MODULE)]
+            const THIS_MODULE: ::kernel::ThisModule = {
+                extern "C" {
+                    static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
+                }
+
+                // SAFETY: `__this_module` is constructed by the kernel at load time
+                // and lives until the module is unloaded.
+                unsafe { ::kernel::ThisModule::from_ptr(__this_module.get()) }
+            };
+
+            #[cfg(not(MODULE))]
+            const THIS_MODULE: ::kernel::ThisModule = unsafe {
+                ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
+            };
         }
 
         // Double nested modules, since then nobody can access the public items inside.
@@ -616,7 +616,7 @@ pub extern "C" fn #ident_exit() {
                 /// This function must only be called once.
                 unsafe fn __init() -> ::kernel::ffi::c_int {
                     let initer = <super::super::LocalModule as ::kernel::InPlaceModule>::init(
-                        &super::super::THIS_MODULE
+                        &<super::super::LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE
                     );
                     // 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

-- 
2.43.0



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

* [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable]
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-06-18 12:11   ` Andreas Hindborg
  2026-06-18 14:13   ` Gary Guo
  2026-05-21  7:52 ` [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule Alvin Sun
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Auto-add `type ThisModule: ::kernel::ModuleMetadata;` as a required
associated type on the trait side if not already defined, and
auto-insert `type ThisModule = crate::LocalModule;` on the impl side
if not explicitly provided, eliminating the need to manually declare
and implement `ThisModule` in every vtable trait and impl.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 rust/macros/lib.rs    |  6 ++++++
 rust/macros/vtable.rs | 38 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index 2cfd59e0f9e7c..d35e45ea745c0 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -176,6 +176,12 @@ pub fn module(input: TokenStream) -> TokenStream {
 ///
 /// This macro should not be used when all functions are required.
 ///
+/// Additionally, this macro automatically handles the `ThisModule`
+/// associated type: on the trait side, `type ThisModule: ModuleMetadata;`
+/// is added as a required associated type if not already defined; on the
+/// impl side, `type ThisModule = LocalModule;` is automatically inserted
+/// if not explicitly defined.
+///
 /// # Examples
 ///
 /// ```
diff --git a/rust/macros/vtable.rs b/rust/macros/vtable.rs
index c6510b0c4ea1d..d3d0e9cbd7172 100644
--- a/rust/macros/vtable.rs
+++ b/rust/macros/vtable.rs
@@ -23,6 +23,7 @@
 
 fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
     let mut gen_items = Vec::new();
+    let mut has_this_module = false;
 
     gen_items.push(parse_quote! {
          /// A marker to prevent implementors from forgetting to use [`#[vtable]`](vtable)
@@ -30,6 +31,28 @@ fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
          const USE_VTABLE_ATTR: ();
     });
 
+    // Detect existing type ThisModule so we don't add a duplicate.
+    for i in &item.items {
+        if let TraitItem::Type(type_item) = i {
+            if type_item.ident == "ThisModule" {
+                has_this_module = true;
+            }
+        }
+    }
+
+    // Add `type ThisModule: ModuleMetadata` as a required associated type if
+    // the trait does not already define it. No default is used because
+    // `associated_type_defaults` is unstable (issue #29661).
+    if !has_this_module {
+        gen_items.push(parse_quote! {
+            /// The module implementing this vtable trait.
+            ///
+            /// Automatically set to `crate::LocalModule` by the `#[vtable]`
+            /// impl macro.
+            type ThisModule: ::kernel::ModuleMetadata;
+        });
+    }
+
     for item in &item.items {
         if let TraitItem::Fn(fn_item) = item {
             let name = &fn_item.sig.ident;
@@ -58,18 +81,31 @@ fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
 fn handle_impl(mut item: ItemImpl) -> Result<ItemImpl> {
     let mut gen_items = Vec::new();
     let mut defined_consts = HashSet::new();
+    let mut defined_types = HashSet::new();
 
-    // Iterate over all user-defined constants to gather any possible explicit overrides.
+    // Iterate over all user-defined constants and types to gather any possible explicit overrides.
     for item in &item.items {
         if let ImplItem::Const(const_item) = item {
             defined_consts.insert(const_item.ident.clone());
         }
+        if let ImplItem::Type(type_item) = item {
+            defined_types.insert(type_item.ident.clone());
+        }
     }
 
     gen_items.push(parse_quote! {
         const USE_VTABLE_ATTR: () = ();
     });
 
+    // Auto-insert `type ThisModule = crate::LocalModule` if not explicitly defined.
+    // `crate::LocalModule` resolves to the real module type (via `module!`) or a
+    // dummy fallback in non-module contexts (e.g., doctests).
+    if !defined_types.contains(&parse_quote!(ThisModule)) {
+        gen_items.push(parse_quote! {
+            type ThisModule = crate::LocalModule;
+        });
+    }
+
     for item in &item.items {
         if let ImplItem::Fn(fn_item) = item {
             let name = &fn_item.sig.ident;

-- 
2.43.0



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

* [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable] Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-06-18 12:13   ` Andreas Hindborg
  2026-05-21  7:52 ` [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer Alvin Sun
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Add a `LocalModule` struct with a null-pointer `ModuleMetadata` impl
in the doctest harness, so that `crate::LocalModule` (auto-inserted
by `#[vtable]`) resolves correctly when there is no `module!` macro.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 scripts/rustdoc_test_gen.rs | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/scripts/rustdoc_test_gen.rs b/scripts/rustdoc_test_gen.rs
index ee76e96b41eea..198af4e446c8c 100644
--- a/scripts/rustdoc_test_gen.rs
+++ b/scripts/rustdoc_test_gen.rs
@@ -239,6 +239,22 @@ macro_rules! assert_eq {{
 
 const __LOG_PREFIX: &[u8] = b"rust_doctests_kernel\0";
 
+/// Dummy module type for doctest context.
+struct LocalModule;
+
+use kernel::{{
+    str::CStr,
+    ModuleMetadata,
+    ThisModule, //
+}};
+use core::ptr::null_mut;
+
+impl ModuleMetadata for LocalModule {{
+    const NAME: &'static CStr = c"rust_doctests_kernel";
+    // SAFETY: `try_module_get`/`module_put` handle null module pointers gracefully.
+    const THIS_MODULE: ThisModule = unsafe {{ ThisModule::from_ptr(null_mut()) }};
+}}
+
 {rust_tests}
 "#
     )

-- 
2.43.0



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

* [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
                   ` (2 preceding siblings ...)
  2026-05-21  7:52 ` [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-06-18 14:15   ` Gary Guo
  2026-05-21  7:52 ` [PATCH v2 5/7] rust: miscdevice: " Alvin Sun
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Change `create_fops()` to accept an owner module pointer instead of
hardcoding `null_mut()`, ensuring the kernel correctly tracks the
module owning the DRM device's file operations.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 rust/kernel/drm/device.rs  | 3 ++-
 rust/kernel/drm/gem/mod.rs | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 403fc35353c74..53e44a780ae97 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -111,7 +111,8 @@ 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 as crate::ModuleMetadata>::THIS_MODULE.as_ptr());
 
     /// 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/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index 01b5bd47a3332..9a203efc59116 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -357,10 +357,10 @@ impl<T: DriverObject> AllocImpl for Object<T> {
     };
 }
 
-pub(super) const fn create_fops() -> bindings::file_operations {
+pub(super) const fn create_fops(owner: *mut bindings::module) -> bindings::file_operations {
     let mut fops: bindings::file_operations = pin_init::zeroed();
 
-    fops.owner = core::ptr::null_mut();
+    fops.owner = owner;
     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] 15+ messages in thread

* [PATCH v2 5/7] rust: miscdevice: set fops.owner from driver module pointer
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
                   ` (3 preceding siblings ...)
  2026-05-21  7:52 ` [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 6/7] rust: configfs: use `LocalModule` for `THIS_MODULE` Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 7/7] block: rnull: " Alvin Sun
  6 siblings, 0 replies; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Set the miscdevice fops owner field from the driver module pointer
via `<T::ThisModule as ModuleMetadata>::THIS_MODULE`, instead of
defaulting to null.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 rust/kernel/miscdevice.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index 83ce50def5ac9..16837c46bca49 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -30,6 +30,7 @@
         ForeignOwnable,
         Opaque, //
     },
+    ModuleMetadata, //
 };
 use core::marker::PhantomData;
 
@@ -430,6 +431,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
         } else {
             None
         },
+        owner: <T::ThisModule as ModuleMetadata>::THIS_MODULE.as_ptr(),
         ..pin_init::zeroed()
     };
 

-- 
2.43.0



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

* [PATCH v2 6/7] rust: configfs: use `LocalModule` for `THIS_MODULE`
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
                   ` (4 preceding siblings ...)
  2026-05-21  7:52 ` [PATCH v2 5/7] rust: miscdevice: " Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-05-21  7:52 ` [PATCH v2 7/7] block: rnull: " Alvin Sun
  6 siblings, 0 replies; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Replace the `THIS_MODULE` static reference in the `configfs_attrs!`
macro with `<LocalModule as ModuleMetadata>::THIS_MODULE`, consistent
with the move of `THIS_MODULE` into the `ModuleMetadata` trait.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 rust/kernel/configfs.rs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 2339c6467325d..cc60297f11551 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -875,7 +875,7 @@ fn as_ptr(&self) -> *const bindings::config_item_type {
 ///                 configfs::Subsystem<Configuration>,
 ///                 Configuration
 ///                 >::new_with_child_ctor::<N,Child>(
-///             &THIS_MODULE,
+///             &<LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE,
 ///             &CONFIGURATION_ATTRS
 ///         );
 ///
@@ -1021,7 +1021,8 @@ macro_rules! configfs_attrs {
 
                     static [< $data:upper _TPE >] : $crate::configfs::ItemType<$container, $data>  =
                         $crate::configfs::ItemType::<$container, $data>::new::<N>(
-                            &THIS_MODULE, &[<$ data:upper _ATTRS >]
+                            &<LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE,
+                            &[<$ data:upper _ATTRS >]
                         );
                 )?
 
@@ -1030,7 +1031,8 @@ macro_rules! configfs_attrs {
                         $crate::configfs::ItemType<$container, $data>  =
                             $crate::configfs::ItemType::<$container, $data>::
                             new_with_child_ctor::<N, $child>(
-                                &THIS_MODULE, &[<$ data:upper _ATTRS >]
+                                &<LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE,
+                                &[<$ data:upper _ATTRS >]
                             );
                 )?
 

-- 
2.43.0



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

* [PATCH v2 7/7] block: rnull: use `LocalModule` for `THIS_MODULE`
  2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
                   ` (5 preceding siblings ...)
  2026-05-21  7:52 ` [PATCH v2 6/7] rust: configfs: use `LocalModule` for `THIS_MODULE` Alvin Sun
@ 2026-05-21  7:52 ` Alvin Sun
  2026-06-18 12:17   ` Andreas Hindborg
  6 siblings, 1 reply; 15+ messages in thread
From: Alvin Sun @ 2026-05-21  7:52 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Replace the `THIS_MODULE` import with `LocalModule` from the crate,
consistent with the move of `THIS_MODULE` into the `ModuleMetadata`
trait.

Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
 drivers/block/rnull/configfs.rs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index c10a55fc58948..b2547ad1e5ddd 100644
--- a/drivers/block/rnull/configfs.rs
+++ b/drivers/block/rnull/configfs.rs
@@ -1,9 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
-use super::{
-    NullBlkDevice,
-    THIS_MODULE, //
-};
+use super::NullBlkDevice;
+use crate::LocalModule;
 use kernel::{
     block::mq::gen_disk::{
         GenDisk,

-- 
2.43.0



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

* Re: [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait
  2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
@ 2026-06-18 12:04   ` Andreas Hindborg
  2026-06-18 14:16   ` Gary Guo
  1 sibling, 0 replies; 15+ messages in thread
From: Andreas Hindborg @ 2026-06-18 12:04 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

"Alvin Sun" <alvin.sun@linux.dev> writes:

> Add a `THIS_MODULE` const to the `ModuleMetadata` trait so that
> modules can provide their `ThisModule` pointer usable in const
> contexts such as static file_operations.
>
> Move the `THIS_MODULE` static from the `module!` macro into the
> `ModuleMetadata` impl, and update `__init` to use
> `LocalModule::THIS_MODULE` instead.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
> ---
>  rust/kernel/lib.rs    |  3 +++
>  rust/macros/module.rs | 34 +++++++++++++++++-----------------
>  2 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index b72b2fbe046d6..f0cf0705d9697 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -184,6 +184,9 @@ fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Erro
>  pub trait ModuleMetadata {
>      /// The name of the module as specified in the `module!` macro.
>      const NAME: &'static crate::str::CStr;
> +
> +    /// The module's `THIS_MODULE` pointer.
> +    const THIS_MODULE: ThisModule;
>  }
>
>  /// Equivalent to `THIS_MODULE` in the C API.
> diff --git a/rust/macros/module.rs b/rust/macros/module.rs
> index 06c18e2075083..b6d7b3299fbf9 100644
> --- a/rust/macros/module.rs
> +++ b/rust/macros/module.rs
> @@ -497,28 +497,28 @@ pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
>          /// Used by the printing macros, e.g. [`info!`].
>          const __LOG_PREFIX: &[u8] = #name_cstr.to_bytes_with_nul();
>
> -        // 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::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.
>          type LocalModule = #type_;
>
>          impl ::kernel::ModuleMetadata for #type_ {
>              const NAME: &'static ::kernel::str::CStr = #name_cstr;
> +
> +            #[cfg(MODULE)]
> +            const THIS_MODULE: ::kernel::ThisModule = {
> +                extern "C" {
> +                    static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
> +                }
> +
> +                // SAFETY: `__this_module` is constructed by the kernel at load time
> +                // and lives until the module is unloaded.
> +                unsafe { ::kernel::ThisModule::from_ptr(__this_module.get()) }
> +            };
> +
> +            #[cfg(not(MODULE))]
> +            const THIS_MODULE: ::kernel::ThisModule = unsafe {
> +                ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
> +            };
>          }
>
>          // Double nested modules, since then nobody can access the public items inside.
> @@ -616,7 +616,7 @@ pub extern "C" fn #ident_exit() {
>                  /// This function must only be called once.
>                  unsafe fn __init() -> ::kernel::ffi::c_int {
>                      let initer = <super::super::LocalModule as ::kernel::InPlaceModule>::init(
> -                        &super::super::THIS_MODULE
> +                        &<super::super::LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE

Is it possible we could make this more ergonomic? Perhaps by adding a
helper:

  fn this_module<M: ::kernel::ModuleMetadata>() -> &'static ::kernel::ThisModule {
      &M::THIS_MODULE
  }

Then the invocation is a little better:

  let initer = <super::super::LocalModule as ::kernel::InPlaceModule>::init(
      this_module::<super::super::LocalModule>()
  );


Best regards,
Andreas Hindborg



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

* Re: [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable]
  2026-05-21  7:52 ` [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable] Alvin Sun
@ 2026-06-18 12:11   ` Andreas Hindborg
  2026-06-18 14:13   ` Gary Guo
  1 sibling, 0 replies; 15+ messages in thread
From: Andreas Hindborg @ 2026-06-18 12:11 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Alvin Sun <alvin.sun@linux.dev> writes:

> Auto-add `type ThisModule: ::kernel::ModuleMetadata;` as a required
> associated type on the trait side if not already defined, and
> auto-insert `type ThisModule = crate::LocalModule;` on the impl side
> if not explicitly provided, eliminating the need to manually declare
> and implement `ThisModule` in every vtable trait and impl.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>


Best regards,
Andreas Hindborg




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

* Re: [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule
  2026-05-21  7:52 ` [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule Alvin Sun
@ 2026-06-18 12:13   ` Andreas Hindborg
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Hindborg @ 2026-06-18 12:13 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Alvin Sun <alvin.sun@linux.dev> writes:

> Add a `LocalModule` struct with a null-pointer `ModuleMetadata` impl
> in the doctest harness, so that `crate::LocalModule` (auto-inserted
> by `#[vtable]`) resolves correctly when there is no `module!` macro.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>

Does this need to be ordered before the vtable auto insert in the patch series?

Best regards,
Andreas Hindborg



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

* Re: [PATCH v2 7/7] block: rnull: use `LocalModule` for `THIS_MODULE`
  2026-05-21  7:52 ` [PATCH v2 7/7] block: rnull: " Alvin Sun
@ 2026-06-18 12:17   ` Andreas Hindborg
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Hindborg @ 2026-06-18 12:17 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block, Alvin Sun

Alvin Sun <alvin.sun@linux.dev> writes:

> Replace the `THIS_MODULE` import with `LocalModule` from the crate,
> consistent with the move of `THIS_MODULE` into the `ModuleMetadata`
> trait.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>

You need to squash this with the previous patch.


Best regards,
Andreas Hindborg




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

* Re: [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable]
  2026-05-21  7:52 ` [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable] Alvin Sun
  2026-06-18 12:11   ` Andreas Hindborg
@ 2026-06-18 14:13   ` Gary Guo
  1 sibling, 0 replies; 15+ messages in thread
From: Gary Guo @ 2026-06-18 14:13 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block

On Thu May 21, 2026 at 8:52 AM BST, Alvin Sun wrote:
> Auto-add `type ThisModule: ::kernel::ModuleMetadata;` as a required
> associated type on the trait side if not already defined, and
> auto-insert `type ThisModule = crate::LocalModule;` on the impl side
> if not explicitly provided, eliminating the need to manually declare
> and implement `ThisModule` in every vtable trait and impl.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>

Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/all/DIMMWHUOLPSH.13JFRHDKDQJGO@garyguo.net

> ---
>  rust/macros/lib.rs    |  6 ++++++
>  rust/macros/vtable.rs | 38 +++++++++++++++++++++++++++++++++++++-
>  2 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
> index 2cfd59e0f9e7c..d35e45ea745c0 100644
> --- a/rust/macros/lib.rs
> +++ b/rust/macros/lib.rs
> @@ -176,6 +176,12 @@ pub fn module(input: TokenStream) -> TokenStream {
>  ///
>  /// This macro should not be used when all functions are required.
>  ///
> +/// Additionally, this macro automatically handles the `ThisModule`
> +/// associated type: on the trait side, `type ThisModule: ModuleMetadata;`
> +/// is added as a required associated type if not already defined; on the
> +/// impl side, `type ThisModule = LocalModule;` is automatically inserted
> +/// if not explicitly defined.
> +///
>  /// # Examples
>  ///
>  /// ```
> diff --git a/rust/macros/vtable.rs b/rust/macros/vtable.rs
> index c6510b0c4ea1d..d3d0e9cbd7172 100644
> --- a/rust/macros/vtable.rs
> +++ b/rust/macros/vtable.rs
> @@ -23,6 +23,7 @@
>  
>  fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
>      let mut gen_items = Vec::new();
> +    let mut has_this_module = false;
>  
>      gen_items.push(parse_quote! {
>           /// A marker to prevent implementors from forgetting to use [`#[vtable]`](vtable)
> @@ -30,6 +31,28 @@ fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
>           const USE_VTABLE_ATTR: ();
>      });
>  
> +    // Detect existing type ThisModule so we don't add a duplicate.
> +    for i in &item.items {
> +        if let TraitItem::Type(type_item) = i {
> +            if type_item.ident == "ThisModule" {
> +                has_this_module = true;
> +            }
> +        }
> +    }
> +
> +    // Add `type ThisModule: ModuleMetadata` as a required associated type if
> +    // the trait does not already define it. No default is used because
> +    // `associated_type_defaults` is unstable (issue #29661).

I don't think this is relevant. What's the sensible default anyway?

> +    if !has_this_module {

Perhaps just make this an one liner :

    if !item.items.iter().any(|i| matches!(item, TraitItem::Type(t) if t.ident == "ThisModule")) {

> +        gen_items.push(parse_quote! {
> +            /// The module implementing this vtable trait.
> +            ///
> +            /// Automatically set to `crate::LocalModule` by the `#[vtable]`
> +            /// impl macro.
> +            type ThisModule: ::kernel::ModuleMetadata;
> +        });
> +    }
> +
>      for item in &item.items {
>          if let TraitItem::Fn(fn_item) = item {
>              let name = &fn_item.sig.ident;
> @@ -58,18 +81,31 @@ fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
>  fn handle_impl(mut item: ItemImpl) -> Result<ItemImpl> {
>      let mut gen_items = Vec::new();
>      let mut defined_consts = HashSet::new();
> +    let mut defined_types = HashSet::new();

I'd just rename `defined_consts` to `defined_items` to reuse the same set as
there cannot be assoc items with same name anyway.

Best,
Gary

>  
> -    // Iterate over all user-defined constants to gather any possible explicit overrides.
> +    // Iterate over all user-defined constants and types to gather any possible explicit overrides.
>      for item in &item.items {
>          if let ImplItem::Const(const_item) = item {
>              defined_consts.insert(const_item.ident.clone());
>          }
> +        if let ImplItem::Type(type_item) = item {
> +            defined_types.insert(type_item.ident.clone());
> +        }
>      }
>  
>      gen_items.push(parse_quote! {
>          const USE_VTABLE_ATTR: () = ();
>      });
>  
> +    // Auto-insert `type ThisModule = crate::LocalModule` if not explicitly defined.
> +    // `crate::LocalModule` resolves to the real module type (via `module!`) or a
> +    // dummy fallback in non-module contexts (e.g., doctests).
> +    if !defined_types.contains(&parse_quote!(ThisModule)) {
> +        gen_items.push(parse_quote! {
> +            type ThisModule = crate::LocalModule;
> +        });
> +    }
> +
>      for item in &item.items {
>          if let ImplItem::Fn(fn_item) = item {
>              let name = &fn_item.sig.ident;



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

* Re: [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer
  2026-05-21  7:52 ` [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer Alvin Sun
@ 2026-06-18 14:15   ` Gary Guo
  0 siblings, 0 replies; 15+ messages in thread
From: Gary Guo @ 2026-06-18 14:15 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block

On Thu May 21, 2026 at 8:52 AM BST, Alvin Sun wrote:
> Change `create_fops()` to accept an owner module pointer instead of
> hardcoding `null_mut()`, ensuring the kernel correctly tracks the
> module owning the DRM device's file operations.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
> ---
>  rust/kernel/drm/device.rs  | 3 ++-
>  rust/kernel/drm/gem/mod.rs | 4 ++--
>  2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
> index 403fc35353c74..53e44a780ae97 100644
> --- a/rust/kernel/drm/device.rs
> +++ b/rust/kernel/drm/device.rs
> @@ -111,7 +111,8 @@ 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 as crate::ModuleMetadata>::THIS_MODULE.as_ptr());

I wonder if the assoc type should just be called `Owner` or `OwnerModule`?

Best.
Gary

>  
>      /// 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/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
> index 01b5bd47a3332..9a203efc59116 100644
> --- a/rust/kernel/drm/gem/mod.rs
> +++ b/rust/kernel/drm/gem/mod.rs
> @@ -357,10 +357,10 @@ impl<T: DriverObject> AllocImpl for Object<T> {
>      };
>  }
>  
> -pub(super) const fn create_fops() -> bindings::file_operations {
> +pub(super) const fn create_fops(owner: *mut bindings::module) -> bindings::file_operations {
>      let mut fops: bindings::file_operations = pin_init::zeroed();
>  
> -    fops.owner = core::ptr::null_mut();
> +    fops.owner = owner;
>      fops.open = Some(bindings::drm_open);
>      fops.release = Some(bindings::drm_release);
>      fops.unlocked_ioctl = Some(bindings::drm_ioctl);



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

* Re: [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait
  2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
  2026-06-18 12:04   ` Andreas Hindborg
@ 2026-06-18 14:16   ` Gary Guo
  1 sibling, 0 replies; 15+ messages in thread
From: Gary Guo @ 2026-06-18 14:16 UTC (permalink / raw)
  To: Alvin Sun, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
	Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
	Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
	Jens Axboe
  Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
	linux-kselftest, kunit-dev, linux-block

On Thu May 21, 2026 at 8:52 AM BST, Alvin Sun wrote:
> Add a `THIS_MODULE` const to the `ModuleMetadata` trait so that
> modules can provide their `ThisModule` pointer usable in const
> contexts such as static file_operations.
>
> Move the `THIS_MODULE` static from the `module!` macro into the
> `ModuleMetadata` impl, and update `__init` to use
> `LocalModule::THIS_MODULE` instead.

Perhaps you could mention that this is made possible by const_refs_to_static
which is stable since the MSRV bump.

Best,
Gary

>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
> ---
>  rust/kernel/lib.rs    |  3 +++
>  rust/macros/module.rs | 34 +++++++++++++++++-----------------
>  2 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index b72b2fbe046d6..f0cf0705d9697 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -184,6 +184,9 @@ fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Erro
>  pub trait ModuleMetadata {
>      /// The name of the module as specified in the `module!` macro.
>      const NAME: &'static crate::str::CStr;
> +
> +    /// The module's `THIS_MODULE` pointer.
> +    const THIS_MODULE: ThisModule;
>  }
>  
>  /// Equivalent to `THIS_MODULE` in the C API.
> diff --git a/rust/macros/module.rs b/rust/macros/module.rs
> index 06c18e2075083..b6d7b3299fbf9 100644
> --- a/rust/macros/module.rs
> +++ b/rust/macros/module.rs
> @@ -497,28 +497,28 @@ pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
>          /// Used by the printing macros, e.g. [`info!`].
>          const __LOG_PREFIX: &[u8] = #name_cstr.to_bytes_with_nul();
>  
> -        // 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::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.
>          type LocalModule = #type_;
>  
>          impl ::kernel::ModuleMetadata for #type_ {
>              const NAME: &'static ::kernel::str::CStr = #name_cstr;
> +
> +            #[cfg(MODULE)]
> +            const THIS_MODULE: ::kernel::ThisModule = {
> +                extern "C" {
> +                    static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
> +                }
> +
> +                // SAFETY: `__this_module` is constructed by the kernel at load time
> +                // and lives until the module is unloaded.
> +                unsafe { ::kernel::ThisModule::from_ptr(__this_module.get()) }
> +            };
> +
> +            #[cfg(not(MODULE))]
> +            const THIS_MODULE: ::kernel::ThisModule = unsafe {
> +                ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
> +            };
>          }
>  
>          // Double nested modules, since then nobody can access the public items inside.
> @@ -616,7 +616,7 @@ pub extern "C" fn #ident_exit() {
>                  /// This function must only be called once.
>                  unsafe fn __init() -> ::kernel::ffi::c_int {
>                      let initer = <super::super::LocalModule as ::kernel::InPlaceModule>::init(
> -                        &super::super::THIS_MODULE
> +                        &<super::super::LocalModule as ::kernel::ModuleMetadata>::THIS_MODULE
>                      );
>                      // 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



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

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

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21  7:52 [PATCH v2 0/7] Fix missing fops.owner in Rust DRM/misc abstractions Alvin Sun
2026-05-21  7:52 ` [PATCH v2 1/7] rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait Alvin Sun
2026-06-18 12:04   ` Andreas Hindborg
2026-06-18 14:16   ` Gary Guo
2026-05-21  7:52 ` [PATCH v2 2/7] rust: macros: auto-insert ThisModule in #[vtable] Alvin Sun
2026-06-18 12:11   ` Andreas Hindborg
2026-06-18 14:13   ` Gary Guo
2026-05-21  7:52 ` [PATCH v2 3/7] rust: doctest: add LocalModule fallback for #[vtable] ThisModule Alvin Sun
2026-06-18 12:13   ` Andreas Hindborg
2026-05-21  7:52 ` [PATCH v2 4/7] rust: drm: set fops.owner from driver module pointer Alvin Sun
2026-06-18 14:15   ` Gary Guo
2026-05-21  7:52 ` [PATCH v2 5/7] rust: miscdevice: " Alvin Sun
2026-05-21  7:52 ` [PATCH v2 6/7] rust: configfs: use `LocalModule` for `THIS_MODULE` Alvin Sun
2026-05-21  7:52 ` [PATCH v2 7/7] block: rnull: " Alvin Sun
2026-06-18 12:17   ` Andreas Hindborg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox