aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 11:25:09 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 11:25:09 -0700
commitd24f5cdbeff8b6a063fca92d0a1f94122a799b59 (patch)
tree1c0c344db3c18572d7176c7caec4a8abdd295647
parent2df813c9a6b6704b75aec7538d2225292e6b6fe6 (diff)
parent47f27155f17498fccb1f222f79089642337498a9 (diff)
Merge tag 'rust-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Warn when using 'bindgen' < 0.72.1 with 'libclang' >= 22, since that combination may fail to build. It includes a probe for the bug in case 'bindgen' happens to be patched, and tests In parallel, Nathan updated the instructions for the kernel.org LLVM+Rust toolchains so that the latest version of 'bindgen' is installed, which should avoid some of these situations - Support testing 'rust_is_available.sh' with 'bash' as '/bin/sh' - Fix an objtool warning by adding one more 'noreturn' function for Rust 1.99.0 (expected 2026-10-01) - Fix build error in the 'rusttest' target due to ambiguity when the 'rustc-dev' component is installed, which was uncovered by the work to support Rust's GCC backend ('rustc_codegen_gcc') - Fix future Clang warnings in the upcoming powerpc support due to macro redefinitions in the UAPI helper header by including the arch-aware 'ioctl.h' header 'kernel' crate: - Rework module ownership support: - Move the module-related types into a new 'module' module and make the 'THIS_MODULE' pointer a constant of 'ModuleMetadata' so that modules can provide the pointer in const contexts, and add a 'this_module' 'const fn' to retrieve it This was enabled by upstream Rust's work on the 'const_mut_refs' and 'const_refs_to_static' features which were stabilized back in Rust 1.83.0 - Teach '#[vtable]' to associate implementations with their owning module, defaulting to the local one, including fallbacks for doctests, uses within the 'kernel' crate (like upcoming KUnit '#[test]'s for DRM) and 'rusttest' - Set 'fops.owner' from the module pointer for DRM and miscdevice - Migrate Rust Binder and configfs away from the old 'THIS_MODULE' 'static' and finally remove it from the 'module!' macro - 'num' module: - Add the new 'casts' module for lossless integer conversions Rust's 'core' library's 'From' implementations do not cover conversions that are not portable or future-proof. However, the kernel supports a narrower set of architectures, which makes it helpful to provide more infallible conversions, instead of having developers use 'as' casts, which carry the risk of silently losing data This goes along with previous work we did to avoid casts in Rust kernel code since they are more powerful than needed Thus, provide safe 'const' conversion functions (e.g. 'usize_as_u64' and 'u64_into_u8'), as well as the 'FromSafeCast' and 'IntoSafeCast' extension traits that provide conversions that are known to be lossless in the kernel, and an 'arch' submodule defining conversions that are known to be lossless on particular architectures (e.g. 64-bit platforms). For instance: // Conversion in const context. const USIZED_CONST: usize = u8_as_usize(255u8); // Non-const conversions. let a = u64::from_safe_cast(4096usize); let b: u64 = 4096usize.into_safe_cast(); - Add 'Bounded::shr_exact' method in the vein of 'try_shrink' which shifts a bounded right only if it loses no set bits - Fix unsoundness issue in the 'Bounded::shr' method by rejecting, at compile-time, shifts of at least the type's bit width - 'fmt' module: - Route '{:p}' raw pointer formatting through the kernel's hashed '%p' format to prevent address leaks, including support for width and padding. Include tests for both 'no_hash_pointers' case and the default (hashed) one - Fix the '{:p}' forwarding implementation, which could print the address of a temporary stack variable - 'time' module: - Make 'Delta' generic over its time unit, with a default unit of nanoseconds ('Nsec'), preserving the existing behavior. Then, add a 'Jiffy' time unit - Add the 'Delta::as_millis_ceil()' method - Fix 'as_micros_ceil()' rounding near 'i64::MAX', which could yield a result one microsecond too small - 'sync' module: - Implement 'ForeignOwnable' for 'ARef<T>', allowing C code to own an 'ARef<T>' - Add a safe abstraction for 'rcu_barrier()' - 'error' module: add all of the remaining error codes, except the deprecated compatibility aliases - 'bug' module: - Fix build error on UML in 'warn_on!' for callers from within the 'kernel' crate - Fix future 'dead_code' warning on arm and loongarch64 and under 'CONFIG_BUG=n' in 'warn_on!', which would trigger with the upcoming SRCU abstractions - Fix future build error in 'rusttest' on cross-compilation cases, which would trigger when 'warn_on!' has callers inside the 'kernel' crate - 'bitfield' module: fix build error for the upcoming support for Rust's GCC backend ('rustc_codegen_gcc') by always inlining a couple conversions used in tests 'pin-init' crate: - User-visible changes: - Merge the '__pinned_init' and '__init' methods and make 'Init' a marker trait - Introduce public APIs 'raw_init' and 'raw_try_init' to prevent users from needing to invoke the internal '__pinned_init' and '__init' methods - Emit errors for duplicate '#[pin]' attributes - Link 'Zeroable::zeroed' and 'pin_init::zeroed' in documentation - Other changes: - Fix unwind safety issues - Clean up lint 'allow' and 'expect's - Overhaul '#[cfg]' handling to pave the way for tuple structs and self-referential structs - Mark many functions as '#[inline]' for better codegen with '-C opt-level=s' ('CC_OPTIMIZE_FOR_SIZE') 'MAINTAINERS': - Update 'MODULE SUPPORT' to cover the new 'module' module And some other fixes, cleanups and improvements" * tag 'rust-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (54 commits) rust: add functions and traits for lossless integer conversions rust: kernel: add `LocalModule` fallback for `#[vtable]` `impl`s rust: fmt: route {:p} through HashedPtr to prevent address leaks rust: fmt: fix {:p} printing stack addresses rust: module: update MAINTAINERS to cover module.rs rust: macros: remove `THIS_MODULE` static from `module!` rust_binder: use `LocalModule` for `THIS_MODULE` rust: configfs: use `LocalModule` for `THIS_MODULE` rust: miscdevice: set fops.owner from driver module pointer rust: drm: set fops.owner from driver module pointer rust: macros: auto-insert OwnerModule in #[vtable] rust: doctest: add LocalModule fallback for #[vtable] ThisModule rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait rust: module: move module types into `module.rs` rust: num: add Bounded::shr_exact rust: num: reject Bounded::shr overshifts at build time rust: num: use const_assert! in Bounded rust: uapi: replace direct asm-generic/ioctl.h include with linux/ioctl.h rust: time: add Delta::as_millis_ceil() rust: time: add jiffies time unit for Delta ...
-rw-r--r--Documentation/rust/quick-start.rst2
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/android/binder/rust_binder_main.rs3
-rw-r--r--drivers/block/rnull/configfs.rs2
-rw-r--r--drivers/gpu/nova-core/gsp/cmdq.rs4
-rw-r--r--rust/Makefile2
-rw-r--r--rust/kernel/alloc/kbox.rs8
-rw-r--r--rust/kernel/auxiliary.rs2
-rw-r--r--rust/kernel/bitfield.rs2
-rw-r--r--rust/kernel/bug.rs34
-rw-r--r--rust/kernel/configfs.rs9
-rw-r--r--rust/kernel/dma.rs10
-rw-r--r--rust/kernel/drm/device.rs5
-rw-r--r--rust/kernel/drm/gem/mod.rs4
-rw-r--r--rust/kernel/drm/gpuvm/va.rs2
-rw-r--r--rust/kernel/drm/gpuvm/vm_bo.rs2
-rw-r--r--rust/kernel/error.rs102
-rw-r--r--rust/kernel/fmt.rs195
-rw-r--r--rust/kernel/i2c.rs2
-rw-r--r--rust/kernel/impl_flags.rs11
-rw-r--r--rust/kernel/init.rs6
-rw-r--r--rust/kernel/lib.rs81
-rw-r--r--rust/kernel/miscdevice.rs4
-rw-r--r--rust/kernel/module.rs80
-rw-r--r--rust/kernel/net/phy.rs6
-rw-r--r--rust/kernel/num.rs2
-rw-r--r--rust/kernel/num/bounded.rs36
-rw-r--r--rust/kernel/num/casts.rs298
-rw-r--r--rust/kernel/pci.rs2
-rw-r--r--rust/kernel/platform.rs2
-rw-r--r--rust/kernel/print.rs2
-rw-r--r--rust/kernel/pwm.rs2
-rw-r--r--rust/kernel/sync/arc.rs20
-rw-r--r--rust/kernel/sync/aref.rs50
-rw-r--r--rust/kernel/sync/rcu.rs20
-rw-r--r--rust/kernel/time.rs141
-rw-r--r--rust/kernel/types.rs8
-rw-r--r--rust/kernel/usb.rs2
-rw-r--r--rust/macros/lib.rs18
-rw-r--r--rust/macros/module.rs36
-rw-r--r--rust/macros/vtable.rs41
-rw-r--r--rust/pin-init/examples/mutex.rs11
-rw-r--r--rust/pin-init/examples/static_init.rs10
-rw-r--r--rust/pin-init/internal/src/init.rs8
-rw-r--r--rust/pin-init/internal/src/pin_data.rs94
-rw-r--r--rust/pin-init/src/__internal.rs13
-rw-r--r--rust/pin-init/src/alloc.rs10
-rw-r--r--rust/pin-init/src/lib.rs333
-rw-r--r--rust/uapi/uapi_helper.h2
-rwxr-xr-xscripts/rust_is_available.sh14
-rw-r--r--scripts/rust_is_available_bindgen_libclang_22.h5
-rwxr-xr-xscripts/rust_is_available_test.py46
-rw-r--r--scripts/rustdoc_test_gen.rs29
-rw-r--r--tools/objtool/check.c1
54 files changed, 1460 insertions, 376 deletions
diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst
index a6ec3fa94d33..f79aa3c7138e 100644
--- a/Documentation/rust/quick-start.rst
+++ b/Documentation/rust/quick-start.rst
@@ -90,7 +90,7 @@ they should generally work out of the box, e.g.::
Ubuntu
******
-Ubuntu 25.10 and 26.04 LTS provide recent Rust releases and thus they should
+Ubuntu 26.04 LTS provides recent Rust releases and thus it should
generally work out of the box, e.g.::
apt install rustc rust-src bindgen rustfmt rust-clippy
diff --git a/MAINTAINERS b/MAINTAINERS
index 0a1ba8f21b1c..1d93f008fb33 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18179,7 +18179,7 @@ F: include/linux/module*.h
F: kernel/module/
F: lib/test_kmod.c
F: lib/tests/module/
-F: rust/kernel/module_param.rs
+F: rust/kernel/module*.rs
F: rust/macros/module.rs
F: scripts/module*
F: tools/testing/selftests/kmod/
diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index dc1941cd2407..d6ceebbd5f94 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -17,6 +17,7 @@ use kernel::{
bindings::{self, seq_file},
fs::File,
list::{ListArc, ListArcSafe, ListLinksSelfPtr, TryNewListArc},
+ module::this_module,
prelude::*,
seq_file::SeqFile,
seq_print,
@@ -318,7 +319,7 @@ pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = {
let zeroed_ops = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
let ops = kernel::bindings::file_operations {
- owner: THIS_MODULE.as_ptr(),
+ owner: this_module::<LocalModule>().as_ptr(),
poll: Some(rust_binder_poll),
unlocked_ioctl: Some(rust_binder_ioctl),
compat_ioctl: bindings::compat_ptr_ioctl,
diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index 7c2eb5c0b722..32c10c3f4d0f 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},
configfs::{self, AttributeOperations},
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 070de0731e95..3c68a66770d3 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -645,8 +645,8 @@ impl CmdqInner {
// SAFETY: `msg_header` and `cmd` are valid references, and not touched if the initializer
// fails.
unsafe {
- msg_element.__init(core::ptr::from_mut(dst.header))?;
- command.init().__init(core::ptr::from_mut(cmd))?;
+ pin_init::raw_try_init(core::ptr::from_mut(dst.header), msg_element)?;
+ pin_init::raw_try_init(core::ptr::from_mut(cmd), command.init())?;
}
// Fill the variable-length payload, which may be empty.
diff --git a/rust/Makefile b/rust/Makefile
index 627ed79dc6f5..fbe0accc51a3 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -350,7 +350,7 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \
rusttestlib-kernel: private rustc_target_flags = --extern ffi \
--extern build_error --extern macros --extern pin_init \
--extern bindings --extern uapi \
- --extern zerocopy --extern zerocopy_derive
+ --extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib --extern zerocopy_derive
rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \
rusttestlib-build_error rusttestlib-pin_init $(obj)/$(libmacros_name) \
$(obj)/bindings.o rusttestlib-zerocopy rusttestlib-zerocopy_derive FORCE
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 35d1e015848d..c63d6acdbb6f 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -372,13 +372,13 @@ where
// - `ptr` is a valid pointer to uninitialized memory.
// - `ptr` is not used if an error is returned.
// - `ptr` won't be moved until it is dropped, i.e. it is pinned.
- unsafe { init(i).__pinned_init(ptr)? };
+ unsafe { pin_init::raw_try_init(ptr, init(i))? };
// SAFETY:
// - `i + 1 <= len`, hence we don't exceed the capacity, due to the call to
// `with_capacity()` above.
// - The new value at index buffer.len() + 1 is the only element being added here, and
- // it has been initialized above by `init(i).__pinned_init(ptr)`.
+ // it has been initialized above by `raw_try_init(ptr, i)`.
unsafe { buffer.inc_len(1) };
}
@@ -463,7 +463,7 @@ where
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid.
- unsafe { init.__init(slot)? };
+ unsafe { pin_init::raw_try_init(slot, init)? };
// SAFETY: All fields have been initialized.
Ok(unsafe { Box::assume_init(self) })
}
@@ -473,7 +473,7 @@ where
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid and will not be moved, because we pin it later.
- unsafe { init.__pinned_init(slot)? };
+ unsafe { pin_init::raw_try_init(slot, init)? };
// SAFETY: All fields have been initialized.
Ok(unsafe { Box::assume_init(self) }.into())
}
diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index c42928d5a239..cc9745fbf179 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -69,7 +69,7 @@ unsafe impl<T: Driver> driver::RegistrationOps for Adapter<T> {
// SAFETY: `adrv` is guaranteed to be a valid `DriverType`.
to_result(unsafe {
- bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr())
+ bindings::__auxiliary_driver_register(adrv.get(), module.as_ptr(), name.as_char_ptr())
})
}
diff --git a/rust/kernel/bitfield.rs b/rust/kernel/bitfield.rs
index 35ede53f2b8e..a0d089423f21 100644
--- a/rust/kernel/bitfield.rs
+++ b/rust/kernel/bitfield.rs
@@ -581,6 +581,7 @@ mod tests {
}
impl From<MemoryType> for Bounded<u64, 4> {
+ #[inline(always)]
fn from(mt: MemoryType) -> Bounded<u64, 4> {
Bounded::from_expr(mt as u64)
}
@@ -606,6 +607,7 @@ mod tests {
}
impl From<Priority> for Bounded<u16, 2> {
+ #[inline(always)]
fn from(p: Priority) -> Bounded<u16, 2> {
Bounded::from_expr(p as u16)
}
diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
index ed943960f851..3566f0234ca4 100644
--- a/rust/kernel/bug.rs
+++ b/rust/kernel/bug.rs
@@ -8,6 +8,7 @@
#[macro_export]
#[doc(hidden)]
+#[cfg(not(testlib))]
#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]
#[cfg(CONFIG_DEBUG_BUGVERBOSE)]
macro_rules! warn_flags {
@@ -47,12 +48,17 @@ macro_rules! warn_flags {
#[macro_export]
#[doc(hidden)]
+#[cfg(not(testlib))]
#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]
#[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]
macro_rules! warn_flags {
($file:expr, $flags:expr) => {
const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
+ if false {
+ _ = $file;
+ }
+
// SAFETY:
// - `flags` and `size` are all compile-time constants, preventing
// any invalid memory access.
@@ -73,14 +79,19 @@ macro_rules! warn_flags {
#[macro_export]
#[doc(hidden)]
+#[cfg(not(testlib))]
#[cfg(all(CONFIG_BUG, CONFIG_UML))]
macro_rules! warn_flags {
($file:expr, $flags:expr) => {
+ if false {
+ _ = $file;
+ }
+
// SAFETY: It is always safe to call `warn_slowpath_fmt()`
// with a valid null-terminated string.
unsafe {
$crate::bindings::warn_slowpath_fmt(
- $crate::c_str!(::core::file!()).as_char_ptr(),
+ $crate::str::CStrExt::as_char_ptr($crate::c_str!(::core::file!())),
line!() as $crate::ffi::c_int,
$flags as $crate::ffi::c_uint,
::core::ptr::null(),
@@ -91,9 +102,15 @@ macro_rules! warn_flags {
#[macro_export]
#[doc(hidden)]
+#[cfg(not(testlib))]
#[cfg(all(CONFIG_BUG, any(CONFIG_LOONGARCH, CONFIG_ARM)))]
macro_rules! warn_flags {
($file:expr, $flags:expr) => {
+ if false {
+ _ = $file;
+ _ = $flags;
+ }
+
// SAFETY: It is always safe to call `WARN_ON()`.
unsafe { $crate::bindings::WARN_ON(true) }
};
@@ -101,9 +118,14 @@ macro_rules! warn_flags {
#[macro_export]
#[doc(hidden)]
-#[cfg(not(CONFIG_BUG))]
+#[cfg(any(testlib, not(CONFIG_BUG)))]
macro_rules! warn_flags {
- ($file:expr, $flags:expr) => {};
+ ($file:expr, $flags:expr) => {
+ if false {
+ _ = $file;
+ _ = $flags;
+ }
+ };
}
#[doc(hidden)]
@@ -118,14 +140,14 @@ macro_rules! warn_on {
let cond = $cond;
#[cfg(CONFIG_DEBUG_BUGVERBOSE_DETAILED)]
- const _COND_STR: &str = concat!("[", stringify!($cond), "] ", file!());
+ const COND_STR: &str = concat!("[", stringify!($cond), "] ", file!());
#[cfg(not(CONFIG_DEBUG_BUGVERBOSE_DETAILED))]
- const _COND_STR: &str = file!();
+ const COND_STR: &str = file!();
if cond {
const WARN_ON_FLAGS: u32 = $crate::bug::bugflag_taint($crate::bindings::TAINT_WARN);
- $crate::warn_flags!(_COND_STR, WARN_ON_FLAGS);
+ $crate::warn_flags!(COND_STR, WARN_ON_FLAGS);
}
cond
}};
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 2339c6467325..cd082b83e9e7 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -875,13 +875,14 @@ impl<Container, Data> ItemType<Container, Data> {
/// configfs::Subsystem<Configuration>,
/// Configuration
/// >::new_with_child_ctor::<N,Child>(
-/// &THIS_MODULE,
+/// ::kernel::module::this_module::<crate::LocalModule>(),
/// &CONFIGURATION_ATTRS
/// );
///
/// &CONFIGURATION_TPE
/// }
/// ```
+#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! configfs_attrs {
(
@@ -1021,7 +1022,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 >]
+ $crate::module::this_module::<crate::LocalModule>(),
+ &[<$ data:upper _ATTRS >]
);
)?
@@ -1030,7 +1032,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 >]
+ $crate::module::this_module::<crate::LocalModule>(),
+ &[<$ data:upper _ATTRS >]
);
)?
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 200def84fb69..8e36a4e7f514 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -449,7 +449,7 @@ impl<T: AsBytes + FromBytes> CoherentBox<[T]> {
// - `T: AsBytes + FromBytes` guarantees all bit patterns are valid, so partial writes on
// error cannot leave the element in an invalid state.
// - The DMA address has not been exposed yet, so there is no concurrent device access.
- unsafe { init.__init(ptr)? };
+ unsafe { pin_init::raw_try_init(ptr, init)? };
Ok(())
}
@@ -791,10 +791,10 @@ impl<T: AsBytes + FromBytes> Coherent<T> {
// SAFETY:
// - `ptr` is valid, properly aligned, and points to exclusively owned memory.
- // - If `__init` fails, `self` is dropped, which safely frees the underlying `Coherent`'s
- // DMA memory. `T: AsBytes + FromBytes` ensures there are no complex `Drop` requirements
- // we are bypassing.
- unsafe { init.__init(ptr)? };
+ // - If `raw_try_init` fails, `self` is dropped, which safely frees the underlying
+ // `Coherent`'s DMA memory. `T: AsBytes + FromBytes` ensures there are no complex `Drop`
+ // requirements we are bypassing.
+ unsafe { pin_init::raw_try_init(ptr, init)? };
Ok(dmem)
}
diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 477cf771fb10..81f9f7e59817 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -203,7 +203,8 @@ impl<T: drm::Driver> UnregisteredDevice<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(crate::module::this_module::<T::OwnerModule>().as_ptr());
/// Create a new `UnregisteredDevice` for a `drm::Driver`.
///
@@ -244,7 +245,7 @@ impl<T: drm::Driver> UnregisteredDevice<T> {
// SAFETY:
// - `raw_data` is a valid pointer to uninitialized memory.
// - `raw_data` will not move until it is dropped.
- unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| {
+ unsafe { pin_init::raw_try_init(raw_data, data) }.inspect_err(|_| {
// SAFETY: `__drm_dev_alloc()` was successful, hence `drm_dev` must be valid and the
// refcount must be non-zero.
unsafe { bindings::drm_dev_put(drm_dev) };
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index c8b66d816871..a7ba1453d40b 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -387,10 +387,10 @@ impl<T: DriverObject, Ctx: DeviceContext> AllocImpl for Object<T, Ctx> {
};
}
-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);
diff --git a/rust/kernel/drm/gpuvm/va.rs b/rust/kernel/drm/gpuvm/va.rs
index 0b09fe44ab39..bf927b8e6fbb 100644
--- a/rust/kernel/drm/gpuvm/va.rs
+++ b/rust/kernel/drm/gpuvm/va.rs
@@ -116,7 +116,7 @@ impl<T: DriverGpuVm> GpuVaAlloc<T> {
pub(super) fn prepare(mut self, va_data: impl PinInit<T::VaData>) -> *mut bindings::drm_gpuva {
let va_ptr = MaybeUninit::as_mut_ptr(&mut self.0);
// SAFETY: The `data` field is pinned.
- let Ok(()) = unsafe { va_data.__pinned_init(&raw mut (*va_ptr).data) };
+ unsafe { pin_init::raw_init(&raw mut (*va_ptr).data, va_data) };
KBox::into_raw(self.0).cast()
}
}
diff --git a/rust/kernel/drm/gpuvm/vm_bo.rs b/rust/kernel/drm/gpuvm/vm_bo.rs
index c064ac63897b..ab12b710267e 100644
--- a/rust/kernel/drm/gpuvm/vm_bo.rs
+++ b/rust/kernel/drm/gpuvm/vm_bo.rs
@@ -181,7 +181,7 @@ impl<T: DriverGpuVm> GpuVmBoAlloc<T> {
};
let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
// SAFETY: `ptr->data` is a valid pinned location.
- let Ok(()) = unsafe { value.__pinned_init(&raw mut (*raw_ptr).data) };
+ unsafe { pin_init::raw_init(&raw mut (*raw_ptr).data, value) };
// INVARIANTS: We just created the vm_bo so it's absent from lists, and the data is valid
// as we just initialized it.
Ok(GpuVmBoAlloc(ptr))
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
index a56ba6309594..e52793f77196 100644
--- a/rust/kernel/error.rs
+++ b/rust/kernel/error.rs
@@ -30,6 +30,7 @@ pub mod code {
};
}
+ // From `include/uapi/asm-generic/errno-base.h`.
declare_err!(EPERM, "Operation not permitted.");
declare_err!(ENOENT, "No such file or directory.");
declare_err!(ESRCH, "No such process.");
@@ -64,9 +65,110 @@ pub mod code {
declare_err!(EPIPE, "Broken pipe.");
declare_err!(EDOM, "Math argument out of domain of func.");
declare_err!(ERANGE, "Math result not representable.");
+
+ // From `include/uapi/asm-generic/errno.h`.
+ declare_err!(EDEADLK, "Resource deadlock would occur.")