- FrameTable: per-frame owner/use, replaces PagePool + ProcessMemory - Quota per process, page tables charged to owner - Regions for shared mem + device MMIO, torn down w/ owner - Platform: create/destroy AS, map/unmap, zero_frame; drop translate_va - RequestPages/ReleasePages/MapPage(move) checked vs kernel records - user window 0x1000..32MiB, private pts by construction - boot loader + device setup go through kernel api - kernel built in place, boot allocator bounded - isolation tests, randomized invariant test, FrameTable kani proofs - fixes: inflated release, unmapped release, dst va unchecked, heap overflow, unbounded pt alloc, unzeroed frames, double free
39 lines
1.2 KiB
Rust
39 lines
1.2 KiB
Rust
use core::cell::UnsafeCell;
|
|
use core::mem::MaybeUninit;
|
|
use core::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
pub struct KernelCell<T> {
|
|
initialized: AtomicBool,
|
|
inner: UnsafeCell<MaybeUninit<T>>,
|
|
}
|
|
|
|
// Single-core, interrupts disabled during kernel access.
|
|
unsafe impl<T> Sync for KernelCell<T> {}
|
|
|
|
impl<T> KernelCell<T> {
|
|
pub const fn uninit() -> Self {
|
|
Self {
|
|
initialized: AtomicBool::new(false),
|
|
inner: UnsafeCell::new(MaybeUninit::uninit()),
|
|
}
|
|
}
|
|
|
|
/// Initializes the cell by letting `build` write the value straight
|
|
/// into its storage, so a large `T` never lives on the stack.
|
|
///
|
|
/// # Safety
|
|
/// `build` must fully initialize the `T` behind the pointer.
|
|
pub unsafe fn init_with(&self, build: impl FnOnce(*mut T)) {
|
|
build(unsafe { (*self.inner.get()).as_mut_ptr() });
|
|
self.initialized.store(true, Ordering::Release);
|
|
}
|
|
|
|
/// Returns a raw pointer to the kernel. Callers must ensure
|
|
/// no aliasing `&mut` references exist. Safe on single-core
|
|
/// with interrupts disabled during kernel calls.
|
|
pub fn as_ptr(&self) -> *mut T {
|
|
debug_assert!(self.initialized.load(Ordering::Acquire));
|
|
unsafe { (*self.inner.get()).as_mut_ptr() }
|
|
}
|
|
}
|