[PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions

Alvin Sun posted 10 patches 1 month, 2 weeks ago
MAINTAINERS                                |  2 +-
drivers/android/binder/rust_binder_main.rs |  3 +-
drivers/block/rnull/configfs.rs            |  5 +-
rust/kernel/auxiliary.rs                   |  2 +-
rust/kernel/configfs.rs                    |  9 ++--
rust/kernel/drm/device.rs                  |  3 +-
rust/kernel/drm/gem/mod.rs                 |  4 +-
rust/kernel/i2c.rs                         |  2 +-
rust/kernel/lib.rs                         | 75 +++-------------------------
rust/kernel/miscdevice.rs                  |  4 +-
rust/kernel/module.rs                      | 80 ++++++++++++++++++++++++++++++
rust/kernel/net/phy.rs                     |  6 ++-
rust/kernel/pci.rs                         |  2 +-
rust/kernel/platform.rs                    |  2 +-
rust/kernel/usb.rs                         |  2 +-
rust/macros/lib.rs                         |  6 +++
rust/macros/module.rs                      | 34 ++++++-------
rust/macros/vtable.rs                      | 41 +++++++++++++--
scripts/rustdoc_test_gen.rs                | 16 ++++++
19 files changed, 189 insertions(+), 109 deletions(-)
[PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Alvin Sun 1 month, 2 weeks ago
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 `this_module::<LocalModule>()`.

Assisted-by: opencode:glm-5.2
Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
---
Changes in v10:
- Drop prerequisite patches that have been merged, to
  resolve rebase conflicts.
- Link to v9: https://lore.kernel.org/r/20260723-fix-fops-owner-v9-0-c1c3af7f7bcb@linux.dev

Changes in v9:
- Rename the binder commit prefix from `rust: binder:` to `rust_binder:`
  to match the in-tree module name.
- Link to v8: https://lore.kernel.org/r/20260713-fix-fops-owner-v8-0-2495cfa82d47@linux.dev

Changes in v8:
- Remove unused `crate::LocalModule` import in rnull configfs.
- Link to v7: https://lore.kernel.org/r/20260627-fix-fops-owner-v7-0-33cd3990edf0@linux.dev

Changes in v7:
- Use `crate::LocalModule` in `configfs_attrs!` and silence `clippy::crate_in_macro_def`, per Gary's review.
- Link to v6: https://lore.kernel.org/r/20260624-fix-fops-owner-v6-0-5295e333cb3e@linux.dev

Changes in v6:
- Update MAINTAINERS to cover the new `rust/kernel/module.rs`.
- Link to v5: https://lore.kernel.org/r/20260624-fix-fops-owner-v5-0-aa1cba242f05@linux.dev

Changes in v5:
- Add `#[inline]` to the `this_module()` helper.
- Fix configfs doc comment to reference `crate::LocalModule` instead of
  bare `LocalModule`.
- Link to v4: https://lore.kernel.org/r/20260623-fix-fops-owner-v4-0-0daf5f077d5c@linux.dev

Changes in v4:
- Move module-related types into a new `rust/kernel/module.rs`.
- Migrate binder from the `module!`-generated `THIS_MODULE` static to
  `this_module::<LocalModule>()`.
- Reorganise the series so that every commit builds independently, and
  drop the legacy `THIS_MODULE` static once all users are migrated.
- Link to v3: https://lore.kernel.org/r/20260622-fix-fops-owner-v3-0-49d45cb37032@linux.dev

Changes in v3:
- Renamed vtable associated type `ThisModule` to `OwnerModule`
- Added `this_module()` helper for ergonomic `THIS_MODULE` access
- Refined vtable macro implementation: one-liner detection and single `defined_items` set
- Reordered commits to place doctest fallback before vtable auto-insert
- Link to v2: https://lore.kernel.org/r/20260521-fix-fops-owner-v2-0-fd99079c5a04@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 (10):
      rust: module: move module types into `module.rs`
      rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait
      rust: doctest: add LocalModule fallback for #[vtable] ThisModule
      rust: macros: auto-insert OwnerModule in #[vtable]
      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`
      rust_binder: use `LocalModule` for `THIS_MODULE`
      rust: macros: remove `THIS_MODULE` static from `module!`
      rust: module: update MAINTAINERS to cover module.rs

 MAINTAINERS                                |  2 +-
 drivers/android/binder/rust_binder_main.rs |  3 +-
 drivers/block/rnull/configfs.rs            |  5 +-
 rust/kernel/auxiliary.rs                   |  2 +-
 rust/kernel/configfs.rs                    |  9 ++--
 rust/kernel/drm/device.rs                  |  3 +-
 rust/kernel/drm/gem/mod.rs                 |  4 +-
 rust/kernel/i2c.rs                         |  2 +-
 rust/kernel/lib.rs                         | 75 +++-------------------------
 rust/kernel/miscdevice.rs                  |  4 +-
 rust/kernel/module.rs                      | 80 ++++++++++++++++++++++++++++++
 rust/kernel/net/phy.rs                     |  6 ++-
 rust/kernel/pci.rs                         |  2 +-
 rust/kernel/platform.rs                    |  2 +-
 rust/kernel/usb.rs                         |  2 +-
 rust/macros/lib.rs                         |  6 +++
 rust/macros/module.rs                      | 34 ++++++-------
 rust/macros/vtable.rs                      | 41 +++++++++++++--
 scripts/rustdoc_test_gen.rs                | 16 ++++++
 19 files changed, 189 insertions(+), 109 deletions(-)
---
base-commit: 2ee859ebf156157609f71060ae472711c8cbc326
change-id: 20260519-fix-fops-owner-e3a77bb27c6c
prerequisite-patch-id: 347c5a3c6dbef9832bfce8419fc23e6e08ba477f

Best regards,
-- 
Alvin Sun <alvin.sun@linux.dev>
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Tue, Aug 11, 2026 at 8:41 AM Alvin Sun <alvin.sun@linux.dev> wrote:
>
> 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 `this_module::<LocalModule>()`.

Applied to `rust-next` -- thanks everyone!

    [ Fixed `clippy::undocumented_unsafe_blocks` lint by wrapping with
      a block. Added interim `#[allow(dead_code)]`. - Miguel ]

    [ Fixed `rusttest` by adding a dummy `LocalModule`. Removed interim
      `#[allow(dead_code)]`. - Miguel ]

    [ Rebased to avoid the imports cleanup patch. - Miguel ]

    [ Removed Acked-by and Cc. - Miguel ]

By the way, I removed the Acked-by in that last patch since I think it
came from an older version as a series-tag that didn't have the patch.
Please let me know if I should re-add it.

And since I was editing that commit for that reason, I took the chance
to remove the Cc because Petr already gave the Acked-by which you
collected, so normally you don't need to keep both in that case.

I hope that clarifies! :)

Cheers,
Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Alvin Sun 1 month, 2 weeks ago
On 8/13/26 00:33, Miguel Ojeda wrote:
> By the way, I removed the Acked-by in that last patch since I think it
> came from an older version as a series-tag that didn't have the patch.
> Please let me know if I should re-add it.

Hi Miguel,

Thanks for applying the series and catching the stray Acked-by.
It was a v5 series-tag, from before the MAINTAINERS patch existed,
so no need to re-add it. I'll be more careful with tags in future
submissions.

Best regards,
Alvin
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Thu, Aug 13, 2026 at 10:15 AM Alvin Sun <alvin.sun@linux.dev> wrote:
>
> Thanks for applying the series and catching the stray Acked-by.
> It was a v5 series-tag, from before the MAINTAINERS patch existed,
> so no need to re-add it. I'll be more careful with tags in future
> submissions.

Thanks for confirming! :)

