From ec7e283afcdc6f625419c5d4a4feafee4dea848b Mon Sep 17 00:00:00 2001 From: Roy Hopkins Date: Wed, 10 Jan 2024 14:55:46 +0000 Subject: [PATCH] svsm: Invalidate IGVM parameter area after stage2 When booting using an IGVM configuration, some of the prevalidated pages are populated outside the first 640K of low memory. These need to be invalidated prior to booting the firmware. This patch passes the location and size of the IGVM parameter block which consitutes all of the prevalidated page outside the 640K range from stage2 to the kernel and invalidates them at the correct time. Signed-off-by: Roy Hopkins --- bootlib/src/kernel_launch.rs | 2 ++ src/stage2.rs | 5 ++++- src/svsm_paging.rs | 20 +++++++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/bootlib/src/kernel_launch.rs b/bootlib/src/kernel_launch.rs index 06150b8a4..abeb64a0c 100644 --- a/bootlib/src/kernel_launch.rs +++ b/bootlib/src/kernel_launch.rs @@ -20,6 +20,8 @@ pub struct KernelLaunchInfo { pub kernel_fs_end: u64, pub cpuid_page: u64, pub secrets_page: u64, + pub stage2_igvm_params_phys_addr: u64, + pub stage2_igvm_params_size: u64, pub igvm_params_phys_addr: u64, pub igvm_params_virt_addr: u64, pub debug_serial_port: u16, diff --git a/src/stage2.rs b/src/stage2.rs index a74b8a447..a0c32357c 100755 --- a/src/stage2.rs +++ b/src/stage2.rs @@ -285,10 +285,11 @@ pub extern "C" fn stage2_main(launch_info: &Stage1LaunchInfo) { // after the kernel. let mut igvm_params_virt_address = VirtAddr::null(); let mut igvm_params_phys_address = PhysAddr::null(); + let mut igvm_params_size = 0; if let SvsmConfig::IgvmConfig(ref igvm_params) = config { igvm_params_virt_address = loaded_kernel_virt_end; igvm_params_phys_address = loaded_kernel_phys_end; - let igvm_params_size = igvm_params.size(); + igvm_params_size = igvm_params.size(); map_and_validate( &config, @@ -337,6 +338,8 @@ pub extern "C" fn stage2_main(launch_info: &Stage1LaunchInfo) { kernel_fs_end: u64::from(launch_info.kernel_fs_end), cpuid_page: config.get_cpuid_page_address(), secrets_page: config.get_secrets_page_address(), + stage2_igvm_params_phys_addr: u64::from(launch_info.igvm_params), + stage2_igvm_params_size: igvm_params_size as u64, igvm_params_phys_addr: u64::from(igvm_params_phys_address), igvm_params_virt_addr: u64::from(igvm_params_virt_address), debug_serial_port: config.debug_serial_port(), diff --git a/src/svsm_paging.rs b/src/svsm_paging.rs index bf7083cca..f470bd8bf 100644 --- a/src/svsm_paging.rs +++ b/src/svsm_paging.rs @@ -150,11 +150,21 @@ pub fn invalidate_early_boot_memory( invalidate_boot_memory_region(config, kernel_elf_region)?; let kernel_fs_size = launch_info.kernel_fs_end - launch_info.kernel_fs_start; - let kernel_fs_region = MemoryRegion::new( - PhysAddr::new(launch_info.kernel_fs_start.try_into().unwrap()), - kernel_fs_size.try_into().unwrap(), - ); - invalidate_boot_memory_region(config, kernel_fs_region)?; + if kernel_fs_size > 0 { + let kernel_fs_region = MemoryRegion::new( + PhysAddr::new(launch_info.kernel_fs_start.try_into().unwrap()), + kernel_fs_size.try_into().unwrap(), + ); + invalidate_boot_memory_region(config, kernel_fs_region)?; + } + + if launch_info.stage2_igvm_params_size > 0 { + let igvm_params_region = MemoryRegion::new( + PhysAddr::new(launch_info.stage2_igvm_params_phys_addr.try_into().unwrap()), + launch_info.stage2_igvm_params_size as usize, + ); + invalidate_boot_memory_region(config, igvm_params_region)?; + } } Ok(())