From 28a194c1a932e708b0a598d1e0609b244b190636 Mon Sep 17 00:00:00 2001 From: Adam Dunlap Date: Wed, 8 Jan 2025 10:24:15 -0800 Subject: [PATCH] stage2: Prefer using IGVM memory map to place SVSM kernel If the IGVM memory map contains a PARAVISOR_RESERVED entry, then place the SVSM kernel at that region instead of the region specified in the IgvmParamBlock. If no such entry exists in the memory map, then continue using the IgvmParamBlock. This allows the hypervisor to dynamically resize the SVSM based on the machine shape without changing the IgvmParamBlock and thus the launch measurement. This is necessary because the SVSM uses more memory when there are more vCPUs (and, in the future, guest memory). Signed-off-by: Adam Dunlap --- kernel/src/igvm_params.rs | 13 +++++++++++++ kernel/src/stage2.rs | 2 ++ 2 files changed, 15 insertions(+) diff --git a/kernel/src/igvm_params.rs b/kernel/src/igvm_params.rs index cfbc13de1..cf9ff4c61 100644 --- a/kernel/src/igvm_params.rs +++ b/kernel/src/igvm_params.rs @@ -75,6 +75,19 @@ impl IgvmParams<'_> { } pub fn find_kernel_region(&self) -> Result, SvsmError> { + // First check the memory map if there's a paravisor region to use. + for entry in self.igvm_memory_map.memory_map.iter() { + if entry.entry_type == MemoryMapEntryType::PARAVISOR_RESERVED { + let starting_page: usize = entry.starting_gpa_page_number.try_into().unwrap(); + let number_of_pages: usize = entry.number_of_pages.try_into().unwrap(); + return Ok(MemoryRegion::new( + PhysAddr::new(starting_page * PAGE_SIZE), + number_of_pages * PAGE_SIZE, + )); + } + } + + // Otherwise, use the region specified in the IgvmParamBlock. let kernel_base = PhysAddr::from(self.igvm_param_block.kernel_base); let kernel_size: usize = self.igvm_param_block.kernel_size.try_into().unwrap(); Ok(MemoryRegion::::new(kernel_base, kernel_size)) diff --git a/kernel/src/stage2.rs b/kernel/src/stage2.rs index e78223631..1d669d04e 100755 --- a/kernel/src/stage2.rs +++ b/kernel/src/stage2.rs @@ -363,6 +363,8 @@ pub extern "C" fn stage2_main(launch_info: &Stage2LaunchInfo) { .find_kernel_region() .expect("Failed to find memory region for SVSM kernel"); + log::info!("SVSM memory region: {kernel_region:?}"); + init_valid_bitmap_alloc(kernel_region).expect("Failed to allocate valid-bitmap"); // The physical memory region we've loaded so far