Cheers,
Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Danilo Krummrich 1 month, 2 weeks ago
(Cc: Mark)

On Wed Aug 12, 2026 at 6:33 PM CEST, Miguel Ojeda wrote:
> On Tue, Aug 11, 2026 at 8:41 AM Alvin Sun <alvin.sun@linux.dev> wrote:
>>
>> 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 `this_module::<LocalModule>()`.
>
> Applied to `rust-next` -- thanks everyone!

This series has a semantic conflict with both the driver-core and the drm-rust
tree:

@Mark: When you merge driver-core-next after rust-next (which I think is the
case) then you need to include the diff in [1] into the merge.

In drm-rust-next the build fails with:

	error[E0425]: cannot find type `LocalModule` in the crate root
	   --> rust/kernel/drm/gem/shmem.rs:628:5
	    |
	628 |     #[vtable]
	    |     ^^^^^^^^^ not found in the crate root
	    |
	    = note: this error originates in the attribute macro `vtable` (in Nightly builds, run with -Z macro-backtrace for more info)

which is because the kunit test in rust/kernel/drm/gem/shmem.rs uses the
#[vtable] macro.

This should be fixed up with a patch on top of this series in rust-next.

I came up with to potential solutions [2] and [3]. I think with the new build
system we want [3], but I'm not entirely sure this works correctly with the
current build system in all cases (at least it did survive my tests).

