1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Kernel types. 4 5 use crate::init::{self, PinInit}; 6 use alloc::boxed::Box; 7 use core::{ 8 cell::UnsafeCell, 9 mem::MaybeUninit, 10 ops::{Deref, DerefMut}, 11 }; 12 13 /// Used to transfer ownership to and from foreign (non-Rust) languages. 14 /// 15 /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and 16 /// later may be transferred back to Rust by calling [`Self::from_foreign`]. 17 /// 18 /// This trait is meant to be used in cases when Rust objects are stored in C objects and 19 /// eventually "freed" back to Rust. 20 pub trait ForeignOwnable: Sized { 21 /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and 22 /// [`ForeignOwnable::from_foreign`]. 23 type Borrowed<'a>; 24 25 /// Converts a Rust-owned object to a foreign-owned one. 26 /// 27 /// The foreign representation is a pointer to void. 28 fn into_foreign(self) -> *const core::ffi::c_void; 29 30 /// Borrows a foreign-owned object. 31 /// 32 /// # Safety 33 /// 34 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 35 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 36 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow_mut`] 37 /// for this object must have been dropped. 38 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>; 39 40 /// Mutably borrows a foreign-owned object. 41 /// 42 /// # Safety 43 /// 44 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 45 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 46 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 47 /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 48 unsafe fn borrow_mut(ptr: *const core::ffi::c_void) -> ScopeGuard<Self, fn(Self)> { 49 // SAFETY: The safety requirements ensure that `ptr` came from a previous call to 50 // `into_foreign`. 51 ScopeGuard::new_with_data(unsafe { Self::from_foreign(ptr) }, |d| { 52 d.into_foreign(); 53 }) 54 } 55 56 /// Converts a foreign-owned object back to a Rust-owned one. 57 /// 58 /// # Safety 59 /// 60 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 61 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 62 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 63 /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 64 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; 65 } 66 67 impl<T: 'static> ForeignOwnable for Box<T> { 68 type Borrowed<'a> = &'a T; 69 70 fn into_foreign(self) -> *const core::ffi::c_void { 71 Box::into_raw(self) as _ 72 } 73 74 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { 75 // SAFETY: The safety requirements for this function ensure that the object is still alive, 76 // so it is safe to dereference the raw pointer. 77 // The safety requirements of `from_foreign` also ensure that the object remains alive for 78 // the lifetime of the returned value. 79 unsafe { &*ptr.cast() } 80 } 81 82 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { 83 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 84 // call to `Self::into_foreign`. 85 unsafe { Box::from_raw(ptr as _) } 86 } 87 } 88 89 impl ForeignOwnable for () { 90 type Borrowed<'a> = (); 91 92 fn into_foreign(self) -> *const core::ffi::c_void { 93 core::ptr::NonNull::dangling().as_ptr() 94 } 95 96 unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {} 97 98 unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {} 99 } 100 101 /// Runs a cleanup function/closure when dropped. 102 /// 103 /// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running. 104 /// 105 /// # Examples 106 /// 107 /// In the example below, we have multiple exit paths and we want to log regardless of which one is 108 /// taken: 109 /// ``` 110 /// # use kernel::ScopeGuard; 111 /// fn example1(arg: bool) { 112 /// let _log = ScopeGuard::new(|| pr_info!("example1 completed\n")); 113 /// 114 /// if arg { 115 /// return; 116 /// } 117 /// 118 /// pr_info!("Do something...\n"); 119 /// } 120 /// 121 /// # example1(false); 122 /// # example1(true); 123 /// ``` 124 /// 125 /// In the example below, we want to log the same message on all early exits but a different one on 126 /// the main exit path: 127 /// ``` 128 /// # use kernel::ScopeGuard; 129 /// fn example2(arg: bool) { 130 /// let log = ScopeGuard::new(|| pr_info!("example2 returned early\n")); 131 /// 132 /// if arg { 133 /// return; 134 /// } 135 /// 136 /// // (Other early returns...) 137 /// 138 /// log.dismiss(); 139 /// pr_info!("example2 no early return\n"); 140 /// } 141 /// 142 /// # example2(false); 143 /// # example2(true); 144 /// ``` 145 /// 146 /// In the example below, we need a mutable object (the vector) to be accessible within the log 147 /// function, so we wrap it in the [`ScopeGuard`]: 148 /// ``` 149 /// # use kernel::ScopeGuard; 150 /// fn example3(arg: bool) -> Result { 151 /// let mut vec = 152 /// ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len())); 153 /// 154 /// vec.try_push(10u8)?; 155 /// if arg { 156 /// return Ok(()); 157 /// } 158 /// vec.try_push(20u8)?; 159 /// Ok(()) 160 /// } 161 /// 162 /// # assert_eq!(example3(false), Ok(())); 163 /// # assert_eq!(example3(true), Ok(())); 164 /// ``` 165 /// 166 /// # Invariants 167 /// 168 /// The value stored in the struct is nearly always `Some(_)`, except between 169 /// [`ScopeGuard::dismiss`] and [`ScopeGuard::drop`]: in this case, it will be `None` as the value 170 /// will have been returned to the caller. Since [`ScopeGuard::dismiss`] consumes the guard, 171 /// callers won't be able to use it anymore. 172 pub struct ScopeGuard<T, F: FnOnce(T)>(Option<(T, F)>); 173 174 impl<T, F: FnOnce(T)> ScopeGuard<T, F> { 175 /// Creates a new guarded object wrapping the given data and with the given cleanup function. 176 pub fn new_with_data(data: T, cleanup_func: F) -> Self { 177 // INVARIANT: The struct is being initialised with `Some(_)`. 178 Self(Some((data, cleanup_func))) 179 } 180 181 /// Prevents the cleanup function from running and returns the guarded data. 182 pub fn dismiss(mut self) -> T { 183 // INVARIANT: This is the exception case in the invariant; it is not visible to callers 184 // because this function consumes `self`. 185 self.0.take().unwrap().0 186 } 187 } 188 189 impl ScopeGuard<(), fn(())> { 190 /// Creates a new guarded object with the given cleanup function. 191 pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> { 192 ScopeGuard::new_with_data((), move |_| cleanup()) 193 } 194 } 195 196 impl<T, F: FnOnce(T)> Deref for ScopeGuard<T, F> { 197 type Target = T; 198 199 fn deref(&self) -> &T { 200 // The type invariants guarantee that `unwrap` will succeed. 201 &self.0.as_ref().unwrap().0 202 } 203 } 204 205 impl<T, F: FnOnce(T)> DerefMut for ScopeGuard<T, F> { 206 fn deref_mut(&mut self) -> &mut T { 207 // The type invariants guarantee that `unwrap` will succeed. 208 &mut self.0.as_mut().unwrap().0 209 } 210 } 211 212 impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> { 213 fn drop(&mut self) { 214 // Run the cleanup function if one is still present. 215 if let Some((data, cleanup)) = self.0.take() { 216 cleanup(data) 217 } 218 } 219 } 220 221 /// Stores an opaque value. 222 /// 223 /// This is meant to be used with FFI objects that are never interpreted by Rust code. 224 #[repr(transparent)] 225 pub struct Opaque<T>(MaybeUninit<UnsafeCell<T>>); 226 227 impl<T> Opaque<T> { 228 /// Creates a new opaque value. 229 pub const fn new(value: T) -> Self { 230 Self(MaybeUninit::new(UnsafeCell::new(value))) 231 } 232 233 /// Creates an uninitialised value. 234 pub const fn uninit() -> Self { 235 Self(MaybeUninit::uninit()) 236 } 237 238 /// Creates a pin-initializer from the given initializer closure. 239 /// 240 /// The returned initializer calls the given closure with the pointer to the inner `T` of this 241 /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it. 242 /// 243 /// This function is safe, because the `T` inside of an `Opaque` is allowed to be 244 /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs 245 /// to verify at that point that the inner value is valid. 246 pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> { 247 // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully 248 // initialize the `T`. 249 unsafe { 250 init::pin_init_from_closure::<_, ::core::convert::Infallible>(move |slot| { 251 init_func(Self::raw_get(slot)); 252 Ok(()) 253 }) 254 } 255 } 256 257 /// Returns a raw pointer to the opaque data. 258 pub fn get(&self) -> *mut T { 259 UnsafeCell::raw_get(self.0.as_ptr()) 260 } 261 262 /// Gets the value behind `this`. 263 /// 264 /// This function is useful to get access to the value without creating intermediate 265 /// references. 266 pub const fn raw_get(this: *const Self) -> *mut T { 267 UnsafeCell::raw_get(this.cast::<UnsafeCell<T>>()) 268 } 269 } 270 271 /// A sum type that always holds either a value of type `L` or `R`. 272 pub enum Either<L, R> { 273 /// Constructs an instance of [`Either`] containing a value of type `L`. 274 Left(L), 275 276 /// Constructs an instance of [`Either`] containing a value of type `R`. 277 Right(R), 278 } 279