Skip to content

Commit

Permalink
mm/alloc: add GlobalBox implementation
Browse files Browse the repository at this point in the history
Add a new type, GlobalBox, which wraps around the TryBox type but uses
the global SvsmAllocator transparently. The new type implements
AsRef<TryBox> and Into<TryBox>, so regular TryBox methods can also be
used on the new type.

Signed-off-by: Carlos López <[email protected]>
  • Loading branch information
00xc committed Jan 24, 2024
1 parent c94b5ff commit 425644d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/mm/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ unsafe impl Allocator for SvsmAllocator {

#[cfg_attr(any(target_os = "none"), global_allocator)]
#[cfg_attr(not(target_os = "none"), allow(dead_code))]
static ALLOCATOR: SvsmAllocator = SvsmAllocator::new();
pub(super) static ALLOCATOR: SvsmAllocator = SvsmAllocator::new();

pub fn root_mem_init(pstart: PhysAddr, vstart: VirtAddr, page_count: usize) {
{
Expand Down
88 changes: 88 additions & 0 deletions src/mm/boxed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use super::alloc::{SvsmAllocator, ALLOCATOR};
use crate::alloc::boxed::TryBox;
use crate::alloc::TryAllocError;
use crate::error::SvsmError;
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};

impl From<TryAllocError> for SvsmError {
fn from(err: TryAllocError) -> Self {
SvsmError::TryAlloc(err)
}
}

/// A [`TryBox`] wrapper which uses the global memory allocator.
#[derive(Debug)]
pub struct GlobalBox<T>(TryBox<T, &'static SvsmAllocator>);

impl<T> GlobalBox<T> {
pub fn try_new(val: T) -> Result<Self, SvsmError> {
let inner = TryBox::try_new_in(val, &ALLOCATOR)?;
Ok(Self(inner))
}

pub fn try_new_uninit() -> Result<GlobalBox<MaybeUninit<T>>, SvsmError> {
let inner = TryBox::try_new_uninit_in(&ALLOCATOR)?;
Ok(GlobalBox(inner))
}

pub fn try_new_zeroed() -> Result<GlobalBox<MaybeUninit<T>>, SvsmError> {
let inner = TryBox::try_new_zeroed_in(&ALLOCATOR)?;
Ok(GlobalBox(inner))
}

pub fn into_inner(self) -> T {
TryBox::into_inner(self.0)
}

/// # Safety
///
/// See the safety requirements for [`TryBox::from_raw_in()`].
#[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self {
Self(TryBox::from_raw_in(raw, &ALLOCATOR))
}
}

impl<T> From<TryBox<T, &'static SvsmAllocator>> for GlobalBox<T> {
fn from(boxed: TryBox<T, &'static SvsmAllocator>) -> Self {
Self(boxed)
}
}

impl<T> From<GlobalBox<T>> for TryBox<T, &'static SvsmAllocator> {
fn from(boxed: GlobalBox<T>) -> Self {
let ptr = TryBox::into_raw(boxed.0);
// SAFETY: if this GlobalBox was constructed correctly then the inner
// pointer is guaranteed to belong to the global allocator. This
// function also consumes the GlobalBox, so the inner pointer will
// not be used twice.
unsafe { TryBox::from_raw_in(ptr, &ALLOCATOR) }
}
}

impl<T> AsRef<TryBox<T, &'static SvsmAllocator>> for GlobalBox<T> {
fn as_ref(&self) -> &TryBox<T, &'static SvsmAllocator> {
&self.0
}
}

impl<T> AsMut<TryBox<T, &'static SvsmAllocator>> for GlobalBox<T> {
fn as_mut(&mut self) -> &mut TryBox<T, &'static SvsmAllocator> {
&mut self.0
}
}

impl<T> Deref for GlobalBox<T> {
type Target = T;

fn deref(&self) -> &T {
TryBox::deref(self.as_ref())
}
}

impl<T> DerefMut for GlobalBox<T> {
fn deref_mut(&mut self) -> &mut T {
TryBox::deref_mut(self.as_mut())
}
}
2 changes: 2 additions & 0 deletions src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

pub mod address_space;
pub mod alloc;
mod boxed;
pub mod guestmem;
pub mod memory;
pub mod page_visibility;
Expand All @@ -17,6 +18,7 @@ pub mod virtualrange;
pub mod vm;

pub use address_space::*;
pub use boxed::GlobalBox;
pub use guestmem::GuestPtr;
pub use memory::{valid_phys_address, writable_phys_addr};
pub use ptguards::*;
Expand Down

0 comments on commit 425644d

Please sign in to comment.