Skip to main content

kernel/
types.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! Kernel types.
4
5use crate::init::{self, PinInit};
6use core::{
7    cell::UnsafeCell,
8    marker::{PhantomData, PhantomPinned},
9    mem::{ManuallyDrop, MaybeUninit},
10    ops::{Deref, DerefMut},
11    ptr::NonNull,
12};
13
14/// Used to transfer ownership to and from foreign (non-Rust) languages.
15///
16/// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
17/// later may be transferred back to Rust by calling [`Self::from_foreign`].
18///
19/// This trait is meant to be used in cases when Rust objects are stored in C objects and
20/// eventually "freed" back to Rust.
21pub trait ForeignOwnable: Sized {
22    /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
23    /// [`ForeignOwnable::from_foreign`].
24    type Borrowed<'a>;
25
26    /// Converts a Rust-owned object to a foreign-owned one.
27    ///
28    /// The foreign representation is a pointer to void. There are no guarantees for this pointer.
29    /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
30    /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
31    /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
32    fn into_foreign(self) -> *const crate::ffi::c_void;
33
34    /// Borrows a foreign-owned object.
35    ///
36    /// # Safety
37    ///
38    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
39    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
40    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>;
41
42    /// Converts a foreign-owned object back to a Rust-owned one.
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`] for
49    /// this object must have been dropped.
50    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self;
51
52    /// Tries to convert a foreign-owned object back to a Rust-owned one.
53    ///
54    /// A convenience wrapper over [`ForeignOwnable::from_foreign`] that returns [`None`] if `ptr`
55    /// is null.
56    ///
57    /// # Safety
58    ///
59    /// `ptr` must either be null or satisfy the safety requirements for
60    /// [`ForeignOwnable::from_foreign`].
61    unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
62        if ptr.is_null() {
63            None
64        } else {
65            // SAFETY: Since `ptr` is not null here, then `ptr` satisfies the safety requirements
66            // of `from_foreign` given the safety requirements of this function.
67            unsafe { Some(Self::from_foreign(ptr)) }
68        }
69    }
70}
71
72impl ForeignOwnable for () {
73    type Borrowed<'a> = ();
74
75    fn into_foreign(self) -> *const crate::ffi::c_void {
76        core::ptr::NonNull::dangling().as_ptr()
77    }
78
79    unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {}
80
81    unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {}
82}
83
84/// Runs a cleanup function/closure when dropped.
85///
86/// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running.
87///
88/// # Examples
89///
90/// In the example below, we have multiple exit paths and we want to log regardless of which one is
91/// taken:
92///
93/// ```
94/// # use kernel::types::ScopeGuard;
95/// fn example1(arg: bool) {
96///     let _log = ScopeGuard::new(|| pr_info!("example1 completed\n"));
97///
98///     if arg {
99///         return;
100///     }
101///
102///     pr_info!("Do something...\n");
103/// }
104///
105/// # example1(false);
106/// # example1(true);
107/// ```
108///
109/// In the example below, we want to log the same message on all early exits but a different one on
110/// the main exit path:
111///
112/// ```
113/// # use kernel::types::ScopeGuard;
114/// fn example2(arg: bool) {
115///     let log = ScopeGuard::new(|| pr_info!("example2 returned early\n"));
116///
117///     if arg {
118///         return;
119///     }
120///
121///     // (Other early returns...)
122///
123///     log.dismiss();
124///     pr_info!("example2 no early return\n");
125/// }
126///
127/// # example2(false);
128/// # example2(true);
129/// ```
130///
131/// In the example below, we need a mutable object (the vector) to be accessible within the log
132/// function, so we wrap it in the [`ScopeGuard`]:
133///
134/// ```
135/// # use kernel::types::ScopeGuard;
136/// fn example3(arg: bool) -> Result {
137///     let mut vec =
138///         ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {} elements\n", v.len()));
139///
140///     vec.push(10u8, GFP_KERNEL)?;
141///     if arg {
142///         return Ok(());
143///     }
144///     vec.push(20u8, GFP_KERNEL)?;
145///     Ok(())
146/// }
147///
148/// # assert_eq!(example3(false), Ok(()));
149/// # assert_eq!(example3(true), Ok(()));
150/// ```
151///
152/// # Invariants
153///
154/// The value stored in the struct is nearly always `Some(_)`, except between
155/// [`ScopeGuard::dismiss`] and [`ScopeGuard::drop`]: in this case, it will be `None` as the value
156/// will have been returned to the caller. Since  [`ScopeGuard::dismiss`] consumes the guard,
157/// callers won't be able to use it anymore.
158pub struct ScopeGuard<T, F: FnOnce(T)>(Option<(T, F)>);
159
160impl<T, F: FnOnce(T)> ScopeGuard<T, F> {
161    /// Creates a new guarded object wrapping the given data and with the given cleanup function.
162    pub fn new_with_data(data: T, cleanup_func: F) -> Self {
163        // INVARIANT: The struct is being initialised with `Some(_)`.
164        Self(Some((data, cleanup_func)))
165    }
166
167    /// Prevents the cleanup function from running and returns the guarded data.
168    pub fn dismiss(mut self) -> T {
169        // INVARIANT: This is the exception case in the invariant; it is not visible to callers
170        // because this function consumes `self`.
171        self.0.take().unwrap().0
172    }
173}
174
175impl ScopeGuard<(), fn(())> {
176    /// Creates a new guarded object with the given cleanup function.
177    pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> {
178        ScopeGuard::new_with_data((), move |()| cleanup())
179    }
180}
181
182impl<T, F: FnOnce(T)> Deref for ScopeGuard<T, F> {
183    type Target = T;
184
185    fn deref(&self) -> &T {
186        // The type invariants guarantee that `unwrap` will succeed.
187        &self.0.as_ref().unwrap().0
188    }
189}
190
191impl<T, F: FnOnce(T)> DerefMut for ScopeGuard<T, F> {
192    fn deref_mut(&mut self) -> &mut T {
193        // The type invariants guarantee that `unwrap` will succeed.
194        &mut self.0.as_mut().unwrap().0
195    }
196}
197
198impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> {
199    fn drop(&mut self) {
200        // Run the cleanup function if one is still present.
201        if let Some((data, cleanup)) = self.0.take() {
202            cleanup(data)
203        }
204    }
205}
206
207/// Stores an opaque value.
208///
209/// This is meant to be used with FFI objects that are never interpreted by Rust code.
210#[repr(transparent)]
211pub struct Opaque<T> {
212    value: UnsafeCell<MaybeUninit<T>>,
213    _pin: PhantomPinned,
214}
215
216impl<T> Opaque<T> {
217    /// Creates a new opaque value.
218    pub const fn new(value: T) -> Self {
219        Self {
220            value: UnsafeCell::new(MaybeUninit::new(value)),
221            _pin: PhantomPinned,
222        }
223    }
224
225    /// Creates an uninitialised value.
226    pub const fn uninit() -> Self {
227        Self {
228            value: UnsafeCell::new(MaybeUninit::uninit()),
229            _pin: PhantomPinned,
230        }
231    }
232
233    /// Creates a pin-initializer from the given initializer closure.
234    ///
235    /// The returned initializer calls the given closure with the pointer to the inner `T` of this
236    /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
237    ///
238    /// This function is safe, because the `T` inside of an `Opaque` is allowed to be
239    /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
240    /// to verify at that point that the inner value is valid.
241    pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> {
242        // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
243        // initialize the `T`.
244        unsafe {
245            init::pin_init_from_closure::<_, ::core::convert::Infallible>(move |slot| {
246                init_func(Self::raw_get(slot));
247                Ok(())
248            })
249        }
250    }
251
252    /// Returns a raw pointer to the opaque data.
253    pub const fn get(&self) -> *mut T {
254        UnsafeCell::get(&self.value).cast::<T>()
255    }
256
257    /// Gets the value behind `this`.
258    ///
259    /// This function is useful to get access to the value without creating intermediate
260    /// references.
261    pub const fn raw_get(this: *const Self) -> *mut T {
262        UnsafeCell::raw_get(this.cast::<UnsafeCell<MaybeUninit<T>>>()).cast::<T>()
263    }
264}
265
266/// Types that are _always_ reference counted.
267///
268/// It allows such types to define their own custom ref increment and decrement functions.
269/// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
270/// [`ARef<T>`].
271///
272/// This is usually implemented by wrappers to existing structures on the C side of the code. For
273/// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
274/// instances of a type.
275///
276/// # Safety
277///
278/// Implementers must ensure that increments to the reference count keep the object alive in memory
279/// at least until matching decrements are performed.
280///
281/// Implementers must also ensure that all instances are reference-counted. (Otherwise they
282/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
283/// alive.)
284pub unsafe trait AlwaysRefCounted {
285    /// Increments the reference count on the object.
286    fn inc_ref(&self);
287
288    /// Decrements the reference count on the object.
289    ///
290    /// Frees the object when the count reaches zero.
291    ///
292    /// # Safety
293    ///
294    /// Callers must ensure that there was a previous matching increment to the reference count,
295    /// and that the object is no longer used after its reference count is decremented (as it may
296    /// result in the object being freed), unless the caller owns another increment on the refcount
297    /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
298    /// [`AlwaysRefCounted::dec_ref`] once).
299    unsafe fn dec_ref(obj: NonNull<Self>);
300}
301
302/// An owned reference to an always-reference-counted object.
303///
304/// The object's reference count is automatically decremented when an instance of [`ARef`] is
305/// dropped. It is also automatically incremented when a new instance is created via
306/// [`ARef::clone`].
307///
308/// # Invariants
309///
310/// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
311/// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
312pub struct ARef<T: AlwaysRefCounted> {
313    ptr: NonNull<T>,
314    _p: PhantomData<T>,
315}
316
317// SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
318// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
319// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
320// mutable reference, for example, when the reference count reaches zero and `T` is dropped.
321unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
322
323// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
324// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
325// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
326// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
327// example, when the reference count reaches zero and `T` is dropped.
328unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
329
330impl<T: AlwaysRefCounted> ARef<T> {
331    /// Creates a new instance of [`ARef`].
332    ///
333    /// It takes over an increment of the reference count on the underlying object.
334    ///
335    /// # Safety
336    ///
337    /// Callers must ensure that the reference count was incremented at least once, and that they
338    /// are properly relinquishing one increment. That is, if there is only one increment, callers
339    /// must not use the underlying object anymore -- it is only safe to do so via the newly
340    /// created [`ARef`].
341    pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
342        // INVARIANT: The safety requirements guarantee that the new instance now owns the
343        // increment on the refcount.
344        Self {
345            ptr,
346            _p: PhantomData,
347        }
348    }
349
350    /// Consumes the `ARef`, returning a raw pointer.
351    ///
352    /// This function does not change the refcount. After calling this function, the caller is
353    /// responsible for the refcount previously managed by the `ARef`.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// use core::ptr::NonNull;
359    /// use kernel::types::{ARef, AlwaysRefCounted};
360    ///
361    /// struct Empty {}
362    ///
363    /// # // SAFETY: TODO.
364    /// unsafe impl AlwaysRefCounted for Empty {
365    ///     fn inc_ref(&self) {}
366    ///     unsafe fn dec_ref(_obj: NonNull<Self>) {}
367    /// }
368    ///
369    /// let mut data = Empty {};
370    /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
371    /// # // SAFETY: TODO.
372    /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
373    /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
374    ///
375    /// assert_eq!(ptr, raw_ptr);
376    /// ```
377    pub fn into_raw(me: Self) -> NonNull<T> {
378        ManuallyDrop::new(me).ptr
379    }
380}
381
382impl<T: AlwaysRefCounted> Clone for ARef<T> {
383    fn clone(&self) -> Self {
384        self.inc_ref();
385        // SAFETY: We just incremented the refcount above.
386        unsafe { Self::from_raw(self.ptr) }
387    }
388}
389
390impl<T: AlwaysRefCounted> Deref for ARef<T> {
391    type Target = T;
392
393    fn deref(&self) -> &Self::Target {
394        // SAFETY: The type invariants guarantee that the object is valid.
395        unsafe { self.ptr.as_ref() }
396    }
397}
398
399impl<T: AlwaysRefCounted> From<&T> for ARef<T> {
400    fn from(b: &T) -> Self {
401        b.inc_ref();
402        // SAFETY: We just incremented the refcount above.
403        unsafe { Self::from_raw(NonNull::from(b)) }
404    }
405}
406
407impl<T: AlwaysRefCounted> Drop for ARef<T> {
408    fn drop(&mut self) {
409        // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
410        // decrement.
411        unsafe { T::dec_ref(self.ptr) };
412    }
413}
414
415/// A sum type that always holds either a value of type `L` or `R`.
416pub enum Either<L, R> {
417    /// Constructs an instance of [`Either`] containing a value of type `L`.
418    Left(L),
419
420    /// Constructs an instance of [`Either`] containing a value of type `R`.
421    Right(R),
422}
423
424/// Types for which any bit pattern is valid.
425///
426/// Not all types are valid for all values. For example, a `bool` must be either zero or one, so
427/// reading arbitrary bytes into something that contains a `bool` is not okay.
428///
429/// It's okay for the type to have padding, as initializing those bytes has no effect.
430///
431/// # Safety
432///
433/// All bit-patterns must be valid for this type. This type must not have interior mutability.
434pub unsafe trait FromBytes {}
435
436macro_rules! impl_frombytes {
437    ($($({$($generics:tt)*})? $t:ty, )*) => {
438        // SAFETY: Safety comments written in the macro invocation.
439        $(unsafe impl$($($generics)*)? FromBytes for $t {})*
440    };
441}
442
443impl_frombytes! {
444    // SAFETY: All bit patterns are acceptable values of the types below.
445    u8, u16, u32, u64, usize,
446    i8, i16, i32, i64, isize,
447
448    // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
449    // patterns are also acceptable for arrays of that type.
450    {<T: FromBytes>} [T],
451    {<T: FromBytes, const N: usize>} [T; N],
452}
453
454/// Types that can be viewed as an immutable slice of initialized bytes.
455///
456/// If a struct implements this trait, then it is okay to copy it byte-for-byte to userspace. This
457/// means that it should not have any padding, as padding bytes are uninitialized. Reading
458/// uninitialized memory is not just undefined behavior, it may even lead to leaking sensitive
459/// information on the stack to userspace.
460///
461/// The struct should also not hold kernel pointers, as kernel pointer addresses are also considered
462/// sensitive. However, leaking kernel pointers is not considered undefined behavior by Rust, so
463/// this is a correctness requirement, but not a safety requirement.
464///
465/// # Safety
466///
467/// Values of this type may not contain any uninitialized bytes. This type must not have interior
468/// mutability.
469pub unsafe trait AsBytes {}
470
471macro_rules! impl_asbytes {
472    ($($({$($generics:tt)*})? $t:ty, )*) => {
473        // SAFETY: Safety comments written in the macro invocation.
474        $(unsafe impl$($($generics)*)? AsBytes for $t {})*
475    };
476}
477
478impl_asbytes! {
479    // SAFETY: Instances of the following types have no uninitialized portions.
480    u8, u16, u32, u64, usize,
481    i8, i16, i32, i64, isize,
482    bool,
483    char,
484    str,
485
486    // SAFETY: If individual values in an array have no uninitialized portions, then the array
487    // itself does not have any uninitialized portions either.
488    {<T: AsBytes>} [T],
489    {<T: AsBytes, const N: usize>} [T; N],
490}