Skip to main content

kernel/
grant.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Support for processes granting memory from their allocations to the kernel.
6//!
7//! ## Grant Overview
8//!
9//! Grants allow capsules to dynamically allocate memory from a process to hold
10//! state on the process's behalf.
11//!
12//! Each capsule that wishes to do this needs to have a [`Grant`] type. Grants
13//! are created at boot, and each have a unique ID and a type `T`. This type
14//! only allows the capsule to allocate memory from a process in the future. It
15//! does not initially represent any allocated memory.
16//!
17//! When a capsule does wish to use its Grant to allocate memory from a process,
18//! it must "enter" the Grant with a specific [`ProcessId`]. Entering a Grant
19//! for a specific process instructs the core kernel to create an object `T` in
20//! the process's memory space and provide the capsule with access to it. If the
21//! Grant has not previously been entered for that process, the memory for
22//! object `T` will be allocated from the "grant region" within the
23//! kernel-accessible portion of the process's memory.
24//!
25//! If a Grant has never been entered for a process, the object `T` will _not_
26//! be allocated in that process's grant region, even if the `Grant` has been
27//! entered for other processes.
28//!
29//! Upcalls and allowed buffer references are stored in the dynamically
30//! allocated grant for a particular Driver as well. Upcalls and allowed buffer
31//! references are stored outside of the `T` object to enable the kernel to
32//! manage them and ensure swapping guarantees are met.
33//!
34//! The type `T` of a Grant is fixed in size and the number of upcalls and
35//! allowed buffers associated with a grant is fixed. That is, when a Grant is
36//! entered for a process the resulting allocated object will be the size of
37//! `SizeOf<T>` plus the size for the structure to hold upcalls and allowed
38//! buffer references. If capsules need additional process-specific memory for
39//! their operation, they can use an [`GrantRegionAllocator`] to request
40//! additional memory from the process's grant region.
41//!
42//! ```text,ignore
43//!                            ┌──────────────────┐
44//!                            │                  │
45//!                            │ Capsule          │
46//!                            │                  │
47//!                            └─┬────────────────┘
48//!                              │ Capsules hold
49//!                              │ references to
50//!                              │ grants.
51//!                              ▼
52//!                            ┌──────────────────┐
53//!                            │ Grant            │
54//!                            │                  │
55//!  Process Memory            │ Type: T          │
56//! ┌────────────────────────┐ │ grant_num: 1     │
57//! │                        │ │ driver_num: 0x4  │
58//! │  ...                   │ └───┬─────────────┬┘
59//! ├────────────────────────┤     │Each Grant   │
60//! │ Grant       ptr 0      │     │has a pointer│
61//! │ Pointers    ptr 1 ───┐ │ ◄───┘per process. │
62//! │             ...      │ │                   │
63//! │             ptr N    │ │                   │
64//! ├──────────────────────┼─┤                   │
65//! │  ...                 │ │                   │
66//! ├──────────────────────┼─┤                   │
67//! │ Grant Region         │ │     When a Grant  │
68//! │                      │ │     is allocated  │
69//! │ ┌─────────────────┐  │ │     for a process │
70//! │ │ Allocated Grant │  │ │ ◄─────────────────┘
71//! │ │                 │  │ │     it uses memory
72//! │ │  [ SizeOf<T> ]  │  │ │     from the grant
73//! │ │─────────────────│  │ │     region.
74//! │ │ Padding         │  │ │
75//! │ │─────────────────│  │ │
76//! │ │ GrantKernelData │  │ │
77//! │ └─────────────────┘◄─┘ │
78//! │                        │
79//! │ ┌─────────────────┐    │
80//! │ │ Custom Grant    │    │ ◄── Capsules can
81//! │ │                 │    │     allocate extra
82//! │ └─────────────────┘    │     memory if needed.
83//! │                        │
84//! ├─kernel_brk─────────────┤
85//! │                        │
86//! │ ...                    │
87//! └────────────────────────┘
88//! ```
89//!
90//! ## Grant Mechanisms and Types
91//!
92//! Here is an overview of the types used by grant.rs to implement the Grant
93//! functionality in Tock:
94//!
95//! ```text,ignore
96//!                         ┌──────────────────────────┐
97//!                         │ struct Grant<T, ...> {   │
98//!                         │   driver_num: usize      │
99//!                         │   grant_num: usize       │
100//!                         │ }                        ├───┐
101//! Entering a Grant for a  └──┬───────────────────────┘   │
102//! process causes the         │                           │
103//! memory for T to be         │ .enter(ProcessId)         │ .enter(ProcessId, fn)
104//! allocated.                 ▼                           │
105//!                         ┌──────────────────────────┐   │ For convenience,
106//! ProcessGrant represents │ struct ProcessGrant<T> { │   │ allocating and getting
107//! a Grant allocated for a │   number: usize          │   │ access to the T object
108//! specific process.       │   process: &Process      │   │ is combined in one
109//!                         │ }                        │   │ .enter() call.
110//! A provided closure      └──┬───────────────────────┘   │
111//! is given access to         │                           │
112//! the underlying memory      │ .enter(fn)                │
113//! where the T is stored.     ▼                           │
114//!                         ┌────────────────────────────┐ │
115//! GrantData wraps the     │ struct GrantData<T>   {    │◄┘
116//! type and provides       │   data: &mut T             │
117//! mutable access.         │ }                          │
118//! GrantKernelData         │ struct GrantKernelData {   │
119//! provides access to      │   upcalls: [SavedUpcall]   │
120//! scheduling upcalls      │   allow_ro: [SavedAllowRo] │
121//! and process buffers.    │   allow_rw: [SavedAllowRW] │
122//!                         │ }                          │
123//!                         └──┬─────────────────────────┘
124//! The actual object T can    │
125//! only be accessed inside    │ fn(mem: &GrantData, kernel_data: &GrantKernelData)
126//! the closure.               ▼
127//! ```
128
129use core::cmp;
130use core::marker::PhantomData;
131use core::mem::{align_of, size_of};
132use core::ops::{Deref, DerefMut};
133use core::ptr::{NonNull, write};
134use core::slice;
135
136use crate::ErrorCode;
137use crate::config;
138use crate::debug;
139use crate::kernel::Kernel;
140use crate::process::ProcessSlot;
141use crate::process::{Error, Process, ProcessCustomGrantIdentifier, ProcessId};
142use crate::processbuffer::{ReadOnlyProcessBuffer, ReadWriteProcessBuffer};
143use crate::processbuffer::{ReadOnlyProcessBufferRef, ReadWriteProcessBufferRef};
144use crate::upcall::{Upcall, UpcallError, UpcallId};
145use crate::utilities::capability_ptr::CapabilityPtr;
146use crate::utilities::machine_register::MachineRegister;
147
148/// Tracks how many upcalls a grant instance supports automatically.
149pub trait UpcallSize {
150    /// The number of upcalls the grant supports.
151    const COUNT: u8;
152}
153
154/// Specifies how many upcalls a grant instance supports automatically.
155pub struct UpcallCount<const NUM: u8>;
156impl<const NUM: u8> UpcallSize for UpcallCount<NUM> {
157    const COUNT: u8 = NUM;
158}
159
160/// Tracks how many read-only allows a grant instance supports automatically.
161pub trait AllowRoSize {
162    /// The number of read-only allows the grant supports.
163    const COUNT: u8;
164}
165
166/// Specifies how many read-only allows a grant instance supports automatically.
167pub struct AllowRoCount<const NUM: u8>;
168impl<const NUM: u8> AllowRoSize for AllowRoCount<NUM> {
169    const COUNT: u8 = NUM;
170}
171
172/// Tracks how many read-write allows a grant instance supports automatically.
173pub trait AllowRwSize {
174    /// The number of read-write allows the grant supports.
175    const COUNT: u8;
176}
177
178/// Specifies how many read-write allows a grant instance supports
179/// automatically.
180pub struct AllowRwCount<const NUM: u8>;
181impl<const NUM: u8> AllowRwSize for AllowRwCount<NUM> {
182    const COUNT: u8 = NUM;
183}
184
185/// Helper that calculated offsets within the kernel owned memory (i.e. the
186/// non-T part of grant).
187///
188/// Example layout of full grant belonging to a single app and driver:
189///
190/// ```text,ignore
191/// 0x003FFC8  ┌────────────────────────────────────┐
192///            │   T                                |
193/// 0x003FFxx  ├  ───────────────────────── ┐ K     |
194///            │   Padding (ensure T aligns)| e     |
195/// 0x003FF44  ├  ───────────────────────── | r     |
196///            │   SavedAllowRwN            | n     |
197///            │   ...                      | e     | G
198///            │   SavedAllowRw1            | l     | r
199///            │   SavedAllowRw0            |       | a
200/// 0x003FF44  ├  ───────────────────────── | O     | n
201///            │   SavedAllowRoN            | w     | t
202///            │   ...                      | n     |
203///            │   SavedAllowRo1            | e     | M
204///            │   SavedAllowRo0            | d     | e
205/// 0x003FF30  ├  ───────────────────────── |       | m
206///            │   SavedUpcallN             | D     | o
207///            │   ...                      | a     | r
208///            │   SavedUpcall1             | t     | y
209///            │   SavedUpcall0             | a     |
210/// 0x003FF24  ├  ───────────────────────── |       |
211///            │   Counters (usize)         |       |
212/// 0x003FF20  └────────────────────────────────────┘
213/// ```
214///
215/// The counters structure is composed as:
216///
217/// ```text,ignore
218/// 0             1             2             3         bytes
219/// |-------------|-------------|-------------|-------------|
220/// | # Upcalls   | # RO Allows | # RW Allows | [unused]    |
221/// |-------------|-------------|-------------|-------------|
222/// ```
223///
224/// This type is created whenever a grant is entered, and is responsible for
225/// ensuring that the grant is closed when it is no longer used. On `Drop`, we
226/// leave the grant. This protects against calling `grant.enter()` without
227/// calling the corresponding `grant.leave()`, perhaps due to accidentally using
228/// the `?` operator.
229struct EnteredGrantKernelManagedLayout<'a> {
230    /// Leaving a grant is handled through the process implementation, so must
231    /// keep a reference to the relevant process.
232    process: &'a dyn Process,
233    /// The grant number of the entered grant that we want to ensure we leave
234    /// properly.
235    grant_num: usize,
236
237    /// The location of the counters structure for the grant.
238    counters_ptr: *mut usize,
239    /// Pointer to the array of saved upcalls.
240    upcalls_array: *mut SavedUpcall,
241    /// Pointer to the array of saved read-only allows.
242    allow_ro_array: *mut SavedAllowRo,
243    /// Pointer to the array of saved read-write allows.
244    allow_rw_array: *mut SavedAllowRw,
245}
246
247/// Represents the number of the upcall elements in the kernel owned section of
248/// the grant.
249#[derive(Copy, Clone)]
250struct UpcallItems(u8);
251/// Represents the number of the read-only allow elements in the kernel owned
252/// section of the grant.
253#[derive(Copy, Clone)]
254struct AllowRoItems(u8);
255/// Represents the number of the read-write allow elements in the kernel owned
256/// section of the grant.
257#[derive(Copy, Clone)]
258struct AllowRwItems(u8);
259/// Represents the size data (in bytes) T within the grant.
260#[derive(Copy, Clone)]
261struct GrantDataSize(usize);
262/// Represents the alignment of data T within the grant.
263#[derive(Copy, Clone)]
264struct GrantDataAlign(usize);
265
266impl<'a> EnteredGrantKernelManagedLayout<'a> {
267    /// Reads the specified pointer as the base of the kernel owned grant region
268    /// that has previously been initialized.
269    ///
270    /// # Safety
271    ///
272    /// The incoming base pointer must be well aligned and already contain
273    /// initialized data in the expected form. There must not be any other
274    /// `EnteredGrantKernelManagedLayout` for the given `base_ptr` at the same
275    /// time, otherwise multiple mutable references to the same upcall/allow
276    /// slices could be created.
277    unsafe fn read_from_base(
278        base_ptr: NonNull<u8>,
279        process: &'a dyn Process,
280        grant_num: usize,
281    ) -> Self {
282        let counters_ptr: *mut usize = base_ptr.as_ptr().cast();
283
284        // # Safety
285        //
286        // The safety requirement for the function ensures that `base_ptr` is
287        // well aligned and there is an initialized counters structure there.
288        let counters_val = unsafe { counters_ptr.read() };
289
290        // Parse the counters field for each of the fields
291        let [_, _, allow_ro_num, upcalls_num] = u32::to_be_bytes(counters_val as u32);
292
293        // Skip over the counter usize, then the stored array of `SavedAllowRo`
294        // items and `SavedAllowRw` items.
295        //
296        // # Safety
297        //
298        // The safety requirement for the function ensures that `base_ptr` is
299        // well aligned and there are initialized arrays of saved upcalls and
300        // allows above the counters.
301        let (upcalls_array, allow_ro_array, allow_rw_array) = unsafe {
302            let upcalls_array: *mut SavedUpcall = counters_ptr.add(1).cast();
303            let allow_ro_array: *mut SavedAllowRo = upcalls_array.add(upcalls_num as usize).cast();
304            let allow_rw_array: *mut SavedAllowRw =
305                allow_ro_array.add(allow_ro_num as usize).cast();
306            (upcalls_array, allow_ro_array, allow_rw_array)
307        };
308
309        Self {
310            process,
311            grant_num,
312            counters_ptr,
313            upcalls_array,
314            allow_ro_array,
315            allow_rw_array,
316        }
317    }
318
319    /// Creates a layout from the specified pointer and lengths of arrays and
320    /// initializes the kernel owned portion of the layout.
321    ///
322    /// # Safety
323    ///
324    /// The incoming base pointer must be well aligned and reference enough
325    /// memory to hold the entire kernel managed grant structure. There must
326    /// not be any other `EnteredGrantKernelManagedLayout` for
327    /// the given `base_ptr` at the same time, otherwise multiple mutable
328    /// references to the same upcall/allow slices could be created.
329    unsafe fn initialize_from_counts(
330        base_ptr: NonNull<u8>,
331        upcalls_num_val: UpcallItems,
332        allow_ro_num_val: AllowRoItems,
333        allow_rw_num_val: AllowRwItems,
334        process: &'a dyn Process,
335        grant_num: usize,
336    ) -> Self {
337        let counters_ptr: *mut usize = base_ptr.as_ptr().cast();
338
339        // Create the counters usize value by correctly packing the various
340        // counts into 8 bit fields.
341        let counter: usize =
342            u32::from_be_bytes([0, allow_rw_num_val.0, allow_ro_num_val.0, upcalls_num_val.0])
343                as usize;
344
345        // # Safety
346        //
347        // Callers guarantee that the `base_ptr` is well aligned to the kernel
348        // managed grant structure and these pointers reconstruct that grant
349        // structure.
350        let (upcalls_array, allow_ro_array, allow_rw_array) = unsafe {
351            let upcalls_array: *mut SavedUpcall = counters_ptr.add(1).cast();
352            let allow_ro_array: *mut SavedAllowRo =
353                upcalls_array.add(upcalls_num_val.0.into()).cast();
354            let allow_rw_array: *mut SavedAllowRw =
355                allow_ro_array.add(allow_ro_num_val.0.into()).cast();
356            (upcalls_array, allow_ro_array, allow_rw_array)
357        };
358
359        // # Safety
360        //
361        // Callers guarantee that the `base_ptr` is well aligned to the kernel
362        // managed grant structure and there is enough memory to hold the entire
363        // grant structure. That ensures writing the grant structure is safe.
364        unsafe {
365            counters_ptr.write(counter);
366            write_default_array(upcalls_array, upcalls_num_val.0.into());
367            write_default_array(allow_ro_array, allow_ro_num_val.0.into());
368            write_default_array(allow_rw_array, allow_rw_num_val.0.into());
369        }
370
371        Self {
372            process,
373            grant_num,
374            counters_ptr,
375            upcalls_array,
376            allow_ro_array,
377            allow_rw_array,
378        }
379    }
380
381    /// Returns the entire grant size including the kernel owned memory,
382    /// padding, and data for T. Requires that grant_t_align be a power of 2,
383    /// which is guaranteed from align_of rust calls.
384    fn grant_size(
385        upcalls_num: UpcallItems,
386        allow_ro_num: AllowRoItems,
387        allow_rw_num: AllowRwItems,
388        grant_t_size: GrantDataSize,
389        grant_t_align: GrantDataAlign,
390    ) -> usize {
391        let kernel_managed_size = size_of::<usize>()
392            + upcalls_num.0 as usize * size_of::<SavedUpcall>()
393            + allow_ro_num.0 as usize * size_of::<SavedAllowRo>()
394            + allow_rw_num.0 as usize * size_of::<SavedAllowRw>();
395        // We know that grant_t_align is a power of 2, so we can make a mask
396        // that will save only the remainder bits.
397        let grant_t_align_mask = grant_t_align.0 - 1;
398        // Determine padding to get to the next multiple of grant_t_align by
399        // taking the remainder and subtracting that from the alignment, then
400        // ensuring a full alignment value maps to 0.
401        let padding =
402            (grant_t_align.0 - (kernel_managed_size & grant_t_align_mask)) & grant_t_align_mask;
403        kernel_managed_size + padding + grant_t_size.0
404    }
405
406    /// Returns the alignment of the entire grant region based on the alignment
407    /// of data T.
408    fn grant_align(grant_t_align: GrantDataAlign) -> usize {
409        // The kernel owned memory all aligned to usize. We need to use the
410        // higher of the two alignment to ensure our padding calculations work
411        // for any alignment of T.
412        cmp::max(align_of::<usize>(), grant_t_align.0)
413    }
414
415    /// Returns the offset for the grant data t within the entire grant region.
416    ///
417    /// # Safety
418    ///
419    /// The caller must ensure that the specified base pointer is aligned to at
420    /// least the alignment of T and points to a grant that is of size
421    /// grant_size bytes.
422    unsafe fn offset_of_grant_data_t(
423        base_ptr: NonNull<u8>,
424        grant_size: usize,
425        grant_t_size: GrantDataSize,
426    ) -> NonNull<u8> {
427        // # Safety
428        //
429        // The location of the grant data T is the last element in the entire
430        // grant region. Caller must verify that memory is accessible and well
431        // aligned to T.
432        unsafe {
433            let grant_t_size_usize: usize = grant_t_size.0;
434            NonNull::new_unchecked(base_ptr.as_ptr().add(grant_size - grant_t_size_usize))
435        }
436    }
437
438    /// Read an 8 bit value from the counter field offset by the specified
439    /// number of bits. This is a helper function for reading the counter field.
440    fn get_counter_offset(&self, offset_bits: usize) -> usize {
441        // # Safety
442        //
443        // Creating a `EnteredGrantKernelManagedLayout` object requires that the
444        // pointers are well aligned and point to valid memory.
445        let counters_val = unsafe { self.counters_ptr.read() };
446        (counters_val >> offset_bits) & 0xFF
447    }
448
449    /// Return the number of upcalls stored by the core kernel for this grant.
450    fn get_upcalls_number(&self) -> usize {
451        self.get_counter_offset(0)
452    }
453
454    /// Return the number of read-only allow buffers stored by the core kernel
455    /// for this grant.
456    fn get_allow_ro_number(&self) -> usize {
457        self.get_counter_offset(8)
458    }
459
460    /// Return the number of read-write allow buffers stored by the core kernel
461    /// for this grant.
462    fn get_allow_rw_number(&self) -> usize {
463        self.get_counter_offset(16)
464    }
465
466    /// Return mutable access to the slice of stored upcalls for this grant.
467    /// This is necessary for storing a new upcall.
468    fn get_upcalls_slice(&mut self) -> &mut [SavedUpcall] {
469        // # Safety
470        //
471        // Creating a `EnteredGrantKernelManagedLayout` object ensures that the
472        // pointer to the upcall array is valid.
473        unsafe { slice::from_raw_parts_mut(self.upcalls_array, self.get_upcalls_number()) }
474    }
475
476    /// Return mutable access to the slice of stored read-only allow buffers for
477    /// this grant. This is necessary for storing a new read-only allow.
478    fn get_allow_ro_slice(&mut self) -> &mut [SavedAllowRo] {
479        // # Safety
480        //
481        // Creating a `EnteredGrantKernelManagedLayout` object ensures that the
482        // pointer to the RO allow array is valid.
483        unsafe { slice::from_raw_parts_mut(self.allow_ro_array, self.get_allow_ro_number()) }
484    }
485
486    /// Return mutable access to the slice of stored read-write allow buffers
487    /// for this grant. This is necessary for storing a new read-write allow.
488    fn get_allow_rw_slice(&mut self) -> &mut [SavedAllowRw] {
489        // # Safety
490        //
491        // Creating a `EnteredGrantKernelManagedLayout` object ensures that the
492        // pointer to the RW allow array is valid.
493        unsafe { slice::from_raw_parts_mut(self.allow_rw_array, self.get_allow_rw_number()) }
494    }
495
496    /// Return slices to the kernel managed upcalls and allow buffers. This
497    /// permits using upcalls and allow buffers when a capsule is accessing a
498    /// grant.
499    fn get_resource_slices(&self) -> (&[SavedUpcall], &[SavedAllowRo], &[SavedAllowRw]) {
500        // # Safety
501        //
502        // Creating a `EnteredGrantKernelManagedLayout` object ensures that the
503        // pointer to the upcall array is valid.
504        let upcall_slice =
505            unsafe { slice::from_raw_parts(self.upcalls_array, self.get_upcalls_number()) };
506
507        // # Safety
508        //
509        // Creating a `EnteredGrantKernelManagedLayout` object ensures that the
510        // pointer to the RO allow array is valid.
511        let allow_ro_slice =
512            unsafe { slice::from_raw_parts(self.allow_ro_array, self.get_allow_ro_number()) };
513
514        // # Safety
515        //
516        // Creating a `KernelManagedLayout` object ensures that the pointer to
517        // the RW allow array is valid.
518        let allow_rw_slice =
519            unsafe { slice::from_raw_parts(self.allow_rw_array, self.get_allow_rw_number()) };
520
521        (upcall_slice, allow_ro_slice, allow_rw_slice)
522    }
523}
524
525// Ensure that we leave the grant once this goes out of scope.
526impl Drop for EnteredGrantKernelManagedLayout<'_> {
527    fn drop(&mut self) {
528        // ### Safety
529        //
530        // To safely call this function we must ensure that no references will
531        // exist to the grant once `leave_grant()` returns. Because using a
532        // `EnteredGrantKernelManagedLayout` object is the only only way we
533        // access the actual memory of a grant, and we are calling
534        // `leave_grant()` from its `drop()` method, we are sure there will be
535        // no remaining references to the grant.
536        unsafe {
537            self.process.leave_grant(self.grant_num);
538        }
539    }
540}
541
542/// This [`GrantData`] object provides access to the memory allocated for a
543/// grant for a specific process.
544///
545/// The [`GrantData`] type is templated on `T`, the actual type of the object in
546/// the grant. [`GrantData`] holds a mutable reference to the type, allowing
547/// users access to the object in process memory.
548///
549/// Capsules gain access to a [`GrantData`] object by calling
550/// [`Grant::enter()`].
551pub struct GrantData<'a, T: 'a + ?Sized> {
552    /// The mutable reference to the actual object type stored in the grant.
553    data: &'a mut T,
554}
555
556impl<'a, T: 'a + ?Sized> GrantData<'a, T> {
557    /// Create a [`GrantData`] object to provide access to the actual object
558    /// allocated for a process.
559    ///
560    /// Only one can [`GrantData`] per underlying object can be created at a
561    /// time. Otherwise, there would be multiple mutable references to the same
562    /// object which is undefined behavior.
563    fn new(data: &'a mut T) -> GrantData<'a, T> {
564        GrantData { data }
565    }
566}
567
568impl<'a, T: 'a + ?Sized> Deref for GrantData<'a, T> {
569    type Target = T;
570    fn deref(&self) -> &T {
571        self.data
572    }
573}
574
575impl<'a, T: 'a + ?Sized> DerefMut for GrantData<'a, T> {
576    fn deref_mut(&mut self) -> &mut T {
577        self.data
578    }
579}
580
581/// This [`GrantKernelData`] object provides a handle to access upcalls and
582/// process buffers stored on behalf of a particular grant/driver.
583///
584/// Capsules gain access to a [`GrantKernelData`] object by calling
585/// [`Grant::enter()`]. From there, they can schedule upcalls or access process
586/// buffers.
587///
588/// It is expected that this type will only exist as a short-lived stack
589/// allocation, so its size is not a significant concern.
590pub struct GrantKernelData<'a> {
591    /// A reference to the actual upcall slice stored in the grant.
592    upcalls: &'a [SavedUpcall],
593
594    /// A reference to the actual read only allow slice stored in the grant.
595    allow_ro: &'a [SavedAllowRo],
596
597    /// A reference to the actual read write allow slice stored in the grant.
598    allow_rw: &'a [SavedAllowRw],
599
600    /// We need to keep track of the driver number so we can properly identify
601    /// the Upcall that is called. We need to keep track of its source so we can
602    /// remove it if the Upcall is unsubscribed.
603    driver_num: usize,
604
605    /// A reference to the process that these upcalls are for. This is used for
606    /// actually scheduling the upcalls.
607    process: &'a dyn Process,
608}
609
610impl<'a> GrantKernelData<'a> {
611    /// Create a [`GrantKernelData`] object to provide a handle for capsules to
612    /// call Upcalls.
613    fn new(
614        upcalls: &'a [SavedUpcall],
615        allow_ro: &'a [SavedAllowRo],
616        allow_rw: &'a [SavedAllowRw],
617        driver_num: usize,
618        process: &'a dyn Process,
619    ) -> GrantKernelData<'a> {
620        Self {
621            upcalls,
622            allow_ro,
623            allow_rw,
624            driver_num,
625            process,
626        }
627    }
628
629    /// Schedule the specified upcall for the process with r0, r1, r2 as
630    /// provided values.
631    ///
632    /// Capsules call this function to schedule upcalls, and upcalls are
633    /// identified by the `subscribe_num`, which must match the subscribe number
634    /// used when the upcall was originally subscribed by a process.
635    /// `subscribe_num`s are indexed starting at zero.
636    pub fn schedule_upcall(
637        &self,
638        subscribe_num: usize,
639        r: (usize, usize, usize),
640    ) -> Result<(), UpcallError> {
641        // Implement `self.upcalls[subscribe_num]` without a chance of a panic.
642        self.upcalls.get(subscribe_num).map_or_else(
643            || {
644                if config::CONFIG.trace_syscalls {
645                    debug!(
646                        "[{:?}] schedule[{:#x}:{}] invalid subscribe_num",
647                        self.process.processid(),
648                        self.driver_num,
649                        subscribe_num,
650                    );
651                }
652
653                Err(UpcallError::InvalidSubscribeNum)
654            },
655            |saved_upcall| {
656                // We can create an `Upcall` object based on what is stored in
657                // the process grant and use that to add the upcall to the
658                // pending array for the process.
659                let upcall = Upcall::new(
660                    self.process.processid(),
661                    UpcallId {
662                        subscribe_num,
663                        driver_num: self.driver_num,
664                    },
665                    saved_upcall.appdata,
666                    saved_upcall.fn_ptr,
667                );
668                upcall.schedule(self.process, r.0, r.1, r.2)
669            },
670        )
671    }
672
673    /// Search the work queue for the first pending operation with the given
674    /// `subscribe_num` and if one exists remove it from the task queue.
675    ///
676    /// Returns the associated [`Task`](crate::process::Task) if one was found, otherwise returns
677    /// [`None`].
678    pub fn remove_upcall(&self, subscribe_num: usize) -> Option<crate::process::Task> {
679        self.process.remove_upcall(UpcallId {
680            subscribe_num,
681            driver_num: self.driver_num,
682        })
683    }
684
685    /// Remove all scheduled upcalls with the given `subscribe_num` from the
686    /// task queue.
687    ///
688    /// Returns the number of removed upcalls.
689    pub fn remove_pending_upcalls(&self, subscribe_num: usize) -> usize {
690        self.process.remove_pending_upcalls(UpcallId {
691            subscribe_num,
692            driver_num: self.driver_num,
693        })
694    }
695
696    /// Returns a lifetime limited reference to the requested
697    /// [`ReadOnlyProcessBuffer`].
698    ///
699    /// The len of the returned [`ReadOnlyProcessBuffer`] must be checked by the
700    /// caller to ensure that a buffer has in fact been allocated. An
701    /// unallocated buffer will be returned as a [`ReadOnlyProcessBuffer`] of
702    /// length 0.
703    ///
704    /// The [`ReadOnlyProcessBuffer`] is only valid for as long as this object
705    /// is valid, i.e. the lifetime of the app enter closure.
706    ///
707    /// If the specified allow number is invalid, then a
708    /// [`crate::process::Error::AddressOutOfBounds`] will be returned. This
709    /// returns a [`crate::process::Error`] to allow for easy chaining of this
710    /// function with the `ReadOnlyProcessBuffer::enter()` function with
711    /// `and_then`.
712    pub fn get_readonly_processbuffer(
713        &self,
714        allow_ro_num: usize,
715    ) -> Result<ReadOnlyProcessBufferRef<'_>, crate::process::Error> {
716        self.allow_ro.get(allow_ro_num).map_or(
717            Err(crate::process::Error::AddressOutOfBounds),
718            |saved_ro| {
719                // # Safety
720                //
721                // This is the saved process buffer data has been validated to
722                // be wholly contained within this process before it was stored.
723                // The lifetime of the ReadOnlyProcessBuffer is bound to the
724                // lifetime of self, which correctly limits dereferencing this
725                // saved pointer to only when it is valid.
726                unsafe {
727                    Ok(ReadOnlyProcessBufferRef::new(
728                        saved_ro.ptr,
729                        saved_ro.len,
730                        self.process.processid(),
731                    ))
732                }
733            },
734        )
735    }
736
737    /// Returns a lifetime limited reference to the requested
738    /// [`ReadWriteProcessBuffer`].
739    ///
740    /// The length of the returned [`ReadWriteProcessBuffer`] must be checked by
741    /// the caller to ensure that a buffer has in fact been allocated. An
742    /// unallocated buffer will be returned as a [`ReadWriteProcessBuffer`] of
743    /// length 0.
744    ///
745    /// The [`ReadWriteProcessBuffer`] is only value for as long as this object
746    /// is valid, i.e. the lifetime of the app enter closure.
747    ///
748    /// If the specified allow number is invalid, then a
749    /// [`crate::process::Error::AddressOutOfBounds`] will be returned. This
750    /// returns a [`crate::process::Error`] to allow for easy chaining of this
751    /// function with the `ReadWriteProcessBuffer::enter()` function with
752    /// `and_then`.
753    pub fn get_readwrite_processbuffer(
754        &self,
755        allow_rw_num: usize,
756    ) -> Result<ReadWriteProcessBufferRef<'_>, crate::process::Error> {
757        self.allow_rw.get(allow_rw_num).map_or(
758            Err(crate::process::Error::AddressOutOfBounds),
759            |saved_rw| {
760                // # Safety
761                //
762                // This is the saved process buffer data has been validated to
763                // be wholly contained within this process before it was stored.
764                // The lifetime of the ReadWriteProcessBuffer is bound to the
765                // lifetime of self, which correctly limits dereferencing this
766                // saved pointer to only when it is valid.
767                unsafe {
768                    Ok(ReadWriteProcessBufferRef::new(
769                        saved_rw.ptr,
770                        saved_rw.len,
771                        self.process.processid(),
772                    ))
773                }
774            },
775        )
776    }
777}
778
779/// A minimal representation of an upcall, used for storing an upcall in a
780/// process' grant table without wasting memory duplicating information such as
781/// process ID.
782#[repr(C)]
783#[derive(Default)]
784struct SavedUpcall {
785    appdata: MachineRegister,
786    fn_ptr: CapabilityPtr,
787}
788
789/// A minimal representation of a read-only allow from app, used for storing a
790/// read-only allow in a process' kernel managed grant space without wasting
791/// memory duplicating information such as process ID.
792#[repr(C)]
793struct SavedAllowRo {
794    ptr: *const u8,
795    len: usize,
796}
797
798// This allow is still needed on the current stable compiler, but generates a warning
799// on the current nightly compiler, as of 05/18/2025. So allow this warning for now.
800// This can probably be fixed on the next nightly update.
801#[allow(clippy::derivable_impls)]
802impl Default for SavedAllowRo {
803    fn default() -> Self {
804        Self {
805            ptr: core::ptr::null(),
806            len: 0,
807        }
808    }
809}
810
811/// A minimal representation of a read-write allow from app, used for storing a
812/// read-write allow in a process' kernel managed grant space without wasting
813/// memory duplicating information such as process ID.
814#[repr(C)]
815struct SavedAllowRw {
816    ptr: *mut u8,
817    len: usize,
818}
819
820// This allow is still needed on the current stable compiler, but generates a warning
821// on the current nightly compiler, as of 05/18/2025. So allow this warning for now.
822// This can probably be fixed on the next nightly update.
823#[allow(clippy::derivable_impls)]
824impl Default for SavedAllowRw {
825    fn default() -> Self {
826        Self {
827            ptr: core::ptr::null_mut(),
828            len: 0,
829        }
830    }
831}
832
833/// Write the default value of T to every element of the array.
834///
835/// # Safety
836///
837/// The pointer must be well aligned and point to allocated memory that is
838/// writable for `size_of::<T> * num` bytes. No Rust references may exist to
839/// memory in the address range spanned by `base..base+num` at the time this
840/// function is called. The memory does not need to be initialized yet. If it
841/// already does contain initialized memory, then those contents will be
842/// overwritten without being `Drop`ed first.
843unsafe fn write_default_array<T: Default>(base: *mut T, num: usize) {
844    // # Safety
845    //
846    // See function description.
847    unsafe {
848        for i in 0..num {
849            base.add(i).write(T::default());
850        }
851    }
852}
853
854/// Enters the grant for the specified process. Caller must hold on to the grant
855/// lifetime guard while they accessing the memory in the layout (second
856/// element).
857fn enter_grant_kernel_managed(
858    process: &dyn Process,
859    driver_num: usize,
860) -> Result<EnteredGrantKernelManagedLayout<'_>, ErrorCode> {
861    let grant_num = process.lookup_grant_from_driver_num(driver_num)?;
862
863    // Check if the grant has been allocated, and if not we cannot enter this
864    // grant.
865    match process.grant_is_allocated(grant_num) {
866        Some(true) => { /* Allocated, nothing to do */ }
867        Some(false) => return Err(ErrorCode::NOMEM),
868        None => return Err(ErrorCode::FAIL),
869    }
870
871    // Return early if no grant.
872    let grant_base_ptr = process.enter_grant(grant_num).or(Err(ErrorCode::NOMEM))?;
873    // # Safety
874    //
875    // We know that this pointer is well aligned and initialized with meaningful
876    // data when the grant region was allocated.
877    let layout = unsafe {
878        EnteredGrantKernelManagedLayout::read_from_base(grant_base_ptr, process, grant_num)
879    };
880    Ok(layout)
881}
882
883/// Subscribe to an upcall by saving the upcall in the grant region for the
884/// process and returning the existing upcall for the same UpcallId.
885pub(crate) fn subscribe(
886    process: &dyn Process,
887    upcall: Upcall,
888) -> Result<Upcall, (Upcall, ErrorCode)> {
889    // Enter grant and keep it open until _grant_open goes out of scope.
890    let mut layout = match enter_grant_kernel_managed(process, upcall.upcall_id.driver_num) {
891        Ok(val) => val,
892        Err(e) => return Err((upcall, e)),
893    };
894
895    // Create the saved upcalls slice from the grant memory.
896    //
897    // # Safety
898    //
899    // This is safe because of how the grant was initially allocated and that
900    // because we were able to enter the grant the grant region must be valid
901    // and initialized. We are also holding the grant open until `_grant_open`
902    // goes out of scope.
903    let saved_upcalls_slice = layout.get_upcalls_slice();
904
905    // Index into the saved upcall slice to get the old upcall. Use .get in case
906    // userspace passed us a bad subscribe number.
907    match saved_upcalls_slice.get_mut(upcall.upcall_id.subscribe_num) {
908        Some(saved_upcall) => {
909            // Create an `Upcall` object with the old saved upcall.
910            let old_upcall = Upcall::new(
911                process.processid(),
912                upcall.upcall_id,
913                saved_upcall.appdata,
914                saved_upcall.fn_ptr,
915            );
916
917            // Overwrite the saved upcall with the new upcall.
918            saved_upcall.appdata = upcall.appdata;
919            saved_upcall.fn_ptr = upcall.fn_ptr;
920
921            // Success!
922            Ok(old_upcall)
923        }
924        None => Err((upcall, ErrorCode::NOSUPPORT)),
925    }
926}
927
928/// Stores the specified read-only process buffer in the kernel managed grant
929/// region for this process and driver. The previous read-only process buffer
930/// stored at the same allow_num id is returned.
931pub(crate) fn allow_ro(
932    process: &dyn Process,
933    driver_num: usize,
934    allow_num: usize,
935    buffer: ReadOnlyProcessBuffer,
936) -> Result<ReadOnlyProcessBuffer, (ReadOnlyProcessBuffer, ErrorCode)> {
937    // Enter grant and keep it open until `_grant_open` goes out of scope.
938    let mut layout = match enter_grant_kernel_managed(process, driver_num) {
939        Ok(val) => val,
940        Err(e) => return Err((buffer, e)),
941    };
942
943    // Create the saved allow ro slice from the grant memory.
944    //
945    // # Safety
946    //
947    // This is safe because of how the grant was initially allocated and that
948    // because we were able to enter the grant the grant region must be valid
949    // and initialized. We are also holding the grant open until _grant_open
950    // goes out of scope.
951    let saved_allow_ro_slice = layout.get_allow_ro_slice();
952
953    // Index into the saved slice to get the old value. Use .get in case
954    // userspace passed us a bad allow number.
955    match saved_allow_ro_slice.get_mut(allow_num) {
956        Some(saved) => {
957            // # Safety
958            //
959            // The pointer has already been validated to be within application
960            // memory before storing the values in the saved slice.
961            let old_allow =
962                unsafe { ReadOnlyProcessBuffer::new(saved.ptr, saved.len, process.processid()) };
963
964            // Replace old values with current buffer.
965            let (ptr, len) = buffer.consume();
966            saved.ptr = ptr;
967            saved.len = len;
968
969            // Success!
970            Ok(old_allow)
971        }
972        None => Err((buffer, ErrorCode::NOSUPPORT)),
973    }
974}
975
976/// Stores the specified read-write process buffer in the kernel managed grant
977/// region for this process and driver. The previous read-write process buffer
978/// stored at the same allow_num id is returned.
979pub(crate) fn allow_rw(
980    process: &dyn Process,
981    driver_num: usize,
982    allow_num: usize,
983    buffer: ReadWriteProcessBuffer,
984) -> Result<ReadWriteProcessBuffer, (ReadWriteProcessBuffer, ErrorCode)> {
985    // Enter grant and keep it open until `_grant_open` goes out of scope.
986    let mut layout = match enter_grant_kernel_managed(process, driver_num) {
987        Ok(val) => val,
988        Err(e) => return Err((buffer, e)),
989    };
990
991    // Create the saved allow rw slice from the grant memory.
992    //
993    // # Safety
994    //
995    // This is safe because of how the grant was initially allocated and that
996    // because we were able to enter the grant the grant region must be valid
997    // and initialized. We are also holding the grant open until `_grant_open`
998    // goes out of scope.
999    let saved_allow_rw_slice = layout.get_allow_rw_slice();
1000
1001    // Index into the saved slice to get the old value. Use .get in case
1002    // userspace passed us a bad allow number.
1003    match saved_allow_rw_slice.get_mut(allow_num) {
1004        Some(saved) => {
1005            // # Safety
1006            //
1007            // The pointer has already been validated to be within application
1008            // memory before storing the values in the saved slice.
1009            let old_allow =
1010                unsafe { ReadWriteProcessBuffer::new(saved.ptr, saved.len, process.processid()) };
1011
1012            // Replace old values with current buffer.
1013            let (ptr, len) = buffer.consume();
1014            saved.ptr = ptr;
1015            saved.len = len;
1016
1017            // Success!
1018            Ok(old_allow)
1019        }
1020        None => Err((buffer, ErrorCode::NOSUPPORT)),
1021    }
1022}
1023
1024/// An instance of a grant allocated for a particular process.
1025///
1026/// [`ProcessGrant`] is a handle to an instance of a grant that has been
1027/// allocated in a specific process's grant region. A [`ProcessGrant`]
1028/// guarantees that the memory for the grant has been allocated in the process's
1029/// memory.
1030///
1031/// This is created from a [`Grant`] when that grant is entered for a specific
1032/// process.
1033pub struct ProcessGrant<
1034    'a,
1035    T: 'a,
1036    Upcalls: UpcallSize,
1037    AllowROs: AllowRoSize,
1038    AllowRWs: AllowRwSize,
1039> {
1040    /// The process the grant is applied to.
1041    ///
1042    /// We use a reference here because instances of [`ProcessGrant`] are very
1043    /// short lived. They only exist while a [`Grant`] is being entered, so we
1044    /// can be sure the process still exists while a `ProcessGrant` exists. No
1045    /// [`ProcessGrant`] can be stored.
1046    process: &'a dyn Process,
1047
1048    /// The syscall driver number this grant is associated with.
1049    driver_num: usize,
1050
1051    /// The identifier of the Grant this is applied for.
1052    grant_num: usize,
1053
1054    /// Used to store Rust types for grant.
1055    _phantom: PhantomData<(T, Upcalls, AllowROs, AllowRWs)>,
1056}
1057
1058impl<'a, T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize>
1059    ProcessGrant<'a, T, Upcalls, AllowROs, AllowRWs>
1060{
1061    /// Create a [`ProcessGrant`] for the given Grant in the given Process's
1062    /// grant region.
1063    ///
1064    /// If the grant in this process has not been setup before this will attempt
1065    /// to allocate the memory from the process's grant region.
1066    ///
1067    /// # Return
1068    ///
1069    /// If the grant is already allocated or could be allocated, and the process
1070    /// is valid, this returns `Ok(ProcessGrant)`. Otherwise it returns a
1071    /// relevant error.
1072    fn new(
1073        grant: &Grant<T, Upcalls, AllowROs, AllowRWs>,
1074        processid: ProcessId,
1075    ) -> Result<Self, Error> {
1076        // Moves non-generic code from new() into non-generic function to reduce
1077        // code bloat from the generic function being monomorphized, as it is
1078        // common to have over 50 copies of Grant::enter() in a Tock kernel (and
1079        // thus 50+ copies of this function). The returned Option indicates if
1080        // the returned pointer still needs to be initialized (in the case where
1081        // the grant was only just allocated).
1082        fn new_inner<'a>(
1083            grant_num: usize,
1084            driver_num: usize,
1085            grant_t_size: GrantDataSize,
1086            grant_t_align: GrantDataAlign,
1087            num_upcalls: UpcallItems,
1088            num_allow_ros: AllowRoItems,
1089            num_allow_rws: AllowRwItems,
1090            processid: ProcessId,
1091        ) -> Result<(Option<NonNull<u8>>, &'a dyn Process), Error> {
1092            // Here is an example of how the grants are laid out in the grant
1093            // region of process's memory:
1094            //
1095            // Mem. Addr.
1096            // 0x0040000  ┌────────────────────────────────────
1097            //            │   DriverNumN    [0x1]
1098            //            │   GrantPointerN [0x003FFC8]
1099            //            │   ...
1100            //            │   DriverNum1    [0x60000]
1101            //            │   GrantPointer1 [0x003FFC0]
1102            //            │   DriverNum0
1103            //            │   GrantPointer0 [0x0000000 (NULL)]
1104            //            ├────────────────────────────────────
1105            //            │   Process Control Block
1106            // 0x003FFE0  ├────────────────────────────────────  Grant Region ┐
1107            //            │   GrantDataN                                      │
1108            // 0x003FFC8  ├────────────────────────────────────               │
1109            //            │   GrantData1                                      ▼
1110            // 0x003FF20  ├────────────────────────────────────
1111            //            │
1112            //            │   --unallocated--
1113            //            │
1114            //            └────────────────────────────────────
1115            //
1116            // An array of pointers (one per possible grant region) point to
1117            // where the actual grant memory is allocated inside of the process.
1118            // The grant memory is not allocated until the actual grant region
1119            // is actually used.
1120
1121            let process = processid
1122                .kernel
1123                .get_process(processid)
1124                .ok_or(Error::NoSuchApp)?;
1125
1126            // Check if the grant is allocated. If not, we allocate it process
1127            // memory first. We then create an `ProcessGrant` object for this
1128            // grant.
1129            if let Some(is_allocated) = process.grant_is_allocated(grant_num) {
1130                if !is_allocated {
1131                    // Calculate the alignment and size for entire grant region.
1132                    let alloc_align = EnteredGrantKernelManagedLayout::grant_align(grant_t_align);
1133                    let alloc_size = EnteredGrantKernelManagedLayout::grant_size(
1134                        num_upcalls,
1135                        num_allow_ros,
1136                        num_allow_rws,
1137                        grant_t_size,
1138                        grant_t_align,
1139                    );
1140
1141                    // Allocate grant, the memory is still uninitialized though.
1142                    if process
1143                        .allocate_grant(grant_num, driver_num, alloc_size, alloc_align)
1144                        .is_err()
1145                    {
1146                        return Err(Error::OutOfMemory);
1147                    }
1148
1149                    let grant_ptr = process.enter_grant(grant_num)?;
1150
1151                    // Create a layout from the counts we have and initialize
1152                    // all memory so it is valid in the future to read as a
1153                    // reference.
1154                    //
1155                    // # Safety
1156                    //
1157                    // - The grant base pointer is well aligned, yet does not
1158                    //   have initialized data.
1159                    // - The pointer points to a large enough space to correctly
1160                    //   write to is guaranteed by alloc of size
1161                    //   `EnteredGrantKernelManagedLayout::grant_size`.
1162                    // - There are no proper rust references that map to these
1163                    //   addresses.
1164                    unsafe {
1165                        let _layout = EnteredGrantKernelManagedLayout::initialize_from_counts(
1166                            grant_ptr,
1167                            num_upcalls,
1168                            num_allow_ros,
1169                            num_allow_rws,
1170                            process,
1171                            grant_num,
1172                        );
1173                    }
1174
1175                    // # Safety
1176                    //
1177                    // The grant pointer points to an alloc that is alloc_size
1178                    // large and is at least as aligned as grant_t_align.
1179                    unsafe {
1180                        Ok((
1181                            Some(EnteredGrantKernelManagedLayout::offset_of_grant_data_t(
1182                                grant_ptr,
1183                                alloc_size,
1184                                grant_t_size,
1185                            )),
1186                            process,
1187                        ))
1188                    }
1189                } else {
1190                    // T was already allocated, outer function should not
1191                    // initialize T.
1192                    Ok((None, process))
1193                }
1194            } else {
1195                // Cannot use the grant region in any way if the process is
1196                // inactive.
1197                Err(Error::InactiveApp)
1198            }
1199        }
1200
1201        // Handle the bulk of the work in a function which is not templated.
1202        let (opt_raw_grant_ptr_nn, process) = new_inner(
1203            grant.grant_num,
1204            grant.driver_num,
1205            GrantDataSize(size_of::<T>()),
1206            GrantDataAlign(align_of::<T>()),
1207            UpcallItems(Upcalls::COUNT),
1208            AllowRoItems(AllowROs::COUNT),
1209            AllowRwItems(AllowRWs::COUNT),
1210            processid,
1211        )?;
1212
1213        // We can now do the initialization of T object if necessary.
1214        if let Some(allocated_ptr) = opt_raw_grant_ptr_nn {
1215            // Grant type T
1216            //
1217            // # Safety
1218            //
1219            // This is safe because:
1220            //
1221            // 1. The pointer address is valid. The pointer is allocated
1222            //    statically in process memory, and will exist for as long
1223            //    as the process does. The grant is only accessible while
1224            //    the process is still valid.
1225            //
1226            // 2. The pointer is correctly aligned. The newly allocated
1227            //    grant is aligned for type T, and there is padding inserted
1228            //    between the upcall array and the T object such that the T
1229            //    object starts a multiple of `align_of<T>` from the
1230            //    beginning of the allocation.
1231            unsafe {
1232                // Convert untyped `*mut u8` allocation to allocated type.
1233                let new_region = NonNull::cast::<T>(allocated_ptr);
1234                // We use `ptr::write` to avoid `Drop`ping the uninitialized
1235                // memory in case `T` implements the `Drop` trait.
1236                write(new_region.as_ptr(), T::default());
1237            }
1238        }
1239
1240        // We have ensured the grant is already allocated or was just allocated,
1241        // so we can create and return the `ProcessGrant` type.
1242        Ok(ProcessGrant {
1243            process,
1244            driver_num: grant.driver_num,
1245            grant_num: grant.grant_num,
1246            _phantom: PhantomData,
1247        })
1248    }
1249
1250    /// Return a [`ProcessGrant`] for a grant in a process if the process is
1251    /// valid and that process grant has already been allocated, or `None`
1252    /// otherwise.
1253    fn new_if_allocated(
1254        grant: &Grant<T, Upcalls, AllowROs, AllowRWs>,
1255        process: &'a dyn Process,
1256    ) -> Option<Self> {
1257        if let Some(is_allocated) = process.grant_is_allocated(grant.grant_num) {
1258            if is_allocated {
1259                Some(ProcessGrant {
1260                    process,
1261                    driver_num: grant.driver_num,
1262                    grant_num: grant.grant_num,
1263                    _phantom: PhantomData,
1264                })
1265            } else {
1266                // Grant has not been allocated.
1267                None
1268            }
1269        } else {
1270            // Process is invalid.
1271            None
1272        }
1273    }
1274
1275    /// Return the [`ProcessId`] of the process this [`ProcessGrant`] is
1276    /// associated with.
1277    pub fn processid(&self) -> ProcessId {
1278        self.process.processid()
1279    }
1280
1281    /// Run a function with access to the memory in the related process for the
1282    /// related Grant. This also provides access to any associated Upcalls and
1283    /// allowed buffers stored with the grant.
1284    ///
1285    /// This is "entering" the grant region, and the _only_ time when the
1286    /// contents of a grant region can be accessed.
1287    ///
1288    /// Note, a grant can only be entered once at a time. Attempting to call
1289    /// `.enter()` on a grant while it is already entered will result in a
1290    /// `panic!()`. See the comment in `access_grant()` for more information.
1291    pub fn enter<F, R>(self, fun: F) -> R
1292    where
1293        F: FnOnce(&mut GrantData<T>, &GrantKernelData) -> R,
1294    {
1295        // # `unwrap()` Safety
1296        //
1297        // `access_grant()` can only return `None` if the grant is already
1298        // entered. Since we are asking for a panic!() if the grant is entered,
1299        // `access_grant()` function will never return `None`.
1300        self.access_grant(fun, true).unwrap()
1301    }
1302
1303    /// Run a function with access to the data in the related process for the
1304    /// related Grant only if that grant region is not already entered. If the
1305    /// grant is already entered silently skip it. Also provide access to
1306    /// associated Upcalls.
1307    ///
1308    /// **You almost certainly should use `.enter()` rather than
1309    /// `.try_enter()`.**
1310    ///
1311    /// While the `.enter()` version can panic, that panic likely indicates a
1312    /// bug in the code and not a condition that should be handled. For example,
1313    /// this benign looking code is wrong:
1314    ///
1315    /// ```ignore
1316    /// self.apps.enter(thisapp, |app_grant, _| {
1317    ///     // Update state in the grant region of `thisapp`. Also, mark that
1318    ///     // `thisapp` needs to run again.
1319    ///     app_grant.runnable = true;
1320    ///
1321    ///     // Now, check all apps to see if any are ready to run.
1322    ///     let mut work_left_to_do = false;
1323    ///     self.apps.iter().each(|other_app| {
1324    ///         other_app.enter(|other_app_grant, _| { // ERROR! This leads to a
1325    ///             if other_app_grant.runnable {      // grant being entered
1326    ///                 work_left_to_do = true;        // twice!
1327    ///             }
1328    ///         })
1329    ///     })
1330    /// })
1331    /// ```
1332    ///
1333    /// The example is wrong because it tries to iterate across all grant
1334    /// regions while one of them is already entered. This will lead to a grant
1335    /// region being entered twice which violates Rust's memory restrictions and
1336    /// is undefined behavior.
1337    ///
1338    /// However, since the example uses `.enter()` on the iteration, Tock will
1339    /// panic when the grant is entered for the second time, notifying the
1340    /// developer that something is wrong. The fix is to exit out of the first
1341    /// `.enter()` before attempting to iterate over the grant for all
1342    /// processes.
1343    ///
1344    /// However, if the example used `.try_enter()` in the iter loop, there
1345    /// would be no panic, but the already entered grant would be silently
1346    /// skipped. This can hide subtle bugs if the skipped grant is only relevant
1347    /// in certain cases.
1348    ///
1349    /// Therefore, only use `try_enter()` if you are sure you want to skip the
1350    /// already entered grant. Cases for this are rare.
1351    ///
1352    /// ## Return
1353    ///
1354    /// Returns `None` if the grant is already entered. Otherwise returns
1355    /// `Some(fun())`.
1356    pub fn try_enter<F, R>(self, fun: F) -> Option<R>
1357    where
1358        F: FnOnce(&mut GrantData<T>, &GrantKernelData) -> R,
1359    {
1360        self.access_grant(fun, false)
1361    }
1362
1363    /// Run a function with access to the memory in the related process for the
1364    /// related Grant. Also provide this function with access to any associated
1365    /// Upcalls and an allocator for allocating additional memory in the
1366    /// process's grant region.
1367    ///
1368    /// This is "entering" the grant region, and the _only_ time when the
1369    /// contents of a grant region can be accessed.
1370    ///
1371    /// Note, a grant can only be entered once at a time. Attempting to call
1372    /// `.enter()` on a grant while it is already entered will result in a
1373    /// panic!()`. See the comment in `access_grant()` for more information.
1374    pub fn enter_with_allocator<F, R>(self, fun: F) -> R
1375    where
1376        F: FnOnce(&mut GrantData<T>, &GrantKernelData, &mut GrantRegionAllocator) -> R,
1377    {
1378        // # `unwrap()` Safety
1379        //
1380        // `access_grant()` can only return `None` if the grant is already
1381        // entered. Since we are asking for a panic!() if the grant is entered,
1382        // `access_grant()` function will never return `None`.
1383        self.access_grant_with_allocator(fun, true).unwrap()
1384    }
1385
1386    /// Access the [`ProcessGrant`] memory and run a closure on the process's
1387    /// grant memory.
1388    ///
1389    /// If `panic_on_reenter` is `true`, this will panic if the grant region is
1390    /// already currently entered. If `panic_on_reenter` is `false`, this will
1391    /// return `None` if the grant region is entered and do nothing.
1392    fn access_grant<F, R>(self, fun: F, panic_on_reenter: bool) -> Option<R>
1393    where
1394        F: FnOnce(&mut GrantData<T>, &GrantKernelData) -> R,
1395    {
1396        self.access_grant_with_allocator(
1397            |grant_data, kernel_data, _allocator| fun(grant_data, kernel_data),
1398            panic_on_reenter,
1399        )
1400    }
1401
1402    /// Access the [`ProcessGrant`] memory and run a closure on the process's
1403    /// grant memory.
1404    ///
1405    /// If `panic_on_reenter` is `true`, this will panic if the grant region is
1406    /// already currently entered. If `panic_on_reenter` is `false`, this will
1407    /// return `None` if the grant region is entered and do nothing.
1408    fn access_grant_with_allocator<F, R>(self, fun: F, panic_on_reenter: bool) -> Option<R>
1409    where
1410        F: FnOnce(&mut GrantData<T>, &GrantKernelData, &mut GrantRegionAllocator) -> R,
1411    {
1412        // Access the grant that is in process memory. This can only fail if
1413        // the grant is already entered.
1414        let grant_ptr = self
1415            .process
1416            .enter_grant(self.grant_num)
1417            .map_err(|_err| {
1418                // If we get an error it is because the grant is already
1419                // entered. `process.enter_grant()` can fail for several
1420                // reasons, but only the double enter case can happen once a
1421                // grant has been applied. The other errors would be detected
1422                // earlier (i.e. before the grant can be applied).
1423
1424                // If `panic_on_reenter` is false, we skip this error and do
1425                // nothing with this grant.
1426                if !panic_on_reenter {
1427                    return;
1428                }
1429
1430                // If `enter_grant` fails, we panic!() to notify the developer
1431                // that they tried to enter the same grant twice which is
1432                // prohibited because it would result in two mutable references
1433                // existing for the same memory. This preserves type correctness
1434                // (but does crash the system).
1435                //
1436                // ## Explanation and Rationale
1437                //
1438                // This panic represents a tradeoff. While it is undesirable to
1439                // have the potential for a runtime crash in this grant region
1440                // code, it balances usability with type correctness. The
1441                // challenge is that calling `self.apps.iter()` is a common
1442                // pattern in capsules to access the grant region of every app
1443                // that is using the capsule, and sometimes it is intuitive to
1444                // call that inside of a `self.apps.enter(processid, |app| {...})`
1445                // closure. However, `.enter()` means that app's grant region is
1446                // entered, and then a naive `.iter()` would re-enter the grant
1447                // region and cause undefined behavior. We considered different
1448                // options to resolve this.
1449                //
1450                // 1. Have `.iter()` only iterate over grant regions which are
1451                //    not entered. This avoids the bug, but could lead to
1452                //    unexpected behavior, as `self.apps.iter()` will do
1453                //    different things depending on where in a capsule it is
1454                //    called.
1455                // 2. Have the compiler detect when `.iter()` is called when a
1456                //    grant region has already been entered. We don't know of a
1457                //    viable way to implement this.
1458                // 3. Panic if `.iter()` is called when a grant is already
1459                //    entered.
1460                //
1461                // We decided on option 3 because it balances minimizing
1462                // surprises (`self.apps.iter()` will always iterate all grants)
1463                // while also protecting against the bug. We expect that any
1464                // code that attempts to call `self.apps.iter()` after calling
1465                // `.enter()` will immediately encounter this `panic!()` and
1466                // have to be refactored before any tests will be successful.
1467                // Therefore, this `panic!()` should only occur at
1468                // development/testing time.
1469                //
1470                // ## How to fix this error
1471                //
1472                // If you are seeing this panic, you need to refactor your
1473                // capsule to not call `.iter()` or `.each()` from inside a
1474                // `.enter()` closure. That is, you need to close the grant
1475                // region you are currently in before trying to iterate over all
1476                // grant regions.
1477                panic!("Attempted to re-enter a grant region.");
1478            })
1479            .ok()?;
1480        let grant_t_align = GrantDataAlign(align_of::<T>());
1481        let grant_t_size = GrantDataSize(size_of::<T>());
1482
1483        let alloc_size = EnteredGrantKernelManagedLayout::grant_size(
1484            UpcallItems(Upcalls::COUNT),
1485            AllowRoItems(AllowROs::COUNT),
1486            AllowRwItems(AllowRWs::COUNT),
1487            grant_t_size,
1488            grant_t_align,
1489        );
1490
1491        // Parse layout of entire grant allocation using the known base pointer.
1492        //
1493        // # Safety
1494        //
1495        // Grant pointer is well aligned and points to initialized data.
1496        let layout = unsafe {
1497            EnteredGrantKernelManagedLayout::read_from_base(grant_ptr, self.process, self.grant_num)
1498        };
1499
1500        // Get references to all of the saved upcall data.
1501        //
1502        // # Safety
1503        //
1504        // - Pointer is well aligned and initialized with data from Self::new()
1505        //   call.
1506        // - Data will not be modified externally while this immutable reference
1507        //   is alive.
1508        // - Data is accessible for the entire duration of this immutable
1509        //   reference.
1510        // - No other mutable reference to this memory exists concurrently.
1511        //   Mutable reference to this memory are only created through the
1512        //   kernel in the syscall interface which is serialized in time with
1513        //   this call.
1514        let (saved_upcalls_slice, saved_allow_ro_slice, saved_allow_rw_slice) =
1515            layout.get_resource_slices();
1516        let grant_data = unsafe {
1517            EnteredGrantKernelManagedLayout::offset_of_grant_data_t(
1518                grant_ptr,
1519                alloc_size,
1520                grant_t_size,
1521            )
1522            .cast()
1523            .as_mut()
1524        };
1525
1526        // Create a wrapped objects that are passed to functor.
1527        let mut grant_data = GrantData::new(grant_data);
1528        let kernel_data = GrantKernelData::new(
1529            saved_upcalls_slice,
1530            saved_allow_ro_slice,
1531            saved_allow_rw_slice,
1532            self.driver_num,
1533            self.process,
1534        );
1535        // Setup an allocator in case the capsule needs additional memory in the
1536        // grant space.
1537        let mut allocator = GrantRegionAllocator {
1538            processid: self.process.processid(),
1539        };
1540
1541        // Call functor and pass back value.
1542        Some(fun(&mut grant_data, &kernel_data, &mut allocator))
1543    }
1544}
1545
1546/// Grant which was allocated from the kernel-owned grant region in a specific
1547/// process's memory, separately from a normal `Grant`.
1548///
1549/// A [`CustomGrant`] allows a capsule to allocate additional memory on behalf
1550/// of a process.
1551pub struct CustomGrant<T> {
1552    /// An identifier for this custom grant within a process's grant region.
1553    ///
1554    /// Here, this is an opaque reference that Process uses to access the
1555    /// custom grant allocation. This setup ensures that Process owns the grant
1556    /// memory.
1557    identifier: ProcessCustomGrantIdentifier,
1558
1559    /// Identifier for the process where this custom grant is allocated.
1560    processid: ProcessId,
1561
1562    /// Used to keep the Rust type of the grant.
1563    _phantom: PhantomData<T>,
1564}
1565
1566impl<T> CustomGrant<T> {
1567    /// Creates a new [`CustomGrant`].
1568    fn new(identifier: ProcessCustomGrantIdentifier, processid: ProcessId) -> Self {
1569        CustomGrant {
1570            identifier,
1571            processid,
1572            _phantom: PhantomData,
1573        }
1574    }
1575
1576    /// Helper function to get the [`ProcessId`] from the custom grant.
1577    pub fn processid(&self) -> ProcessId {
1578        self.processid
1579    }
1580
1581    /// Gives access to inner data within the given closure.
1582    ///
1583    /// If the process has since been restarted or crashed, or the memory is
1584    /// otherwise no longer present, then this function will not call the given
1585    /// closure, and will instead directly return `Err(Error::NoSuchApp)`.
1586    ///
1587    /// Because this function requires `&mut self`, it should be impossible to
1588    /// access the inner data of a given `CustomGrant` reentrantly. Thus the
1589    /// reentrance detection we use for non-custom grants is not needed here.
1590    pub fn enter<F, R>(&self, fun: F) -> Result<R, Error>
1591    where
1592        F: FnOnce(GrantData<'_, T>) -> R,
1593    {
1594        // Verify that the process this CustomGrant was allocated within still
1595        // exists.
1596        self.processid
1597            .kernel
1598            .process_map_or(Err(Error::NoSuchApp), self.processid, |process| {
1599                // App is valid.
1600
1601                // Now try to access the custom grant memory.
1602                let grant_ptr: *mut u8 = process.enter_custom_grant(self.identifier)?;
1603                let grant_ptr: *mut T = grant_ptr.cast();
1604
1605                // # Safety
1606                //
1607                // `grant_ptr` must be a valid pointer and there must not exist
1608                // any other references to the same memory. We verify the
1609                // pointer is valid and aligned when the memory is allocated and
1610                // `CustomGrant` is created. We are sure that there are no
1611                // other references because the only way to create a reference
1612                // is using this `enter()` function, and it can only be called
1613                // once (because of the `&mut self` requirement).
1614                let custom_grant = unsafe { &mut *grant_ptr };
1615                let borrowed = GrantData::new(custom_grant);
1616                Ok(fun(borrowed))
1617            })
1618    }
1619}
1620
1621/// Tool for allocating additional memory regions in a process's grant region.
1622///
1623/// This is optionally provided along with a grant so that if a capsule needs
1624/// per-process dynamic allocation it can allocate additional memory.
1625pub struct GrantRegionAllocator {
1626    /// The process the allocator will allocate memory from.
1627    processid: ProcessId,
1628}
1629
1630impl GrantRegionAllocator {
1631    /// Allocates a new [`CustomGrant`] initialized using the given closure.
1632    ///
1633    /// The closure will be called exactly once, and the result will be used to
1634    /// initialize the owned value.
1635    ///
1636    /// This interface was chosen instead of a simple `alloc(val)` as it's
1637    /// much more likely to optimize out all stack intermediates. This
1638    /// helps to prevent stack overflows when allocating large values.
1639    ///
1640    /// # Panic Safety
1641    ///
1642    /// If `init` panics, the freshly allocated memory may leak.
1643    pub fn alloc_with<T, F>(&self, init: F) -> Result<CustomGrant<T>, Error>
1644    where
1645        F: FnOnce() -> T,
1646    {
1647        let (custom_grant_identifier, typed_ptr) = self.alloc_raw::<T>()?;
1648
1649        // # Safety
1650        //
1651        // Writing to this pointer is safe as long as the pointer is valid
1652        // and aligned. `alloc_raw()` guarantees these constraints are met.
1653        unsafe {
1654            // We use `ptr::write` to avoid `Drop`ping the uninitialized memory
1655            // in case `T` implements the `Drop` trait.
1656            write(typed_ptr.as_ptr(), init());
1657        }
1658
1659        Ok(CustomGrant::new(custom_grant_identifier, self.processid))
1660    }
1661
1662    /// Allocates a slice of n instances of a given type. Each instance is
1663    /// initialized using the provided function.
1664    ///
1665    /// The provided function will be called exactly `n` times, and will be
1666    /// passed the index it's initializing, from `0` through `NUM_ITEMS - 1`.
1667    ///
1668    /// # Panic Safety
1669    ///
1670    /// If `val_func` panics, the freshly allocated memory and any values
1671    /// already written will be leaked.
1672    pub fn alloc_n_with<T, F, const NUM_ITEMS: usize>(
1673        &self,
1674        mut init: F,
1675    ) -> Result<CustomGrant<[T; NUM_ITEMS]>, Error>
1676    where
1677        F: FnMut(usize) -> T,
1678    {
1679        let (custom_grant_identifier, typed_ptr) = self.alloc_n_raw::<T>(NUM_ITEMS)?;
1680
1681        for i in 0..NUM_ITEMS {
1682            // # Safety
1683            //
1684            // The allocate function guarantees that `ptr` points to memory
1685            // large enough to allocate `num_items` copies of the object.
1686            unsafe {
1687                write(typed_ptr.as_ptr().add(i), init(i));
1688            }
1689        }
1690
1691        Ok(CustomGrant::new(custom_grant_identifier, self.processid))
1692    }
1693
1694    /// Allocates uninitialized grant memory appropriate to store a `T`.
1695    ///
1696    /// The caller must initialize the memory.
1697    ///
1698    /// Also returns a ProcessCustomGrantIdentifier to access the memory later.
1699    fn alloc_raw<T>(&self) -> Result<(ProcessCustomGrantIdentifier, NonNull<T>), Error> {
1700        self.alloc_n_raw::<T>(1)
1701    }
1702
1703    /// Allocates space for a dynamic number of items.
1704    ///
1705    /// The caller is responsible for initializing the returned memory.
1706    ///
1707    /// Returns memory appropriate for storing `num_items` contiguous instances
1708    /// of `T` and a ProcessCustomGrantIdentifier to access the memory later.
1709    fn alloc_n_raw<T>(
1710        &self,
1711        num_items: usize,
1712    ) -> Result<(ProcessCustomGrantIdentifier, NonNull<T>), Error> {
1713        let (custom_grant_identifier, raw_ptr) =
1714            self.alloc_n_raw_inner(num_items, size_of::<T>(), align_of::<T>())?;
1715        let typed_ptr = NonNull::cast::<T>(raw_ptr);
1716
1717        Ok((custom_grant_identifier, typed_ptr))
1718    }
1719
1720    /// Helper to reduce code bloat by avoiding monomorphization.
1721    fn alloc_n_raw_inner(
1722        &self,
1723        num_items: usize,
1724        single_alloc_size: usize,
1725        alloc_align: usize,
1726    ) -> Result<(ProcessCustomGrantIdentifier, NonNull<u8>), Error> {
1727        let alloc_size = single_alloc_size
1728            .checked_mul(num_items)
1729            .ok_or(Error::OutOfMemory)?;
1730        self.processid
1731            .kernel
1732            .process_map_or(Err(Error::NoSuchApp), self.processid, |process| {
1733                process
1734                    .allocate_custom_grant(alloc_size, alloc_align)
1735                    .map_or(
1736                        Err(Error::OutOfMemory),
1737                        |(custom_grant_identifier, raw_ptr)| Ok((custom_grant_identifier, raw_ptr)),
1738                    )
1739            })
1740    }
1741}
1742
1743/// Type for storing an object of type T in process memory that is only
1744/// accessible by the kernel.
1745///
1746/// A single [`Grant`] can allocate space for one object of type T for each
1747/// process on the board. Each allocated object will reside in the grant region
1748/// belonging to the process that the object is allocated for. The [`Grant`]
1749/// type is used to get access to [`ProcessGrant`]s, which are tied to a
1750/// specific process and provide access to the memory object allocated for that
1751/// process.
1752pub struct Grant<T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize> {
1753    /// Hold a reference to the core kernel so we can iterate processes.
1754    pub(crate) kernel: &'static Kernel,
1755
1756    /// Keep track of the syscall driver number assigned to the capsule that is
1757    /// using this grant. This allows us to uniquely identify upcalls stored in
1758    /// this grant.
1759    driver_num: usize,
1760
1761    /// The identifier for this grant. Having an identifier allows the Process
1762    /// implementation to lookup the memory for this grant in the specific
1763    /// process.
1764    grant_num: usize,
1765
1766    /// Used to store the Rust types for grant.
1767    ptr: PhantomData<(T, Upcalls, AllowROs, AllowRWs)>,
1768}
1769
1770impl<T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize>
1771    Grant<T, Upcalls, AllowROs, AllowRWs>
1772{
1773    /// Create a new [`Grant`] type which allows a capsule to store
1774    /// process-specific data for each process in the process's memory region.
1775    ///
1776    /// This must only be called from the main kernel so that it can ensure that
1777    /// `grant_index` is a valid index.
1778    pub(crate) fn new(kernel: &'static Kernel, driver_num: usize, grant_index: usize) -> Self {
1779        Self {
1780            kernel,
1781            driver_num,
1782            grant_num: grant_index,
1783            ptr: PhantomData,
1784        }
1785    }
1786
1787    /// Enter the grant for a specific process.
1788    ///
1789    /// This creates a [`ProcessGrant`] which is a handle for a grant allocated
1790    /// for a specific process. Then, that [`ProcessGrant`] is entered and the
1791    /// provided closure is run with access to the memory in the grant region.
1792    pub fn enter<F, R>(&self, processid: ProcessId, fun: F) -> Result<R, Error>
1793    where
1794        F: FnOnce(&mut GrantData<T>, &GrantKernelData) -> R,
1795    {
1796        let pg = ProcessGrant::new(self, processid)?;
1797
1798        // If we have managed to create an `ProcessGrant`, all we need
1799        // to do is actually access the memory and run the
1800        // capsule-provided closure. This can only fail if the grant is
1801        // already entered, at which point the kernel will panic.
1802        Ok(pg.enter(fun))
1803    }
1804
1805    /// Enter the grant for a specific process with access to an allocator.
1806    ///
1807    /// This creates an [`ProcessGrant`] which is a handle for a grant allocated
1808    /// for a specific process. Then, that [`ProcessGrant`] is entered and the
1809    /// provided closure is run with access to the memory in the grant region.
1810    ///
1811    /// The allocator allows the caller to dynamically allocate additional
1812    /// memory in the process's grant region.
1813    pub fn enter_with_allocator<F, R>(&self, processid: ProcessId, fun: F) -> Result<R, Error>
1814    where
1815        F: FnOnce(&mut GrantData<T>, &GrantKernelData, &mut GrantRegionAllocator) -> R,
1816    {
1817        // Get the `ProcessGrant` for the process, possibly needing to
1818        // actually allocate the memory in the process's grant region to
1819        // do so. This can fail for a variety of reasons, and if so we
1820        // return the error to the capsule.
1821        let pg = ProcessGrant::new(self, processid)?;
1822
1823        // If we have managed to create an `ProcessGrant`, all we need
1824        // to do is actually access the memory and run the
1825        // capsule-provided closure. This can only fail if the grant is
1826        // already entered, at which point the kernel will panic.
1827        Ok(pg.enter_with_allocator(fun))
1828    }
1829
1830    /// Run a function on the grant for each active process if the grant has
1831    /// been allocated for that process.
1832    ///
1833    /// This will silently skip any process where the grant has not previously
1834    /// been allocated. This will also silently skip any invalid processes.
1835    ///
1836    /// Calling this function when an [`ProcessGrant`] for a process is
1837    /// currently entered will result in a panic.
1838    pub fn each<F>(&self, mut fun: F)
1839    where
1840        F: FnMut(ProcessId, &mut GrantData<T>, &GrantKernelData),
1841    {
1842        // Create a the iterator across `ProcessGrant`s for each process.
1843        for pg in self.iter() {
1844            let processid = pg.processid();
1845            // Since we iterating, there is no return value we need to worry
1846            // about.
1847            pg.enter(|data, upcalls| fun(processid, data, upcalls));
1848        }
1849    }
1850
1851    /// Get an iterator over all processes and their active grant regions for
1852    /// this particular grant.
1853    ///
1854    /// Calling this function when an [`ProcessGrant`] for a process is
1855    /// currently entered will result in a panic.
1856    pub fn iter(&self) -> Iter<'_, T, Upcalls, AllowROs, AllowRWs> {
1857        Iter {
1858            grant: self,
1859            subiter: self.kernel.get_process_iter(),
1860        }
1861    }
1862}
1863
1864/// Type to iterate [`ProcessGrant`]s across processes.
1865pub struct Iter<
1866    'a,
1867    T: 'a + Default,
1868    Upcalls: UpcallSize,
1869    AllowROs: AllowRoSize,
1870    AllowRWs: AllowRwSize,
1871> {
1872    /// The grant type to use.
1873    grant: &'a Grant<T, Upcalls, AllowROs, AllowRWs>,
1874
1875    /// Iterator over valid processes.
1876    subiter: core::iter::FilterMap<
1877        core::slice::Iter<'a, ProcessSlot>,
1878        fn(&ProcessSlot) -> Option<&'static dyn Process>,
1879    >,
1880}
1881
1882impl<'a, T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize> Iterator
1883    for Iter<'a, T, Upcalls, AllowROs, AllowRWs>
1884{
1885    type Item = ProcessGrant<'a, T, Upcalls, AllowROs, AllowRWs>;
1886
1887    fn next(&mut self) -> Option<Self::Item> {
1888        let grant = self.grant;
1889        // Get the next `ProcessId` from the kernel processes array that is
1890        // setup to use this grant. Since the iterator itself is saved calling
1891        // this function again will start where we left off.
1892        self.subiter
1893            .find_map(|process| ProcessGrant::new_if_allocated(grant, process))
1894    }
1895}