Skip to content

Commit

Permalink
Reserve space at the base of the kernel area for IGVM info such as the
Browse files Browse the repository at this point in the history
initial VMSA

Signed-off-by: Jon Lange <jlange@microsoft.com>
  • Loading branch information
msft-jlange committed Dec 10, 2023
1 parent 89cfa27 commit d5d232c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 7 deletions.
6 changes: 5 additions & 1 deletion igvm_params/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ pub struct IgvmParamBlock {
/// to launch guest firmware once kernel initialization is complete.
pub launch_fw: u8,

_reserved: [u8; 7],
_reserved: [u8; 3],

/// The amount of space that must be reserved at the base of the kernel
/// memory region (e.g. for VMSA contents).
pub kernel_reserved_size: u32,

/// The number of bytes in the kernel memory region.
pub kernel_size: u32,
Expand Down
7 changes: 7 additions & 0 deletions src/igvm_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ impl IgvmParams<'_> {
Ok(MemoryRegion::<PhysAddr>::new(kernel_base, kernel_size))
}

pub fn reserved_kernel_area_size(&self) -> usize {
self.igvm_param_block
.kernel_reserved_size
.try_into()
.unwrap()
}

pub fn page_state_change_required(&self) -> bool {
self.igvm_param_page.default_shared_pages != 0
}
Expand Down
3 changes: 3 additions & 0 deletions src/stage2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ pub extern "C" fn stage2_main(launch_info: &Stage1LaunchInfo) {
// IGVM parameters. Otherwise, it will be the base of the kernel
// region.
let mut loaded_kernel_phys_end = kernel_region_phys_start;
if let SvsmConfig::IgvmConfig(ref igvm_params) = config {
loaded_kernel_phys_end = loaded_kernel_phys_end + igvm_params.reserved_kernel_area_size();
}

// Map, validate and populate the SVSM kernel ELF's PT_LOAD segments. The
// segments' virtual address range might not necessarily be contiguous,
Expand Down
30 changes: 24 additions & 6 deletions src/svsm_paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,35 @@ use crate::sev::ghcb::PageStateChangeOp;
use crate::sev::{pvalidate, PvalidateOp};
use crate::types::{PageSize, PAGE_SIZE};

struct IgvmParamInfo<'a> {
virt_addr: VirtAddr,
igvm_params: Option<IgvmParams<'a>>,
}

pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64File) {
let vaddr = mm::alloc::allocate_zeroed_page().expect("Failed to allocate root page-table");
let mut pgtable = PageTableRef::new(unsafe { &mut *vaddr.as_mut_ptr::<PageTable>() });
let igvm_param_info = if launch_info.igvm_params_virt_addr != 0 {
let addr = VirtAddr::from(launch_info.igvm_params_virt_addr);
IgvmParamInfo {
virt_addr: addr,
igvm_params: Some(IgvmParams::new(addr)),
}
} else {
IgvmParamInfo {
virt_addr: VirtAddr::null(),
igvm_params: None,
}
};

// Install mappings for the kernel's ELF segments each.
// The memory backing the kernel ELF segments gets allocated back to back
// from the physical memory region by the Stage2 loader.
let mut phys = PhysAddr::from(launch_info.kernel_region_phys_start);
if let Some(ref igvm_params) = igvm_param_info.igvm_params {
phys = phys + igvm_params.reserved_kernel_area_size();
}

for segment in kernel_elf.image_load_segment_iter(launch_info.kernel_region_virt_start) {
let vaddr_start = VirtAddr::from(segment.vaddr_range.vaddr_begin);
let vaddr_end = VirtAddr::from(segment.vaddr_range.vaddr_end);
Expand All @@ -47,14 +68,11 @@ pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64Fi
}

// Map the IGVM parameters if present.
if launch_info.igvm_params_virt_addr != 0 {
let igvm_params_virt_addr = VirtAddr::from(launch_info.igvm_params_virt_addr);
let igvm_params = IgvmParams::new(igvm_params_virt_addr);

if let Some(ref igvm_params) = igvm_param_info.igvm_params {
pgtable
.map_region(
igvm_params_virt_addr,
igvm_params_virt_addr + igvm_params.size(),
igvm_param_info.virt_addr,
igvm_param_info.virt_addr + igvm_params.size(),
PhysAddr::from(launch_info.igvm_params_phys_addr),
PTEntryFlags::data(),
)
Expand Down

0 comments on commit d5d232c

Please sign in to comment.