Alternatively, we could just open-code a dummy module as in [2] for now.

[1] driver-core-next merge fixup

diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs
index a4927452016e..17ca504b7f8d 100644
--- a/rust/kernel/serdev.rs
+++ b/rust/kernel/serdev.rs
@@ -87,7 +87,7 @@ unsafe fn register(
         }

         // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
-        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.0) })
+        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.as_ptr()) })
     }

     unsafe fn unregister(sdrv: &Opaque<Self::DriverType>) {

[2] Open-coded dummy module

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index c04e6c5aa7e0..274924cfcc05 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -157,6 +157,15 @@
 /// Prefix to appear before log messages printed from within the `kernel` crate.
 const __LOG_PREFIX: &[u8] = b"rust_kernel\0";

+/// Dummy module type for `#[vtable]` impl blocks within the kernel crate (e.g. kunit tests).
+struct LocalModule;
+
+impl ModuleMetadata for LocalModule {
+    const NAME: &'static str::CStr = c"rust_kernel";
+    // SAFETY: `try_module_get`/`module_put` handle null module pointers gracefully.
+    const THIS_MODULE: ThisModule = unsafe { ThisModule::from_ptr(core::ptr::null_mut()) };
+}
+
 #[cfg(not(testlib))]
 #[panic_handler]
 fn panic(info: &core::panic::PanicInfo<'_>) -> ! {

[3] Allow module!() for kernel crate

diff --git a/rust/Makefile b/rust/Makefile
index 48adcd9b7851..4f6bf1b4d194 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -279,6 +279,7 @@ rustdoc-pin_init: $(src)/pin-init/src/lib.rs rustdoc-pin_init_internal \
        +$(call if_changed,rustdoc)

 rustdoc-kernel: private is-kernel-object := y
+rustdoc-kernel: private rustc_target_envs = RUST_MODFILE=kernel/lib.rs
 rustdoc-kernel: private rustc_target_flags = --extern ffi --extern pin_init \
     --extern build_error --extern macros \
     --extern bindings --extern uapi \
@@ -351,6 +352,7 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \
     rusttestlib-pin_init_internal $(obj)/$(libpin_init_internal_name) FORCE
        +$(call if_changed,rustc_test_library)

+rusttestlib-kernel: private rustc_target_envs = RUST_MODFILE=kernel/lib.rs
 rusttestlib-kernel: private rustc_target_flags = --extern ffi \
     --extern build_error --extern macros --extern pin_init \
     --extern bindings --extern uapi \
@@ -386,6 +388,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
        rm -rf $(objtree)/$(obj)/test/doctests/kernel; \
        mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
        $(rustc_target_envs) \
+       RUST_MODFILE=kernel/lib.rs \
        OBJTREE=$(abspath $(objtree)) \
        $(RUSTDOC) --test $(filter-out --remap-path-scope=%,$(rust_flags)) \
                -L$(objtree)/$(obj) --extern ffi --extern pin_init \
@@ -788,6 +791,7 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \
     $(obj)/uapi/uapi_generated.rs FORCE
        +$(call if_changed_rule,rustc_library)

+$(obj)/kernel.o: private rustc_target_envs = RUST_MODFILE=kernel/lib.rs
 $(obj)/kernel.o: private rustc_target_flags = --extern ffi --extern pin_init \
     --extern build_error --extern macros --extern bindings --extern uapi \
     --extern zerocopy --extern zerocopy_derive
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index c04e6c5aa7e0..7df9159788ad 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -154,8 +154,21 @@
 };
 pub use uapi;

-/// Prefix to appear before log messages printed from within the `kernel` crate.
-const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
+struct KernelCrateModule;
+
+impl Module for KernelCrateModule {
+    fn init(_module: &'static ThisModule) -> error::Result<Self> {
+        Ok(Self)
+    }
+}
+
+macros::module! {
+    type: KernelCrateModule,
+    name: "rust_kernel",
+    authors: ["Rust for Linux Contributors"],
+    description: "The kernel crate",
+    license: "GPL",
+}

 #[cfg(not(testlib))]
 #[panic_handler]
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Wed, Aug 12, 2026 at 11:53 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> This series has a semantic conflict with both the driver-core and the drm-rust
> tree:
>
> @Mark: When you merge driver-core-next after rust-next (which I think is the
> case) then you need to include the diff in [1] into the merge.

Mark: in case it helps to make it clearer and so you don't have to
read much, that [1] diff still needs to be included (i.e. the rest of
the discussion and the commit I added is independent).

Thanks!

Cheers,
Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Gary Guo 1 month, 2 weeks ago
On Wed Aug 12, 2026 at 10:53 PM BST, Danilo Krummrich wrote:
> (Cc: Mark)
>
> On Wed Aug 12, 2026 at 6:33 PM CEST, Miguel Ojeda wrote:
>> On Tue, Aug 11, 2026 at 8:41 AM Alvin Sun <alvin.sun@linux.dev> wrote:
>>>
>>> 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 `this_module::<LocalModule>()`.
>>
>> Applied to `rust-next` -- thanks everyone!
>
> This series has a semantic conflict with both the driver-core and the drm-rust
> tree:
>
> @Mark: When you merge driver-core-next after rust-next (which I think is the
> case) then you need to include the diff in [1] into the merge.
>
> In drm-rust-next the build fails with:
>
> 	error[E0425]: cannot find type `LocalModule` in the crate root
> 	   --> rust/kernel/drm/gem/shmem.rs:628:5
> 	    |
> 	628 |     #[vtable]
> 	    |     ^^^^^^^^^ not found in the crate root
> 	    |
> 	    = note: this error originates in the attribute macro `vtable` (in Nightly builds, run with -Z macro-backtrace for more info)
>
> which is because the kunit test in rust/kernel/drm/gem/shmem.rs uses the
> #[vtable] macro.
>
> This should be fixed up with a patch on top of this series in rust-next.
>
> I came up with to potential solutions [2] and [3]. I think with the new build
> system we want [3], but I'm not entirely sure this works correctly with the
> current build system in all cases (at least it did survive my tests).
>
> Alternatively, we could just open-code a dummy module as in [2] for now.
>
> [1] driver-core-next merge fixup
>
> diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs
> index a4927452016e..17ca504b7f8d 100644
> --- a/rust/kernel/serdev.rs
> +++ b/rust/kernel/serdev.rs
> @@ -87,7 +87,7 @@ unsafe fn register(
>          }
>
>          // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
> -        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.0) })
> +        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.as_ptr()) })

