From 425644d32c5c31e474b417b746f39782431083e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20L=C3=B3pez?= Date: Wed, 24 Jan 2024 12:07:33 +0100 Subject: [PATCH] mm/alloc: add GlobalBox implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new type, GlobalBox, which wraps around the TryBox type but uses the global SvsmAllocator transparently. The new type implements AsRef and Into, so regular TryBox methods can also be used on the new type. Signed-off-by: Carlos López --- src/mm/alloc.rs | 2 +- src/mm/boxed.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ src/mm/mod.rs | 2 ++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/mm/boxed.rs diff --git a/src/mm/alloc.rs b/src/mm/alloc.rs index ae3dc10063..af7b2a0526 100644 --- a/src/mm/alloc.rs +++ b/src/mm/alloc.rs @@ -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) { { diff --git a/src/mm/boxed.rs b/src/mm/boxed.rs new file mode 100644 index 0000000000..4e8cbf3f5f --- /dev/null +++ b/src/mm/boxed.rs @@ -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 for SvsmError { + fn from(err: TryAllocError) -> Self { + SvsmError::TryAlloc(err) + } +} + +/// A [`TryBox`] wrapper which uses the global memory allocator. +#[derive(Debug)] +pub struct GlobalBox(TryBox); + +impl GlobalBox { + pub fn try_new(val: T) -> Result { + let inner = TryBox::try_new_in(val, &ALLOCATOR)?; + Ok(Self(inner)) + } + + pub fn try_new_uninit() -> Result>, SvsmError> { + let inner = TryBox::try_new_uninit_in(&ALLOCATOR)?; + Ok(GlobalBox(inner)) + } + + pub fn try_new_zeroed() -> Result>, 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 From> for GlobalBox { + fn from(boxed: TryBox) -> Self { + Self(boxed) + } +} + +impl From> for TryBox { + fn from(boxed: GlobalBox) -> 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 AsRef> for GlobalBox { + fn as_ref(&self) -> &TryBox { + &self.0 + } +} + +impl AsMut> for GlobalBox { + fn as_mut(&mut self) -> &mut TryBox { + &mut self.0 + } +} + +impl Deref for GlobalBox { + type Target = T; + + fn deref(&self) -> &T { + TryBox::deref(self.as_ref()) + } +} + +impl DerefMut for GlobalBox { + fn deref_mut(&mut self) -> &mut T { + TryBox::deref_mut(self.as_mut()) + } +} diff --git a/src/mm/mod.rs b/src/mm/mod.rs index 9721c532d9..fd2ee6c164 100644 --- a/src/mm/mod.rs +++ b/src/mm/mod.rs @@ -6,6 +6,7 @@ pub mod address_space; pub mod alloc; +mod boxed; pub mod guestmem; pub mod memory; pub mod page_visibility; @@ -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::*;