summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWedson Almeida Filho <wedsonaf@gmail.com>2023-01-30 03:44:02 -0300
committerMiguel Ojeda <ojeda@kernel.org>2023-02-01 13:24:19 +0100
commit26949bac1e8264c711a81f962845aa0538279c78 (patch)
tree498c70f9d9bb65b9adc9787e573d5dabd8cc2d23
parent0fc4424d24a230c7fb539d5d708c81c68aafa9be (diff)
rust: types: implement `ForeignOwnable` for `Box<T>`
This allows us to hand ownership of Rust dynamically allocated objects to the C side of the kernel. Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Reviewed-by: Alice Ferrazzi <alice.ferrazzi@miraclelinux.com> Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
-rw-r--r--rust/kernel/types.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index 72710b7442a3..411655eca3e9 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -2,6 +2,7 @@
//! Kernel types.
+use alloc::boxed::Box;
use core::{
cell::UnsafeCell,
mem::MaybeUninit,
@@ -62,6 +63,28 @@ pub trait ForeignOwnable: Sized {
unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self;
}
+impl<T: 'static> ForeignOwnable for Box<T> {
+ type Borrowed<'a> = &'a T;
+
+ fn into_foreign(self) -> *const core::ffi::c_void {
+ Box::into_raw(self) as _
+ }
+
+ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T {
+ // 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.
+ unsafe { &*ptr.cast() }
+ }
+
+ unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
+ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
+ // call to `Self::into_foreign`.
+ unsafe { Box::from_raw(ptr as _) }
+ }
+}
+
/// Runs a cleanup function/closure when dropped.
///
/// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running.