`module.0` shouldn't be used in the first place, it just happens to be visible
due to the unfortunate placement at crate root.

Perhaps you can update driver-core tree to use `as_ptr()`? It was already there
and not newly introduced in the series.

>      }
>
>      unsafe fn unregister(sdrv: &Opaque<Self::DriverType>) {
>
> [2] Open-coded dummy module
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index c04e6c5aa7e0..274924cfcc05 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -157,6 +157,15 @@
>  /// Prefix to appear before log messages printed from within the `kernel` crate.
>  const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
>
> +/// Dummy module type for `#[vtable]` impl blocks within the kernel crate (e.g. kunit tests).
> +struct LocalModule;
> +
> +impl ModuleMetadata for LocalModule {
> +    const NAME: &'static str::CStr = c"rust_kernel";
> +    // SAFETY: `try_module_get`/`module_put` handle null module pointers gracefully.
> +    const THIS_MODULE: ThisModule = unsafe { ThisModule::from_ptr(core::ptr::null_mut()) };
> +}
> +
>  #[cfg(not(testlib))]
>  #[panic_handler]
>  fn panic(info: &core::panic::PanicInfo<'_>) -> ! {

IMO this is the correct way, also consistent with

https://lore.kernel.org/rust-for-linux/20260811-fix-fops-owner-v10-3-7e71776f9dbe@linux.dev/

It might make sense to add this to rust-next.

Best,
Gary
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Thu, Aug 13, 2026 at 1:57 AM Gary Guo <gary@garyguo.net> wrote:
>
> IMO this is the correct way, also consistent with
>
> https://lore.kernel.org/rust-for-linux/20260811-fix-fops-owner-v10-3-7e71776f9dbe@linux.dev/
>
> It might make sense to add this to rust-next.

Yeah, it is also consistent (in the sense of adding a fallback) with
the other fix I added when applying the series for the `macros`
doctest; and the `kernel` crate is not an actual module yet.

I guess yet another solution would be to have an even more local
fallback, but that would be too local in my opinion, i.e. we will want
to use it elsewhere sooner or later.

So I could fold [2] into commit 98f256e27262, but a commit on top is
fine, I will reference that commit from the new one instead.

Ok, done -- Danilo, I took your diff and converted it into a proper
commit, please double-check you are OK with the Signed-off-by:

  ec6fcf8a175a ("rust: kernel: add `LocalModule` fallback for
`#[vtable]` `impl`s")

Thanks!

Cheers,
Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Alvin Sun 1 month, 2 weeks ago
On 8/13/26 17:32, Miguel Ojeda wrote:
> On Thu, Aug 13, 2026 at 1:57 AM Gary Guo <gary@garyguo.net> wrote:
>> IMO this is the correct way, also consistent with
>>
>> https://lore.kernel.org/rust-for-linux/20260811-fix-fops-owner-v10-3-7e71776f9dbe@linux.dev/
>>
>> It might make sense to add this to rust-next.
> Yeah, it is also consistent (in the sense of adding a fallback) with
> the other fix I added when applying the series for the `macros`
> doctest; and the `kernel` crate is not an actual module yet.
>
> I guess yet another solution would be to have an even more local
> fallback, but that would be too local in my opinion, i.e. we will want
> to use it elsewhere sooner or later.
>
> So I could fold [2] into commit 98f256e27262, but a commit on top is
> fine, I will reference that commit from the new one instead.
>
> Ok, done -- Danilo, I took your diff and converted it into a proper
> commit, please double-check you are OK with the Signed-off-by:
>
>    ec6fcf8a175a ("rust: kernel: add `LocalModule` fallback for
> `#[vtable]` `impl`s")

I was just looking at the difference between the doctest and in-crate
`#[kunit_tests]` test paths — thanks for taking care of this.

I'll look into [3] once the new build system lands.

Best regards,
Alvin

>
> Thanks!
>
> Cheers,
> Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Thu, Aug 13, 2026 at 11:32 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Ok, done -- Danilo, I took your diff and converted it into a proper
> commit, please double-check you are OK with the Signed-off-by:
>
>   ec6fcf8a175a ("rust: kernel: add `LocalModule` fallback for
> `#[vtable]` `impl`s")

We also need an `allow(dead_code)` until we actually use it
unconditionally: a2595ed13816 instead.

Cheers,
Miguel
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Danilo Krummrich 1 month, 2 weeks ago
On Thu Aug 13, 2026 at 11:32 AM CEST, Miguel Ojeda wrote:
> Ok, done -- Danilo, I took your diff and converted it into a proper
> commit, please double-check you are OK with the Signed-off-by:

Of course, thanks!

- Danilo
Re: [PATCH v10 00/10] Fix missing fops.owner in Rust DRM/misc abstractions
Posted by Danilo Krummrich 1 month, 2 weeks ago
On Thu Aug 13, 2026 at 1:57 AM CEST, Gary Guo wrote:
> On Wed Aug 12, 2026 at 10:53 PM BST, Danilo Krummrich wrote:
>> (Cc: Mark)
>>
>> On Wed Aug 12, 2026 at 6:33 PM CEST, Miguel Ojeda wrote:
>>> On Tue, Aug 11, 2026 at 8:41 AM Alvin Sun <alvin.sun@linux.dev> wrote:
>>>>
>>>> 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 `this_module::<LocalModule>()`.
>>>
>>> Applied to `rust-next` -- thanks everyone!
>>
>> This series has a semantic conflict with both the driver-core and the drm-rust
>> tree:
>>
>> @Mark: When you merge driver-core-next after rust-next (which I think is the
>> case) then you need to include the diff in [1] into the merge.
>>
>> In drm-rust-next the build fails with:
>>
>> 	error[E0425]: cannot find type `LocalModule` in the crate root
>> 	   --> rust/kernel/drm/gem/shmem.rs:628:5
>> 	    |
>> 	628 |     #[vtable]
>> 	    |     ^^^^^^^^^ not found in the crate root
>> 	    |
>> 	    = note: this error originates in the attribute macro `vtable` (in Nightly builds, run with -Z macro-backtrace for more info)
>>
>> which is because the kunit test in rust/kernel/drm/gem/shmem.rs uses the
>> #[vtable] macro.
>>
>> This should be fixed up with a patch on top of this series in rust-next.
>>
>> I came up with to potential solutions [2] and [3]. I think with the new build
>> system we want [3], but I'm not entirely sure this works correctly with the
>> current build system in all cases (at least it did survive my tests).
>>
>> Alternatively, we could just open-code a dummy module as in [2] for now.
>>
>> [1] driver-core-next merge fixup
>>
>> diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs
>> index a4927452016e..17ca504b7f8d 100644
>> --- a/rust/kernel/serdev.rs
>> +++ b/rust/kernel/serdev.rs
>> @@ -87,7 +87,7 @@ unsafe fn register(
>>          }
>>
>>          // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
>> -        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.0) })
>> +        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.as_ptr()) })
>
> `module.0` shouldn't be used in the first place, it just happens to be visible
> due to the unfortunate placement at crate root.
>
> Perhaps you can update driver-core tree to use `as_ptr()`? It was already there
> and not newly introduced in the series.

