2024-10-04 15:41:15 +00:00
|
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
|
|
|
|
|
|
|
//! Implementation of [`Box`].
|
|
|
|
|
|
|
|
|
|
|
|
#[allow(unused_imports)] // Used in doc comments.
|
|
|
|
|
|
use super::allocator::{KVmalloc, Kmalloc, Vmalloc};
|
|
|
|
|
|
use super::{AllocError, Allocator, Flags};
|
|
|
|
|
|
use core::alloc::Layout;
|
2025-06-16 03:34:07 +00:00
|
|
|
|
use core::borrow::{Borrow, BorrowMut};
|
2024-10-04 15:41:15 +00:00
|
|
|
|
use core::fmt;
|
|
|
|
|
|
use core::marker::PhantomData;
|
|
|
|
|
|
use core::mem::ManuallyDrop;
|
|
|
|
|
|
use core::mem::MaybeUninit;
|
|
|
|
|
|
use core::ops::{Deref, DerefMut};
|
|
|
|
|
|
use core::pin::Pin;
|
|
|
|
|
|
use core::ptr::NonNull;
|
|
|
|
|
|
use core::result::Result;
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
use crate::ffi::c_void;
|
2025-03-08 11:05:09 +00:00
|
|
|
|
use crate::init::InPlaceInit;
|
2024-10-04 15:41:15 +00:00
|
|
|
|
use crate::types::ForeignOwnable;
|
2025-03-08 11:05:09 +00:00
|
|
|
|
use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
|
2024-10-04 15:41:15 +00:00
|
|
|
|
|
|
|
|
|
|
/// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// This is the kernel's version of the Rust stdlib's `Box`. There are several differences,
|
|
|
|
|
|
/// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not
|
|
|
|
|
|
/// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`]
|
|
|
|
|
|
/// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions
|
|
|
|
|
|
/// that may allocate memory are fallible.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`].
|
|
|
|
|
|
/// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]).
|
|
|
|
|
|
///
|
|
|
|
|
|
/// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let b = KBox::<u64>::new(24_u64, GFP_KERNEL)?;
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*b, 24_u64);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// # use kernel::bindings;
|
|
|
|
|
|
/// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1;
|
|
|
|
|
|
/// struct Huge([u8; SIZE]);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert!(KBox::<Huge>::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err());
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// # use kernel::bindings;
|
|
|
|
|
|
/// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1;
|
|
|
|
|
|
/// struct Huge([u8; SIZE]);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok());
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
///
|
2025-04-12 06:29:13 +00:00
|
|
|
|
/// [`Box`]es can also be used to store trait objects by coercing their type:
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// trait FooTrait {}
|
|
|
|
|
|
///
|
|
|
|
|
|
/// struct FooStruct;
|
|
|
|
|
|
/// impl FooTrait for FooStruct {}
|
|
|
|
|
|
///
|
|
|
|
|
|
/// let _ = KBox::new(FooStruct, GFP_KERNEL)? as KBox<dyn FooTrait>;
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
///
|
2024-10-04 15:41:15 +00:00
|
|
|
|
/// # Invariants
|
|
|
|
|
|
///
|
|
|
|
|
|
/// `self.0` is always properly aligned and either points to memory allocated with `A` or, for
|
|
|
|
|
|
/// zero-sized types, is a dangling, well aligned pointer.
|
|
|
|
|
|
#[repr(transparent)]
|
2025-04-12 06:29:13 +00:00
|
|
|
|
#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))]
|
|
|
|
|
|
pub struct Box<#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, pointee)] T: ?Sized, A: Allocator>(
|
|
|
|
|
|
NonNull<T>,
|
|
|
|
|
|
PhantomData<A>,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// This is to allow coercion from `Box<T, A>` to `Box<U, A>` if `T` can be converted to the
|
|
|
|
|
|
// dynamically-sized type (DST) `U`.
|
|
|
|
|
|
#[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
|
|
|
|
|
|
impl<T, U, A> core::ops::CoerceUnsized<Box<U, A>> for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized + core::marker::Unsize<U>,
|
|
|
|
|
|
U: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// This is to allow `Box<U, A>` to be dispatched on when `Box<T, A>` can be coerced into `Box<U,
|
|
|
|
|
|
// A>`.
|
|
|
|
|
|
#[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
|
|
|
|
|
|
impl<T, U, A> core::ops::DispatchFromDyn<Box<U, A>> for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized + core::marker::Unsize<U>,
|
|
|
|
|
|
U: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
2024-10-04 15:41:15 +00:00
|
|
|
|
|
|
|
|
|
|
/// Type alias for [`Box`] with a [`Kmalloc`] allocator.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let b = KBox::new(24_u64, GFP_KERNEL)?;
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*b, 24_u64);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
pub type KBox<T> = Box<T, super::allocator::Kmalloc>;
|
|
|
|
|
|
|
|
|
|
|
|
/// Type alias for [`Box`] with a [`Vmalloc`] allocator.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let b = VBox::new(24_u64, GFP_KERNEL)?;
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*b, 24_u64);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
pub type VBox<T> = Box<T, super::allocator::Vmalloc>;
|
|
|
|
|
|
|
|
|
|
|
|
/// Type alias for [`Box`] with a [`KVmalloc`] allocator.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let b = KVBox::new(24_u64, GFP_KERNEL)?;
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*b, 24_u64);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
pub type KVBox<T> = Box<T, super::allocator::KVmalloc>;
|
|
|
|
|
|
|
Rust changes for v6.15
Toolchain and infrastructure:
- Extract the 'pin-init' API from the 'kernel' crate and make it into
a standalone crate.
In order to do this, the contents are rearranged so that they can
easily be kept in sync with the version maintained out-of-tree that
other projects have started to use too (or plan to, like QEMU).
This will reduce the maintenance burden for Benno, who will now have
his own sub-tree, and will simplify future expected changes like the
move to use 'syn' to simplify the implementation.
- Add '#[test]'-like support based on KUnit.
We already had doctests support based on KUnit, which takes the
examples in our Rust documentation and runs them under KUnit.
Now, we are adding the beginning of the support for "normal" tests,
similar to those the '#[test]' tests in userspace Rust. For instance:
#[kunit_tests(my_suite)]
mod tests {
#[test]
fn my_test() {
assert_eq!(1 + 1, 2);
}
}
Unlike with doctests, the 'assert*!'s do not map to the KUnit
assertion APIs yet.
- Check Rust signatures at compile time for functions called from C by
name.
In particular, introduce a new '#[export]' macro that can be placed
in the Rust function definition. It will ensure that the function
declaration on the C side matches the signature on the Rust function:
#[export]
pub unsafe extern "C" fn my_function(a: u8, b: i32) -> usize {
// ...
}
The macro essentially forces the compiler to compare the types of
the actual Rust function and the 'bindgen'-processed C signature.
These cases are rare so far. In the future, we may consider
introducing another tool, 'cbindgen', to generate C headers
automatically. Even then, having these functions explicitly marked
may be a good idea anyway.
- Enable the 'raw_ref_op' Rust feature: it is already stable, and
allows us to use the new '&raw' syntax, avoiding a couple macros.
After everyone has migrated, we will disallow the macros.
- Pass the correct target to 'bindgen' on Usermode Linux.
- Fix 'rusttest' build in macOS.
'kernel' crate:
- New 'hrtimer' module: add support for setting up intrusive timers
without allocating when starting the timer. Add support for
'Pin<Box<_>>', 'Arc<_>', 'Pin<&_>' and 'Pin<&mut _>' as pointer types
for use with timer callbacks. Add support for setting clock source
and timer mode.
- New 'dma' module: add a simple DMA coherent allocator abstraction and
a test sample driver.
- 'list' module: make the linked list 'Cursor' point between elements,
rather than at an element, which is more convenient to us and allows
for cursors to empty lists; and document it with examples of how to
perform common operations with the provided methods.
- 'str' module: implement a few traits for 'BStr' as well as the
'strip_prefix()' method.
- 'sync' module: add 'Arc::as_ptr'.
- 'alloc' module: add 'Box::into_pin'.
- 'error' module: extend the 'Result' documentation, including a few
examples on different ways of handling errors, a warning about using
methods that may panic, and links to external documentation.
'macros' crate:
- 'module' macro: add the 'authors' key to support multiple authors.
The original key will be kept until everyone has migrated.
Documentation:
- Add error handling sections.
MAINTAINERS:
- Add Danilo Krummrich as reviewer of the Rust "subsystem".
- Add 'RUST [PIN-INIT]' entry with Benno Lossin as maintainer. It has
its own sub-tree.
- Add sub-tree for 'RUST [ALLOC]'.
- Add 'DMA MAPPING HELPERS DEVICE DRIVER API [RUST]' entry with Abdiel
Janulgue as primary maintainer. It will go through the sub-tree of
the 'RUST [ALLOC]' entry.
- Add 'HIGH-RESOLUTION TIMERS [RUST]' entry with Andreas Hindborg as
maintainer. It has its own sub-tree.
And a few other cleanups and improvements.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmfpQgAACgkQGXyLc2ht
IW35CQ//VOIFKtG6qgHVMIxrmpT7YFsrAU41h+cHT2lzy5KiTqSYlCgd18SJ+Iyy
vi1ylfdyqOpH5EoO+opPN2H4E+VUlRJg7BkZrT4p1lgGDEKg1mtR/825TxquLNFM
A653f3FvK/scMb6X43kWNKGK/jnxlfxBGmUwIY4/p7+adIuZzXnNbPkV9XYGLx3r
8KIBKJ9gM52eXoCoF8XJpg6Vg/0rYWIet32OzYF0PvzSAOqUlH4keu15jeUo+59V
tgCzAkc2yV3oSo721KYlpPeCPKI5iVCzIcwT0n8fqraXtgGnaFPe5XF16U9Qvrjv
vRp5/dePAHwsOcj5ErzOgLMqGa1sqY76lxDI05PNcBJ8fBAhNEV/rpCTXs/wRagQ
xUZOdsQyEn0V/BOtV+dnwu410dElEeJdOAeojSYFm1gUay43a0e6yIboxn3Ylnfx
8jONSokZ/UFHX3wOFNqHeXsY+REB8Qq8OZXjNBZVFpKHNsICWA0G3BcCRnB1815k
0v7seSdrST78EJ/A5nM0a9gghuLzYgAN04SDx0FzKjb2mHs3PiVfXDvrNMCJ0pBW
zbF9RlvszKZStY5tpxdZ5Zh+f7rfYcnJHYhNpoP7DJr136iWP+NnHbk1lK6+o4WY
lPVdMMgUSUlEXIHgK2ebcb/I1KBrDYiPktmvKAFLrH3qVzhkLAU=
=PCxf
-----END PGP SIGNATURE-----
Merge tag 'rust-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- Extract the 'pin-init' API from the 'kernel' crate and make it into
a standalone crate.
In order to do this, the contents are rearranged so that they can
easily be kept in sync with the version maintained out-of-tree that
other projects have started to use too (or plan to, like QEMU).
This will reduce the maintenance burden for Benno, who will now
have his own sub-tree, and will simplify future expected changes
like the move to use 'syn' to simplify the implementation.
- Add '#[test]'-like support based on KUnit.
We already had doctests support based on KUnit, which takes the
examples in our Rust documentation and runs them under KUnit.
Now, we are adding the beginning of the support for "normal" tests,
similar to those the '#[test]' tests in userspace Rust. For
instance:
#[kunit_tests(my_suite)]
mod tests {
#[test]
fn my_test() {
assert_eq!(1 + 1, 2);
}
}
Unlike with doctests, the 'assert*!'s do not map to the KUnit
assertion APIs yet.
- Check Rust signatures at compile time for functions called from C
by name.
In particular, introduce a new '#[export]' macro that can be placed
in the Rust function definition. It will ensure that the function
declaration on the C side matches the signature on the Rust
function:
#[export]
pub unsafe extern "C" fn my_function(a: u8, b: i32) -> usize {
// ...
}
The macro essentially forces the compiler to compare the types of
the actual Rust function and the 'bindgen'-processed C signature.
These cases are rare so far. In the future, we may consider
introducing another tool, 'cbindgen', to generate C headers
automatically. Even then, having these functions explicitly marked
may be a good idea anyway.
- Enable the 'raw_ref_op' Rust feature: it is already stable, and
allows us to use the new '&raw' syntax, avoiding a couple macros.
After everyone has migrated, we will disallow the macros.
- Pass the correct target to 'bindgen' on Usermode Linux.
- Fix 'rusttest' build in macOS.
'kernel' crate:
- New 'hrtimer' module: add support for setting up intrusive timers
without allocating when starting the timer. Add support for
'Pin<Box<_>>', 'Arc<_>', 'Pin<&_>' and 'Pin<&mut _>' as pointer
types for use with timer callbacks. Add support for setting clock
source and timer mode.
- New 'dma' module: add a simple DMA coherent allocator abstraction
and a test sample driver.
- 'list' module: make the linked list 'Cursor' point between
elements, rather than at an element, which is more convenient to us
and allows for cursors to empty lists; and document it with
examples of how to perform common operations with the provided
methods.
- 'str' module: implement a few traits for 'BStr' as well as the
'strip_prefix()' method.
- 'sync' module: add 'Arc::as_ptr'.
- 'alloc' module: add 'Box::into_pin'.
- 'error' module: extend the 'Result' documentation, including a few
examples on different ways of handling errors, a warning about
using methods that may panic, and links to external documentation.
'macros' crate:
- 'module' macro: add the 'authors' key to support multiple authors.
The original key will be kept until everyone has migrated.
Documentation:
- Add error handling sections.
MAINTAINERS:
- Add Danilo Krummrich as reviewer of the Rust "subsystem".
- Add 'RUST [PIN-INIT]' entry with Benno Lossin as maintainer. It has
its own sub-tree.
- Add sub-tree for 'RUST [ALLOC]'.
- Add 'DMA MAPPING HELPERS DEVICE DRIVER API [RUST]' entry with
Abdiel Janulgue as primary maintainer. It will go through the
sub-tree of the 'RUST [ALLOC]' entry.
- Add 'HIGH-RESOLUTION TIMERS [RUST]' entry with Andreas Hindborg as
maintainer. It has its own sub-tree.
And a few other cleanups and improvements"
* tag 'rust-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (71 commits)
rust: dma: add `Send` implementation for `CoherentAllocation`
rust: macros: fix `make rusttest` build on macOS
rust: block: refactor to use `&raw mut`
rust: enable `raw_ref_op` feature
rust: uaccess: name the correct function
rust: rbtree: fix comments referring to Box instead of KBox
rust: hrtimer: add maintainer entry
rust: hrtimer: add clocksource selection through `ClockId`
rust: hrtimer: add `HrTimerMode`
rust: hrtimer: implement `HrTimerPointer` for `Pin<Box<T>>`
rust: alloc: add `Box::into_pin`
rust: hrtimer: implement `UnsafeHrTimerPointer` for `Pin<&mut T>`
rust: hrtimer: implement `UnsafeHrTimerPointer` for `Pin<&T>`
rust: hrtimer: add `hrtimer::ScopedHrTimerPointer`
rust: hrtimer: add `UnsafeHrTimerPointer`
rust: hrtimer: allow timer restart from timer handler
rust: str: implement `strip_prefix` for `BStr`
rust: str: implement `AsRef<BStr>` for `[u8]` and `BStr`
rust: str: implement `Index` for `BStr`
rust: str: implement `PartialEq` for `BStr`
...
2025-03-31 00:03:26 +00:00
|
|
|
|
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
|
2025-04-07 03:34:41 +00:00
|
|
|
|
// <https://doc.rust-lang.org/stable/std/option/index.html#representation>).
|
Rust changes for v6.15
Toolchain and infrastructure:
- Extract the 'pin-init' API from the 'kernel' crate and make it into
a standalone crate.
In order to do this, the contents are rearranged so that they can
easily be kept in sync with the version maintained out-of-tree that
other projects have started to use too (or plan to, like QEMU).
This will reduce the maintenance burden for Benno, who will now have
his own sub-tree, and will simplify future expected changes like the
move to use 'syn' to simplify the implementation.
- Add '#[test]'-like support based on KUnit.
We already had doctests support based on KUnit, which takes the
examples in our Rust documentation and runs them under KUnit.
Now, we are adding the beginning of the support for "normal" tests,
similar to those the '#[test]' tests in userspace Rust. For instance:
#[kunit_tests(my_suite)]
mod tests {
#[test]
fn my_test() {
assert_eq!(1 + 1, 2);
}
}
Unlike with doctests, the 'assert*!'s do not map to the KUnit
assertion APIs yet.
- Check Rust signatures at compile time for functions called from C by
name.
In particular, introduce a new '#[export]' macro that can be placed
in the Rust function definition. It will ensure that the function
declaration on the C side matches the signature on the Rust function:
#[export]
pub unsafe extern "C" fn my_function(a: u8, b: i32) -> usize {
// ...
}
The macro essentially forces the compiler to compare the types of
the actual Rust function and the 'bindgen'-processed C signature.
These cases are rare so far. In the future, we may consider
introducing another tool, 'cbindgen', to generate C headers
automatically. Even then, having these functions explicitly marked
may be a good idea anyway.
- Enable the 'raw_ref_op' Rust feature: it is already stable, and
allows us to use the new '&raw' syntax, avoiding a couple macros.
After everyone has migrated, we will disallow the macros.
- Pass the correct target to 'bindgen' on Usermode Linux.
- Fix 'rusttest' build in macOS.
'kernel' crate:
- New 'hrtimer' module: add support for setting up intrusive timers
without allocating when starting the timer. Add support for
'Pin<Box<_>>', 'Arc<_>', 'Pin<&_>' and 'Pin<&mut _>' as pointer types
for use with timer callbacks. Add support for setting clock source
and timer mode.
- New 'dma' module: add a simple DMA coherent allocator abstraction and
a test sample driver.
- 'list' module: make the linked list 'Cursor' point between elements,
rather than at an element, which is more convenient to us and allows
for cursors to empty lists; and document it with examples of how to
perform common operations with the provided methods.
- 'str' module: implement a few traits for 'BStr' as well as the
'strip_prefix()' method.
- 'sync' module: add 'Arc::as_ptr'.
- 'alloc' module: add 'Box::into_pin'.
- 'error' module: extend the 'Result' documentation, including a few
examples on different ways of handling errors, a warning about using
methods that may panic, and links to external documentation.
'macros' crate:
- 'module' macro: add the 'authors' key to support multiple authors.
The original key will be kept until everyone has migrated.
Documentation:
- Add error handling sections.
MAINTAINERS:
- Add Danilo Krummrich as reviewer of the Rust "subsystem".
- Add 'RUST [PIN-INIT]' entry with Benno Lossin as maintainer. It has
its own sub-tree.
- Add sub-tree for 'RUST [ALLOC]'.
- Add 'DMA MAPPING HELPERS DEVICE DRIVER API [RUST]' entry with Abdiel
Janulgue as primary maintainer. It will go through the sub-tree of
the 'RUST [ALLOC]' entry.
- Add 'HIGH-RESOLUTION TIMERS [RUST]' entry with Andreas Hindborg as
maintainer. It has its own sub-tree.
And a few other cleanups and improvements.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmfpQgAACgkQGXyLc2ht
IW35CQ//VOIFKtG6qgHVMIxrmpT7YFsrAU41h+cHT2lzy5KiTqSYlCgd18SJ+Iyy
vi1ylfdyqOpH5EoO+opPN2H4E+VUlRJg7BkZrT4p1lgGDEKg1mtR/825TxquLNFM
A653f3FvK/scMb6X43kWNKGK/jnxlfxBGmUwIY4/p7+adIuZzXnNbPkV9XYGLx3r
8KIBKJ9gM52eXoCoF8XJpg6Vg/0rYWIet32OzYF0PvzSAOqUlH4keu15jeUo+59V
tgCzAkc2yV3oSo721KYlpPeCPKI5iVCzIcwT0n8fqraXtgGnaFPe5XF16U9Qvrjv
vRp5/dePAHwsOcj5ErzOgLMqGa1sqY76lxDI05PNcBJ8fBAhNEV/rpCTXs/wRagQ
xUZOdsQyEn0V/BOtV+dnwu410dElEeJdOAeojSYFm1gUay43a0e6yIboxn3Ylnfx
8jONSokZ/UFHX3wOFNqHeXsY+REB8Qq8OZXjNBZVFpKHNsICWA0G3BcCRnB1815k
0v7seSdrST78EJ/A5nM0a9gghuLzYgAN04SDx0FzKjb2mHs3PiVfXDvrNMCJ0pBW
zbF9RlvszKZStY5tpxdZ5Zh+f7rfYcnJHYhNpoP7DJr136iWP+NnHbk1lK6+o4WY
lPVdMMgUSUlEXIHgK2ebcb/I1KBrDYiPktmvKAFLrH3qVzhkLAU=
=PCxf
-----END PGP SIGNATURE-----
Merge tag 'rust-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- Extract the 'pin-init' API from the 'kernel' crate and make it into
a standalone crate.
In order to do this, the contents are rearranged so that they can
easily be kept in sync with the version maintained out-of-tree that
other projects have started to use too (or plan to, like QEMU).
This will reduce the maintenance burden for Benno, who will now
have his own sub-tree, and will simplify future expected changes
like the move to use 'syn' to simplify the implementation.
- Add '#[test]'-like support based on KUnit.
We already had doctests support based on KUnit, which takes the
examples in our Rust documentation and runs them under KUnit.
Now, we are adding the beginning of the support for "normal" tests,
similar to those the '#[test]' tests in userspace Rust. For
instance:
#[kunit_tests(my_suite)]
mod tests {
#[test]
fn my_test() {
assert_eq!(1 + 1, 2);
}
}
Unlike with doctests, the 'assert*!'s do not map to the KUnit
assertion APIs yet.
- Check Rust signatures at compile time for functions called from C
by name.
In particular, introduce a new '#[export]' macro that can be placed
in the Rust function definition. It will ensure that the function
declaration on the C side matches the signature on the Rust
function:
#[export]
pub unsafe extern "C" fn my_function(a: u8, b: i32) -> usize {
// ...
}
The macro essentially forces the compiler to compare the types of
the actual Rust function and the 'bindgen'-processed C signature.
These cases are rare so far. In the future, we may consider
introducing another tool, 'cbindgen', to generate C headers
automatically. Even then, having these functions explicitly marked
may be a good idea anyway.
- Enable the 'raw_ref_op' Rust feature: it is already stable, and
allows us to use the new '&raw' syntax, avoiding a couple macros.
After everyone has migrated, we will disallow the macros.
- Pass the correct target to 'bindgen' on Usermode Linux.
- Fix 'rusttest' build in macOS.
'kernel' crate:
- New 'hrtimer' module: add support for setting up intrusive timers
without allocating when starting the timer. Add support for
'Pin<Box<_>>', 'Arc<_>', 'Pin<&_>' and 'Pin<&mut _>' as pointer
types for use with timer callbacks. Add support for setting clock
source and timer mode.
- New 'dma' module: add a simple DMA coherent allocator abstraction
and a test sample driver.
- 'list' module: make the linked list 'Cursor' point between
elements, rather than at an element, which is more convenient to us
and allows for cursors to empty lists; and document it with
examples of how to perform common operations with the provided
methods.
- 'str' module: implement a few traits for 'BStr' as well as the
'strip_prefix()' method.
- 'sync' module: add 'Arc::as_ptr'.
- 'alloc' module: add 'Box::into_pin'.
- 'error' module: extend the 'Result' documentation, including a few
examples on different ways of handling errors, a warning about
using methods that may panic, and links to external documentation.
'macros' crate:
- 'module' macro: add the 'authors' key to support multiple authors.
The original key will be kept until everyone has migrated.
Documentation:
- Add error handling sections.
MAINTAINERS:
- Add Danilo Krummrich as reviewer of the Rust "subsystem".
- Add 'RUST [PIN-INIT]' entry with Benno Lossin as maintainer. It has
its own sub-tree.
- Add sub-tree for 'RUST [ALLOC]'.
- Add 'DMA MAPPING HELPERS DEVICE DRIVER API [RUST]' entry with
Abdiel Janulgue as primary maintainer. It will go through the
sub-tree of the 'RUST [ALLOC]' entry.
- Add 'HIGH-RESOLUTION TIMERS [RUST]' entry with Andreas Hindborg as
maintainer. It has its own sub-tree.
And a few other cleanups and improvements"
* tag 'rust-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (71 commits)
rust: dma: add `Send` implementation for `CoherentAllocation`
rust: macros: fix `make rusttest` build on macOS
rust: block: refactor to use `&raw mut`
rust: enable `raw_ref_op` feature
rust: uaccess: name the correct function
rust: rbtree: fix comments referring to Box instead of KBox
rust: hrtimer: add maintainer entry
rust: hrtimer: add clocksource selection through `ClockId`
rust: hrtimer: add `HrTimerMode`
rust: hrtimer: implement `HrTimerPointer` for `Pin<Box<T>>`
rust: alloc: add `Box::into_pin`
rust: hrtimer: implement `UnsafeHrTimerPointer` for `Pin<&mut T>`
rust: hrtimer: implement `UnsafeHrTimerPointer` for `Pin<&T>`
rust: hrtimer: add `hrtimer::ScopedHrTimerPointer`
rust: hrtimer: add `UnsafeHrTimerPointer`
rust: hrtimer: allow timer restart from timer handler
rust: str: implement `strip_prefix` for `BStr`
rust: str: implement `AsRef<BStr>` for `[u8]` and `BStr`
rust: str: implement `Index` for `BStr`
rust: str: implement `PartialEq` for `BStr`
...
2025-03-31 00:03:26 +00:00
|
|
|
|
unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {}
|
2025-03-08 11:04:38 +00:00
|
|
|
|
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`.
|
|
|
|
|
|
unsafe impl<T, A> Send for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: Send + ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`.
|
|
|
|
|
|
unsafe impl<T, A> Sync for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: Sync + ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
/// Creates a new `Box<T, A>` from a raw pointer.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Safety
|
|
|
|
|
|
///
|
|
|
|
|
|
/// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently
|
|
|
|
|
|
/// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the
|
|
|
|
|
|
/// `Box`.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// For ZSTs, `raw` must be a dangling, well aligned pointer.
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
pub const unsafe fn from_raw(raw: *mut T) -> Self {
|
|
|
|
|
|
// INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function.
|
|
|
|
|
|
// SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer.
|
|
|
|
|
|
Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Consumes the `Box<T, A>` and returns a raw pointer.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive
|
|
|
|
|
|
/// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the
|
|
|
|
|
|
/// allocation, if any.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let x = KBox::new(24, GFP_KERNEL)?;
|
|
|
|
|
|
/// let ptr = KBox::into_raw(x);
|
|
|
|
|
|
/// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`.
|
|
|
|
|
|
/// let x = unsafe { KBox::from_raw(ptr) };
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*x, 24);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
pub fn into_raw(b: Self) -> *mut T {
|
|
|
|
|
|
ManuallyDrop::new(b).0.as_ptr()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Consumes and leaks the `Box<T, A>` and returns a mutable reference.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// See [`Box::into_raw`] for more details.
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
pub fn leak<'a>(b: Self) -> &'a mut T {
|
|
|
|
|
|
// SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer
|
|
|
|
|
|
// which points to an initialized instance of `T`.
|
|
|
|
|
|
unsafe { &mut *Box::into_raw(b) }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> Box<MaybeUninit<T>, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
/// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// It is undefined behavior to call this function while the value inside of `b` is not yet
|
|
|
|
|
|
/// fully initialized.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Safety
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Callers must ensure that the value inside of `b` is in an initialized state.
|
|
|
|
|
|
pub unsafe fn assume_init(self) -> Box<T, A> {
|
|
|
|
|
|
let raw = Self::into_raw(self);
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements
|
|
|
|
|
|
// of this function, the value inside the `Box` is in an initialized state. Hence, it is
|
|
|
|
|
|
// safe to reconstruct the `Box` as `Box<T, A>`.
|
|
|
|
|
|
unsafe { Box::from_raw(raw.cast()) }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Writes the value and converts to `Box<T, A>`.
|
|
|
|
|
|
pub fn write(mut self, value: T) -> Box<T, A> {
|
|
|
|
|
|
(*self).write(value);
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: We've just initialized `b`'s value.
|
|
|
|
|
|
unsafe { self.assume_init() }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
/// Creates a new `Box<T, A>` and initializes its contents with `x`.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// New memory is allocated with `A`. The allocation may fail, in which case an error is
|
|
|
|
|
|
/// returned. For ZSTs no memory is allocated.
|
|
|
|
|
|
pub fn new(x: T, flags: Flags) -> Result<Self, AllocError> {
|
|
|
|
|
|
let b = Self::new_uninit(flags)?;
|
|
|
|
|
|
Ok(Box::write(b, x))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Creates a new `Box<T, A>` with uninitialized contents.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// New memory is allocated with `A`. The allocation may fail, in which case an error is
|
|
|
|
|
|
/// returned. For ZSTs no memory is allocated.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let b = KBox::<u64>::new_uninit(GFP_KERNEL)?;
|
|
|
|
|
|
/// let b = KBox::write(b, 24);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// assert_eq!(*b, 24_u64);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> {
|
|
|
|
|
|
let layout = Layout::new::<MaybeUninit<T>>();
|
|
|
|
|
|
let ptr = A::alloc(layout, flags)?;
|
|
|
|
|
|
|
|
|
|
|
|
// INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`,
|
|
|
|
|
|
// which is sufficient in size and alignment for storing a `T`.
|
|
|
|
|
|
Ok(Box(ptr.cast(), PhantomData))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be
|
|
|
|
|
|
/// pinned in memory and can't be moved.
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError>
|
|
|
|
|
|
where
|
|
|
|
|
|
A: 'static,
|
|
|
|
|
|
{
|
|
|
|
|
|
Ok(Self::new(x, flags)?.into())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-09 15:19:00 +00:00
|
|
|
|
/// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement
|
|
|
|
|
|
/// [`Unpin`], then `x` will be pinned in memory and can't be moved.
|
|
|
|
|
|
pub fn into_pin(this: Self) -> Pin<Self> {
|
|
|
|
|
|
this.into()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-04 15:41:15 +00:00
|
|
|
|
/// Forgets the contents (does not run the destructor), but keeps the allocation.
|
|
|
|
|
|
fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> {
|
|
|
|
|
|
let ptr = Self::into_raw(this);
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: `ptr` is valid, because it came from `Box::into_raw`.
|
|
|
|
|
|
unsafe { Box::from_raw(ptr.cast()) }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Drops the contents, but keeps the allocation.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// let value = KBox::new([0; 32], GFP_KERNEL)?;
|
|
|
|
|
|
/// assert_eq!(*value, [0; 32]);
|
|
|
|
|
|
/// let value = KBox::drop_contents(value);
|
|
|
|
|
|
/// // Now we can re-use `value`:
|
|
|
|
|
|
/// let value = KBox::write(value, [1; 32]);
|
|
|
|
|
|
/// assert_eq!(*value, [1; 32]);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> {
|
|
|
|
|
|
let ptr = this.0.as_ptr();
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the
|
|
|
|
|
|
// value stored in `this` again.
|
|
|
|
|
|
unsafe { core::ptr::drop_in_place(ptr) };
|
|
|
|
|
|
|
|
|
|
|
|
Self::forget_contents(this)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Moves the `Box`'s value out of the `Box` and consumes the `Box`.
|
|
|
|
|
|
pub fn into_inner(b: Self) -> T {
|
|
|
|
|
|
// SAFETY: By the type invariant `&*b` is valid for `read`.
|
|
|
|
|
|
let value = unsafe { core::ptr::read(&*b) };
|
|
|
|
|
|
let _ = Self::forget_contents(b);
|
|
|
|
|
|
value
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
/// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then
|
|
|
|
|
|
/// `*b` will be pinned in memory and can't be moved.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory.
|
|
|
|
|
|
fn from(b: Box<T, A>) -> Self {
|
|
|
|
|
|
// SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long
|
|
|
|
|
|
// as `T` does not implement `Unpin`.
|
|
|
|
|
|
unsafe { Pin::new_unchecked(b) }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
A: Allocator + 'static,
|
|
|
|
|
|
{
|
|
|
|
|
|
type Initialized = Box<T, A>;
|
|
|
|
|
|
|
|
|
|
|
|
fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
|
|
|
|
|
|
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)? };
|
|
|
|
|
|
// SAFETY: All fields have been initialized.
|
|
|
|
|
|
Ok(unsafe { Box::assume_init(self) })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
|
|
|
|
|
|
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)? };
|
|
|
|
|
|
// SAFETY: All fields have been initialized.
|
|
|
|
|
|
Ok(unsafe { Box::assume_init(self) }.into())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> InPlaceInit<T> for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
A: Allocator + 'static,
|
|
|
|
|
|
{
|
|
|
|
|
|
type PinnedSelf = Pin<Self>;
|
|
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E>
|
|
|
|
|
|
where
|
|
|
|
|
|
E: From<AllocError>,
|
|
|
|
|
|
{
|
|
|
|
|
|
Box::<_, A>::new_uninit(flags)?.write_pin_init(init)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
|
|
|
|
|
|
where
|
|
|
|
|
|
E: From<AllocError>,
|
|
|
|
|
|
{
|
|
|
|
|
|
Box::<_, A>::new_uninit(flags)?.write_init(init)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
// SAFETY: The pointer returned by `into_foreign` comes from a well aligned
|
|
|
|
|
|
// pointer to `T`.
|
2025-04-23 13:54:37 +00:00
|
|
|
|
unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A>
|
2024-10-04 15:41:15 +00:00
|
|
|
|
where
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
2025-06-12 13:09:43 +00:00
|
|
|
|
const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
|
2024-10-04 15:41:15 +00:00
|
|
|
|
type Borrowed<'a> = &'a T;
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
type BorrowedMut<'a> = &'a mut T;
|
2024-10-04 15:41:15 +00:00
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
fn into_foreign(self) -> *mut c_void {
|
|
|
|
|
|
Box::into_raw(self).cast()
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn from_foreign(ptr: *mut c_void) -> Self {
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
|
|
|
|
|
|
// call to `Self::into_foreign`.
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe { Box::from_raw(ptr.cast()) }
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T {
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: The safety requirements of this method ensure that the object remains alive and
|
|
|
|
|
|
// immutable for the duration of 'a.
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe { &*ptr.cast() }
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a mut T {
|
|
|
|
|
|
let ptr = ptr.cast();
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
// SAFETY: The safety requirements of this method ensure that the pointer is valid and that
|
|
|
|
|
|
// nothing else will access the value for the duration of 'a.
|
|
|
|
|
|
unsafe { &mut *ptr }
|
|
|
|
|
|
}
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
// SAFETY: The pointer returned by `into_foreign` comes from a well aligned
|
|
|
|
|
|
// pointer to `T`.
|
2025-04-23 13:54:37 +00:00
|
|
|
|
unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
|
2024-10-04 15:41:15 +00:00
|
|
|
|
where
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
2025-06-12 13:09:43 +00:00
|
|
|
|
const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
|
2024-10-04 15:41:15 +00:00
|
|
|
|
type Borrowed<'a> = Pin<&'a T>;
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
type BorrowedMut<'a> = Pin<&'a mut T>;
|
2024-10-04 15:41:15 +00:00
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
fn into_foreign(self) -> *mut c_void {
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: We are still treating the box as pinned.
|
2025-06-12 13:09:43 +00:00
|
|
|
|
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn from_foreign(ptr: *mut c_void) -> Self {
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
|
|
|
|
|
|
// call to `Self::into_foreign`.
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn borrow<'a>(ptr: *mut c_void) -> Pin<&'a T> {
|
2024-10-04 15:41:15 +00:00
|
|
|
|
// SAFETY: The safety requirements for this function ensure that the object is still alive,
|
|
|
|
|
|
// so it is safe to dereference the raw pointer.
|
|
|
|
|
|
// The safety requirements of `from_foreign` also ensure that the object remains alive for
|
|
|
|
|
|
// the lifetime of the returned value.
|
2025-06-12 13:09:43 +00:00
|
|
|
|
let r = unsafe { &*ptr.cast() };
|
2024-10-04 15:41:15 +00:00
|
|
|
|
|
|
|
|
|
|
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
|
|
|
|
|
|
unsafe { Pin::new_unchecked(r) }
|
|
|
|
|
|
}
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
|
2025-06-12 13:09:43 +00:00
|
|
|
|
unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Pin<&'a mut T> {
|
|
|
|
|
|
let ptr = ptr.cast();
|
rust: kernel: add improved version of `ForeignOwnable::borrow_mut`
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241120-borrow-mut-v6-6-80dbadd00951@gmail.com
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-20 11:46:05 +00:00
|
|
|
|
// SAFETY: The safety requirements for this function ensure that the object is still alive,
|
|
|
|
|
|
// so it is safe to dereference the raw pointer.
|
|
|
|
|
|
// The safety requirements of `from_foreign` also ensure that the object remains alive for
|
|
|
|
|
|
// the lifetime of the returned value.
|
|
|
|
|
|
let r = unsafe { &mut *ptr };
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
|
|
|
|
|
|
unsafe { Pin::new_unchecked(r) }
|
|
|
|
|
|
}
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> Deref for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
|
|
fn deref(&self) -> &T {
|
|
|
|
|
|
// SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized
|
|
|
|
|
|
// instance of `T`.
|
|
|
|
|
|
unsafe { self.0.as_ref() }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> DerefMut for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn deref_mut(&mut self) -> &mut T {
|
|
|
|
|
|
// SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized
|
|
|
|
|
|
// instance of `T`.
|
|
|
|
|
|
unsafe { self.0.as_mut() }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-16 03:34:07 +00:00
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// # use core::borrow::Borrow;
|
|
|
|
|
|
/// # use kernel::alloc::KBox;
|
|
|
|
|
|
/// struct Foo<B: Borrow<u32>>(B);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// // Owned instance.
|
|
|
|
|
|
/// let owned = Foo(1);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// // Owned instance using `KBox`.
|
|
|
|
|
|
/// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// let i = 1;
|
|
|
|
|
|
/// // Borrowed from `i`.
|
|
|
|
|
|
/// let borrowed = Foo(&i);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
impl<T, A> Borrow<T> for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn borrow(&self) -> &T {
|
|
|
|
|
|
self.deref()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// # use core::borrow::BorrowMut;
|
|
|
|
|
|
/// # use kernel::alloc::KBox;
|
|
|
|
|
|
/// struct Foo<B: BorrowMut<u32>>(B);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// // Owned instance.
|
|
|
|
|
|
/// let owned = Foo(1);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// // Owned instance using `KBox`.
|
|
|
|
|
|
/// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// let mut i = 1;
|
|
|
|
|
|
/// // Borrowed from `i`.
|
|
|
|
|
|
/// let borrowed = Foo(&mut i);
|
|
|
|
|
|
/// # Ok::<(), Error>(())
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
impl<T, A> BorrowMut<T> for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn borrow_mut(&mut self) -> &mut T {
|
|
|
|
|
|
self.deref_mut()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-11 13:40:41 +00:00
|
|
|
|
impl<T, A> fmt::Display for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized + fmt::Display,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
|
<T as fmt::Display>::fmt(&**self, f)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-04 15:41:15 +00:00
|
|
|
|
impl<T, A> fmt::Debug for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized + fmt::Debug,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2024-11-11 13:51:27 +00:00
|
|
|
|
<T as fmt::Debug>::fmt(&**self, f)
|
2024-10-04 15:41:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<T, A> Drop for Box<T, A>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: ?Sized,
|
|
|
|
|
|
A: Allocator,
|
|
|
|
|
|
{
|
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
|
let layout = Layout::for_value::<T>(self);
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant.
|
|
|
|
|
|
unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) };
|
|
|
|
|
|
|
|
|
|
|
|
// SAFETY:
|
|
|
|
|
|
// - `self.0` was previously allocated with `A`.
|
|
|
|
|
|
// - `layout` is equal to the `Layout´ `self.0` was allocated with.
|
|
|
|
|
|
unsafe { A::free(self.0.cast(), layout) };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|