Skip to content

Commit

Permalink
Parse the IGVM memory map
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Lange <jlange@microsoft.com>
  • Loading branch information
msft-jlange committed Dec 4, 2023
1 parent 9080fab commit b0bbe8d
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 4 deletions.
88 changes: 85 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ log = { version = "0.4.17", features = ["max_level_info", "release_max_level_inf
packit = { git = "https://github.com/coconut-svsm/packit", version = "0.1.0" }
aes-gcm = { version = "0.10.3", default-features = false, features = ["aes", "alloc"] }
igvm_params = { path = "igvm_params" }
igvm_defs = { version = "0.1.0" }

[target."x86_64-unknown-none".dev-dependencies]
test = { version = "0.1.0", path = "test" }
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<'a> SvsmConfig<'a> {
pub fn get_memory_regions(&self) -> Result<Vec<MemoryRegion<PhysAddr>>, SvsmError> {
match self {
SvsmConfig::FirmwareConfig(fw_cfg) => fw_cfg.get_memory_regions(),
&SvsmConfig::IgvmConfig(_) => todo!(),
SvsmConfig::IgvmConfig(igvm_params) => igvm_params.get_memory_regions(),
}
}
pub fn load_cpu_info(&self) -> Result<Vec<ACPICPUInfo>, SvsmError> {
Expand Down
58 changes: 58 additions & 0 deletions src/igvm_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,46 @@
//
// Author: Jon Lange (jlange@microsoft.com)

extern crate alloc;

use crate::address::{PhysAddr, VirtAddr};
use crate::error::SvsmError;
use crate::error::SvsmError::Firmware;
use crate::mm::PAGE_SIZE;
use crate::utils::MemoryRegion;
use alloc::vec::Vec;

use core::mem::size_of;
use igvm_defs::{MemoryMapEntryType, IGVM_VHS_MEMORY_MAP_ENTRY};
use igvm_params::{IgvmParamBlock, IgvmParamPage};

const IGVM_MEMORY_ENTRIES_PER_PAGE: usize = PAGE_SIZE / size_of::<IGVM_VHS_MEMORY_MAP_ENTRY>();

#[derive(Clone, Debug)]
#[repr(C, align(64))]
pub struct IgvmMemoryMap {
memory_map: [IGVM_VHS_MEMORY_MAP_ENTRY; IGVM_MEMORY_ENTRIES_PER_PAGE],
}

#[derive(Clone, Debug)]
pub struct IgvmParams<'a> {
igvm_param_block: &'a IgvmParamBlock,
igvm_param_page: &'a IgvmParamPage,
igvm_memory_map: &'a IgvmMemoryMap,
}

impl IgvmParams<'_> {
pub fn new(addr: VirtAddr) -> Self {
let param_block = unsafe { &*addr.as_ptr::<IgvmParamBlock>() };
let param_page_address = addr + param_block.param_page_offset.try_into().unwrap();
let param_page = unsafe { &*param_page_address.as_ptr::<IgvmParamPage>() };
let memory_map_address = addr + param_block.memory_map_offset.try_into().unwrap();
let memory_map = unsafe { &*memory_map_address.as_ptr::<IgvmMemoryMap>() };

Self {
igvm_param_block: param_block,
igvm_param_page: param_page,
igvm_memory_map: memory_map,
}
}

Expand Down Expand Up @@ -54,4 +73,43 @@ impl IgvmParams<'_> {
pub fn get_secrets_page_address(&self) -> u64 {
self.igvm_param_block.secrets_page as u64
}

pub fn get_memory_regions(&self) -> Result<Vec<MemoryRegion<PhysAddr>>, SvsmError> {
// Count the number of memory entries present. They must be
// non-overlapping and strictly increasing.
let mut number_of_entries = 0;
let mut next_page_number = 0;
for i in 0..IGVM_MEMORY_ENTRIES_PER_PAGE {
let entry = &self.igvm_memory_map.memory_map[i];
if entry.number_of_pages == 0 {
break;
}
if entry.starting_gpa_page_number < next_page_number {
return Err(Firmware);
}
let next_supplied_page_number = entry.starting_gpa_page_number + entry.number_of_pages;
if next_supplied_page_number < next_page_number {
return Err(Firmware);
}
next_page_number = next_supplied_page_number;
number_of_entries += 1;
}

// Now loop over the supplied entires and add a region for each
// known type.
let mut regions: Vec<MemoryRegion<PhysAddr>> = Vec::new();
for i in 0..number_of_entries {
let entry = &self.igvm_memory_map.memory_map[i];
if entry.entry_type == MemoryMapEntryType::MEMORY {
let starting_page: usize = entry.starting_gpa_page_number.try_into().unwrap();
let number_of_pages: usize = entry.number_of_pages.try_into().unwrap();
regions.push(MemoryRegion::new(
PhysAddr::new(starting_page * PAGE_SIZE),
number_of_pages * PAGE_SIZE,
));
}
}

Ok(regions)
}
}

0 comments on commit b0bbe8d

Please sign in to comment.