Skip to content

Commit

Permalink
Move the rest of the operations into the HAL trait.
Browse files Browse the repository at this point in the history
I don't particularly like how `Platform` permeates everyhing now, but
that'll be a fight for a different day.

And some of the base structures in the crate hierarchy indeed need a
cleanup, as the SEV crates are now leaking into TDX. But that will be a
fight for a different day as well.

Bug: 350496083
Change-Id: I85bd2ce572a2ef784093cc30053aa13a82b42fd3
  • Loading branch information
andrisaar committed Aug 12, 2024
1 parent c81f2b9 commit 420c873
Show file tree
Hide file tree
Showing 21 changed files with 540 additions and 432 deletions.
22 changes: 17 additions & 5 deletions stage0/src/acpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ impl Allocate {
Zone::from_repr(self.zone)
}

fn invoke(&self, fwcfg: &mut FwCfg, acpi_digest: &mut Sha256) -> Result<(), &'static str> {
fn invoke<P: crate::Platform>(
&self,
fwcfg: &mut FwCfg<P>,
acpi_digest: &mut Sha256,
) -> Result<(), &'static str> {
let file = fwcfg.find(self.file()).unwrap();
let name = self.file().to_str().map_err(|_| "invalid file name")?;

Expand Down Expand Up @@ -465,7 +469,11 @@ enum Command<'a> {
}

impl Command<'_> {
pub fn invoke(&self, fwcfg: &mut FwCfg, acpi_digest: &mut Sha256) -> Result<(), &'static str> {
pub fn invoke<P: crate::Platform>(
&self,
fwcfg: &mut FwCfg<P>,
acpi_digest: &mut Sha256,
) -> Result<(), &'static str> {
match self {
Command::Allocate(allocate) => allocate.invoke(fwcfg, acpi_digest),
Command::AddPointer(add_pointer) => add_pointer.invoke(),
Expand Down Expand Up @@ -500,7 +508,11 @@ impl RomfileCommand {
}
}

fn invoke(&self, fwcfg: &mut FwCfg, acpi_digest: &mut Sha256) -> Result<(), &'static str> {
fn invoke<P: crate::Platform>(
&self,
fwcfg: &mut FwCfg<P>,
acpi_digest: &mut Sha256,
) -> Result<(), &'static str> {
if self.tag > CommandTag::VMM_SPECIFIC && self.tag().is_none() {
log::warn!("ignoring proprietary ACPI linker command with tag {:#x}", self.tag);
return Ok(());
Expand All @@ -520,8 +532,8 @@ impl RomfileCommand {
/// Populates the ACPI tables per linking instructions in `etc/table-loader`.
///
/// Returns the address of the RSDP table.
pub fn build_acpi_tables(
fwcfg: &mut FwCfg,
pub fn build_acpi_tables<P: crate::Platform>(
fwcfg: &mut FwCfg<P>,
acpi_digest: &mut Sha256,
) -> Result<&'static Rsdp, &'static str> {
let file =
Expand Down
38 changes: 22 additions & 16 deletions stage0/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use alloc::boxed::Box;
use core::{
alloc::{AllocError, Allocator, Layout},
marker::PhantomData,
mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr::NonNull,
Expand All @@ -30,7 +31,10 @@ use x86_64::{
VirtAddr,
};

use crate::paging::{share_page, unshare_page};
use crate::{
paging::{share_page, unshare_page},
Platform,
};

struct Inner<const N: usize> {
index: AtomicUsize,
Expand Down Expand Up @@ -108,25 +112,26 @@ unsafe impl<const N: usize> Allocator for BumpAllocator<N> {
/// they could well fit on one page, currently that'd use 8K of memory.
/// That, however, is an implementation detail, and may change in the future.
#[repr(transparent)]
struct SharedAllocator<A: Allocator> {
struct SharedAllocator<A: Allocator, P: Platform> {
inner: A,
_phantom: PhantomData<P>,
}

impl<A: Allocator> SharedAllocator<A> {
impl<A: Allocator, P: Platform> SharedAllocator<A, P> {
fn new(allocator: A) -> Self {
Self { inner: allocator }
Self { inner: allocator, _phantom: PhantomData }
}
}

unsafe impl<A: Allocator> Allocator for SharedAllocator<A> {
unsafe impl<A: Allocator, P: Platform> Allocator for SharedAllocator<A, P> {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
let layout =
layout.align_to(Size4KiB::SIZE as usize).map_err(|_| AllocError)?.pad_to_align();
let allocation = self.inner.allocate(layout)?;
for offset in (0..allocation.len()).step_by(Size4KiB::SIZE as usize) {
// Safety: the allocation has succeeded and the offset won't exceed the size of
// the allocation.
share_page(Page::containing_address(VirtAddr::from_ptr(unsafe {
share_page::<P>(Page::containing_address(VirtAddr::from_ptr(unsafe {
allocation.as_non_null_ptr().as_ptr().add(offset)
})))
}
Expand All @@ -142,7 +147,7 @@ unsafe impl<A: Allocator> Allocator for SharedAllocator<A> {
for offset in (0..layout.size()).step_by(Size4KiB::SIZE as usize) {
// Safety: the allocation has succeeded and the offset won't exceed the size of
// the allocation.
unshare_page(Page::containing_address(VirtAddr::from_ptr(unsafe {
unshare_page::<P>(Page::containing_address(VirtAddr::from_ptr(unsafe {
ptr.as_ptr().add(offset)
})))
}
Expand All @@ -151,11 +156,11 @@ unsafe impl<A: Allocator> Allocator for SharedAllocator<A> {
}

/// Stores a data structure on a shared page.
pub struct Shared<T: 'static, A: Allocator> {
inner: Box<T, SharedAllocator<A>>,
pub struct Shared<T: 'static, A: Allocator, P: Platform> {
inner: Box<T, SharedAllocator<A, P>>,
}

impl<T, A: Allocator> Shared<T, A> {
impl<T, A: Allocator, P: Platform> Shared<T, A, P> {
pub fn new_in(t: T, alloc: A) -> Self
where
A: 'static,
Expand All @@ -172,40 +177,41 @@ impl<T, A: Allocator> Shared<T, A> {
/// was used for the original allocation of the `Shared`.
///
/// Again, see `Box::from_raw_in` for more details.
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Shared<T, A> {
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Shared<T, A, P> {
Self { inner: Box::from_raw_in(raw, SharedAllocator::new(alloc)) }
}

/// See `Box::leak` for documentation.
pub fn leak<'a>(s: Shared<T, A>) -> &'a mut T
pub fn leak<'a>(s: Shared<T, A, P>) -> &'a mut T
where
A: 'a,
P: 'a,
{
Box::leak(s.inner)
}
}

impl<T, A: Allocator> Deref for Shared<T, A> {
impl<T, A: Allocator, P: Platform> Deref for Shared<T, A, P> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.inner
}
}

impl<T, A: Allocator> DerefMut for Shared<T, A> {
impl<T, A: Allocator, P: Platform> DerefMut for Shared<T, A, P> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}

impl<T, A: Allocator> AsRef<T> for Shared<T, A> {
impl<T, A: Allocator, P: Platform> AsRef<T> for Shared<T, A, P> {
fn as_ref(&self) -> &T {
&self.inner
}
}

impl<T, A: Allocator> AsMut<T> for Shared<T, A> {
impl<T, A: Allocator, P: Platform> AsMut<T> for Shared<T, A, P> {
fn as_mut(&mut self) -> &mut T {
&mut self.inner
}
Expand Down
Loading

0 comments on commit 420c873

Please sign in to comment.