xref: /openbmc/linux/rust/kernel/types.rs (revision 234489ac)
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