Heh, I just remembered that patch 1 of this series did fix this in a couple of
places and assumed that it was introduced in the same patch without looking
further.

In that case I can throw in a patch in the driver-core tree; will send it
tomorrow.

>>      }
>>
>>      unsafe fn unregister(sdrv: &Opaque<Self::DriverType>) {
>>
>> [2] Open-coded dummy module
>>
>> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
>> index c04e6c5aa7e0..274924cfcc05 100644
>> --- a/rust/kernel/lib.rs
>> +++ b/rust/kernel/lib.rs
>> @@ -157,6 +157,15 @@
>>  /// Prefix to appear before log messages printed from within the `kernel` crate.
>>  const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
>>
>> +/// Dummy module type for `#[vtable]` impl blocks within the kernel crate (e.g. kunit tests).
>> +struct LocalModule;
>> +
>> +impl ModuleMetadata for LocalModule {
>> +    const NAME: &'static str::CStr = c"rust_kernel";
>> +    // SAFETY: `try_module_get`/`module_put` handle null module pointers gracefully.
>> +    const THIS_MODULE: ThisModule = unsafe { ThisModule::from_ptr(core::ptr::null_mut()) };
>> +}
>> +
>>  #[cfg(not(testlib))]
>>  #[panic_handler]
>>  fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
>
> IMO this is the correct way, also consistent with
>
> https://lore.kernel.org/rust-for-linux/20260811-fix-fops-owner-v10-3-7e71776f9dbe@linux.dev/
>
> It might make sense to add this to rust-next.

I feel like [3] is the superior solution (just unsure about the build system
implications); once we have the new build system some subsystem crates will be
actual modules, some will be always built-in. So, in general I think we want to
use the module!() macro.