pub struct FrameAllocOptions { /* private fields */ }Expand description
Options controlling how a physical frame is allocated.
The default configuration (FrameAllocOptions::new()) produces a
zeroed frame. Callers that need a non-zeroed frame (e.g. DMA buffers
that are immediately filled by hardware, or frames that will be fully
overwritten before any read) must explicitly call .zeroed(false).
§Example
// Allocate a zeroed page-table frame (the safe default).
let frame = FrameAllocOptions::new()
.purpose(FramePurpose::PageTable)
.allocate(token)?;
// Allocate a user-data frame without zeroing (caller guarantees it will
// be fully overwritten, e.g. by an ELF segment load).
let frame = FrameAllocOptions::new()
.zeroed(false)
.purpose(FramePurpose::UserData)
.allocate(token)?;Implementations§
Source§impl FrameAllocOptions
impl FrameAllocOptions
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates allocation options with safe defaults:
zeroed = true- purpose =
KernelData
Sourcepub fn zeroed(self, zeroed: bool) -> Self
pub fn zeroed(self, zeroed: bool) -> Self
Override the zero-initialisation policy.
§Safety contract (enforced by convention, not the type system)
If zeroed is set to false, the caller MUST fully overwrite every
byte of the frame before allowing any other CPU or subsystem to read it.
Violating this rule is a memory-safety hazard: stale bytes in an
intermediate page-table node cause the CPU to follow arbitrary PTEs.
Sourcepub fn purpose(self, p: FramePurpose) -> Self
pub fn purpose(self, p: FramePurpose) -> Self
Set the intended purpose of the frame.
PageTable purpose forces zeroing even if .zeroed(false) was called.
Sourcepub fn allocate(self, token: &IrqDisabledToken) -> Result<PhysFrame, AllocError>
pub fn allocate(self, token: &IrqDisabledToken) -> Result<PhysFrame, AllocError>
Allocate a single 4 KiB frame according to the configured options.
The allocation path is:
- Ask the buddy allocator for an order-0 frame (exclusive ownership is guaranteed by the buddy’s own bitmap + free-list discipline).
- Optionally zero the 4 KiB frame contents via the HHDM.
- Stamp
FrameMeta::flagswith the purpose flags usingReleaseordering. - Store
refcount = 1withReleaseordering so any laterAcquireload of the refcount observes the fully-initialised metadata and (if zeroed) zeroed content.
§Sentinel handoff: CAS(REFCOUNT_UNUSED -> 1)
buddy.rs maintains the invariant that every frame on the free list has
refcount == REFCOUNT_UNUSED. mark_block_allocated() leaves this
sentinel intact, so the frame arriving here still carries REFCOUNT_UNUSED.
The CAS atomically claims the frame and acts as a fail-fast corruption
check: if the same frame appears twice in the buddy free list (double-free
or metadata corruption), the second allocation attempt will observe a
refcount of 1 (set by the first allocation) and panic immediately rather
than silently aliasing memory.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for FrameAllocOptions
impl RefUnwindSafe for FrameAllocOptions
impl Send for FrameAllocOptions
impl Sync for FrameAllocOptions
impl Unpin for FrameAllocOptions
impl UnsafeUnpin for FrameAllocOptions
impl UnwindSafe for FrameAllocOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more