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 marker::PhantomData, 10 mem::MaybeUninit, 11 ops::{Deref, DerefMut}, 12 ptr::NonNull, 13 }; 14 15 /// Used to transfer ownership to and from foreign (non-Rust) languages. 16 /// 17 /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and 18 /// later may be transferred back to Rust by calling [`Self::from_foreign`]. 19 /// 20 /// This trait is meant to be used in cases when Rust objects are stored in C objects and 21 /// eventually "freed" back to Rust. 22 pub trait ForeignOwnable: Sized { 23 /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and 24 /// [`ForeignOwnable::from_foreign`]. 25 type Borrowed<'a>; 26 27 /// Converts a Rust-owned object to a foreign-owned one. 28 /// 29 /// The foreign representation is a pointer to void. 30 fn into_foreign(self) -> *const core::ffi::c_void; 31 32 /// Borrows a foreign-owned object. 33 /// 34 /// # Safety 35 /// 36 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 37 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 38 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow_mut`] 39 /// for this object must have been dropped. 40 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>; 41 42 /// Mutably borrows a foreign-owned object. 43 /// 44 /// # Safety 45 /// 46 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 47 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 48 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 49 /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 50 unsafe fn borrow_mut(ptr: *const core::ffi::c_void) -> ScopeGuard<Self, fn(Self)> { 51 // SAFETY: The safety requirements ensure that `ptr` came from a previous call to 52 // `into_foreign`. 53 ScopeGuard::new_with_data(unsafe { Self::from_foreign(ptr) }, |d| { 54 d.into_foreign(); 55 }) 56 } 57 58 /// Converts a foreign-owned object back to a Rust-owned one. 59 /// 60 /// # Safety 61 /// 62 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 63 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 64 /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 65 /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 66 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; 67 } 68 69 impl<T: 'static> ForeignOwnable for Box<T> { 70 type Borrowed<'a> = &'a T; 71 72 fn into_foreign(self) -> *const core::ffi::c_void { 73 Box::into_raw(self) as _ 74 } 75 76 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { 77 // SAFETY: The safety requirements for this function ensure that the object is still alive, 78 // so it is safe to dereference the raw pointer. 79 // The safety requirements of `from_foreign` also ensure that the object remains alive for 80 // the lifetime of the returned value. 81 unsafe { &*ptr.cast() } 82 } 83 84 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { 85 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 86 // call to `Self::into_foreign`. 87 unsafe { Box::from_raw(ptr as _) } 88 } 89 } 90 91 impl ForeignOwnable for () { 92 type Borrowed<'a> = (); 93 94 fn into_foreign(self) -> *const core::ffi::c_void { 95 core::ptr::NonNull::dangling().as_ptr() 96 } 97 98 unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {} 99 100 unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {} 101 } 102 103 /// Runs a cleanup function/closure when dropped. 104 /// 105 /// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running. 106 /// 107 /// # Examples 108 /// 109 /// In the example below, we have multiple exit paths and we want to log regardless of which one is 110 /// taken: 111 /// ``` 112 /// # use kernel::ScopeGuard; 113 /// fn example1(arg: bool) { 114 /// let _log = ScopeGuard::new(|| pr_info!("example1 completed\n")); 115 /// 116 /// if arg { 117 /// return; 118 /// } 119 /// 120 /// pr_info!("Do something...\n"); 121 /// } 122 /// 123 /// # example1(false); 124 /// # example1(true); 125 /// ``` 126 /// 127 /// In the example below, we want to log the same message on all early exits but a different one on 128 /// the main exit path: 129 /// ``` 130 /// # use kernel::ScopeGuard; 131 /// fn example2(arg: bool) { 132 /// let log = ScopeGuard::new(|| pr_info!("example2 returned early\n")); 133 /// 134 /// if arg { 135 /// return; 136 /// } 137 /// 138 /// // (Other early returns...) 139 /// 140 /// log.dismiss(); 141 /// pr_info!("example2 no early return\n"); 142 /// } 143 /// 144 /// # example2(false); 145 /// # example2(true); 146 /// ``` 147 /// 148 /// In the example below, we need a mutable object (the vector) to be accessible within the log 149 /// function, so we wrap it in the [`ScopeGuard`]: 150 /// ``` 151 /// # use kernel::ScopeGuard; 152 /// fn example3(arg: bool) -> Result { 153 /// let mut vec = 154 /// ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len())); 155 /// 156 /// vec.try_push(10u8)?; 157 /// if arg { 158 /// return Ok(()); 159 /// } 160 /// vec.try_push(20u8)?; 161 /// Ok(()) 162 /// } 163 /// 164 /// # assert_eq!(example3(false), Ok(())); 165 /// # assert_eq!(example3(true), Ok(())); 166 /// ``` 167 /// 168 /// # Invariants 169 /// 170 /// The value stored in the struct is nearly always `Some(_)`, except between 171 /// [`ScopeGuard::dismiss`] and [`ScopeGuard::drop`]: in this case, it will be `None` as the value 172 /// will have been returned to the caller. Since [`ScopeGuard::dismiss`] consumes the guard, 173 /// callers won't be able to use it anymore. 174 pub struct ScopeGuard<T, F: FnOnce(T)>(Option<(T, F)>); 175 176 impl<T, F: FnOnce(T)> ScopeGuard<T, F> { 177 /// Creates a new guarded object wrapping the given data and with the given cleanup function. 178 pub fn new_with_data(data: T, cleanup_func: F) -> Self { 179 // INVARIANT: The struct is being initialised with `Some(_)`. 180 Self(Some((data, cleanup_func))) 181 } 182 183 /// Prevents the cleanup function from running and returns the guarded data. 184 pub fn dismiss(mut self) -> T { 185 // INVARIANT: This is the exception case in the invariant; it is not visible to callers 186 // because this function consumes `self`. 187 self.0.take().unwrap().0 188 } 189 } 190 191 impl ScopeGuard<(), fn(())> { 192 /// Creates a new guarded object with the given cleanup function. 193 pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> { 194 ScopeGuard::new_with_data((), move |_| cleanup()) 195 } 196 } 197 198 impl<T, F: FnOnce(T)> Deref for ScopeGuard<T, F> { 199 type Target = T; 200 201 fn deref(&self) -> &T { 202 // The type invariants guarantee that `unwrap` will succeed. 203 &self.0.as_ref().unwrap().0 204 } 205 } 206 207 impl<T, F: FnOnce(T)> DerefMut for ScopeGuard<T, F> { 208 fn deref_mut(&mut self) -> &mut T { 209 // The type invariants guarantee that `unwrap` will succeed. 210 &mut self.0.as_mut().unwrap().0 211 } 212 } 213 214 impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> { 215 fn drop(&mut self) { 216 // Run the cleanup function if one is still present. 217 if let Some((data, cleanup)) = self.0.take() { 218 cleanup(data) 219 } 220 } 221 } 222 223 /// Stores an opaque value. 224 /// 225 /// This is meant to be used with FFI objects that are never interpreted by Rust code. 226 #[repr(transparent)] 227 pub struct Opaque<T>(MaybeUninit<UnsafeCell<T>>); 228 229 impl<T> Opaque<T> { 230 /// Creates a new opaque value. 231 pub const fn new(value: T) -> Self { 232 Self(MaybeUninit::new(UnsafeCell::new(value))) 233 } 234 235 /// Creates an uninitialised value. 236 pub const fn uninit() -> Self { 237 Self(MaybeUninit::uninit()) 238 } 239 240 /// Creates a pin-initializer from the given initializer closure. 241 /// 242 /// The returned initializer calls the given closure with the pointer to the inner `T` of this 243 /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it. 244 /// 245 /// This function is safe, because the `T` inside of an `Opaque` is allowed to be 246 /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs 247 /// to verify at that point that the inner value is valid. 248 pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> { 249 // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully 250 // initialize the `T`. 251 unsafe { 252 init::pin_init_from_closure::<_, ::core::convert::Infallible>(move |slot| { 253 init_func(Self::raw_get(slot)); 254 Ok(()) 255 }) 256 } 257 } 258 259 /// Returns a raw pointer to the opaque data. 260 pub fn get(&self) -> *mut T { 261 UnsafeCell::raw_get(self.0.as_ptr()) 262 } 263 264 /// Gets the value behind `this`. 265 /// 266 /// This function is useful to get access to the value without creating intermediate 267 /// references. 268 pub const fn raw_get(this: *const Self) -> *mut T { 269 UnsafeCell::raw_get(this.cast::<UnsafeCell<T>>()) 270 } 271 } 272 273 /// Types that are _always_ reference counted. 274 /// 275 /// It allows such types to define their own custom ref increment and decrement functions. 276 /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference 277 /// [`ARef<T>`]. 278 /// 279 /// This is usually implemented by wrappers to existing structures on the C side of the code. For 280 /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted 281 /// instances of a type. 282 /// 283 /// # Safety 284 /// 285 /// Implementers must ensure that increments to the reference count keep the object alive in memory 286 /// at least until matching decrements are performed. 287 /// 288 /// Implementers must also ensure that all instances are reference-counted. (Otherwise they 289 /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object 290 /// alive.) 291 pub unsafe trait AlwaysRefCounted { 292 /// Increments the reference count on the object. 293 fn inc_ref(&self); 294 295 /// Decrements the reference count on the object. 296 /// 297 /// Frees the object when the count reaches zero. 298 /// 299 /// # Safety 300 /// 301 /// Callers must ensure that there was a previous matching increment to the reference count, 302 /// and that the object is no longer used after its reference count is decremented (as it may 303 /// result in the object being freed), unless the caller owns another increment on the refcount 304 /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls 305 /// [`AlwaysRefCounted::dec_ref`] once). 306 unsafe fn dec_ref(obj: NonNull<Self>); 307 } 308 309 /// An owned reference to an always-reference-counted object. 310 /// 311 /// The object's reference count is automatically decremented when an instance of [`ARef`] is 312 /// dropped. It is also automatically incremented when a new instance is created via 313 /// [`ARef::clone`]. 314 /// 315 /// # Invariants 316 /// 317 /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In 318 /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count. 319 pub struct ARef<T: AlwaysRefCounted> { 320 ptr: NonNull<T>, 321 _p: PhantomData<T>, 322 } 323 324 impl<T: AlwaysRefCounted> ARef<T> { 325 /// Creates a new instance of [`ARef`]. 326 /// 327 /// It takes over an increment of the reference count on the underlying object. 328 /// 329 /// # Safety 330 /// 331 /// Callers must ensure that the reference count was incremented at least once, and that they 332 /// are properly relinquishing one increment. That is, if there is only one increment, callers 333 /// must not use the underlying object anymore -- it is only safe to do so via the newly 334 /// created [`ARef`]. 335 pub unsafe fn from_raw(ptr: NonNull<T>) -> Self { 336 // INVARIANT: The safety requirements guarantee that the new instance now owns the 337 // increment on the refcount. 338 Self { 339 ptr, 340 _p: PhantomData, 341 } 342 } 343 } 344 345 impl<T: AlwaysRefCounted> Clone for ARef<T> { 346 fn clone(&self) -> Self { 347 self.inc_ref(); 348 // SAFETY: We just incremented the refcount above. 349 unsafe { Self::from_raw(self.ptr) } 350 } 351 } 352 353 impl<T: AlwaysRefCounted> Deref for ARef<T> { 354 type Target = T; 355 356 fn deref(&self) -> &Self::Target { 357 // SAFETY: The type invariants guarantee that the object is valid. 358 unsafe { self.ptr.as_ref() } 359 } 360 } 361 362 impl<T: AlwaysRefCounted> From<&T> for ARef<T> { 363 fn from(b: &T) -> Self { 364 b.inc_ref(); 365 // SAFETY: We just incremented the refcount above. 366 unsafe { Self::from_raw(NonNull::from(b)) } 367 } 368 } 369 370 impl<T: AlwaysRefCounted> Drop for ARef<T> { 371 fn drop(&mut self) { 372 // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to 373 // decrement. 374 unsafe { T::dec_ref(self.ptr) }; 375 } 376 } 377 378 /// A sum type that always holds either a value of type `L` or `R`. 379 pub enum Either<L, R> { 380 /// Constructs an instance of [`Either`] containing a value of type `L`. 381 Left(L), 382 383 /// Constructs an instance of [`Either`] containing a value of type `R`. 384 Right(R), 385 } 386