From 9080fab97e6a7af3257af0c646bd52f5c7f66176 Mon Sep 17 00:00:00 2001 From: Jon Lange Date: Tue, 5 Dec 2023 10:30:55 -0800 Subject: [PATCH] Map the IGVM parameters into the page tables constructed by the kernel Signed-off-by: Jon Lange --- src/kernel_launch.rs | 4 +++- src/stage2.rs | 4 +++- src/svsm.rs | 4 ++-- src/svsm_paging.rs | 20 ++++++++++++++++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/kernel_launch.rs b/src/kernel_launch.rs index f51d46c01f..2018484637 100644 --- a/src/kernel_launch.rs +++ b/src/kernel_launch.rs @@ -23,7 +23,9 @@ pub struct KernelLaunchInfo { pub kernel_fs_end: u64, pub cpuid_page: u64, pub secrets_page: u64, - pub igvm_params: u64, + pub igvm_params_phys_addr: u64, + pub igvm_params_virt_addr: u64, + pub igvm_params_size: u64, } impl KernelLaunchInfo { diff --git a/src/stage2.rs b/src/stage2.rs index f2203f96ca..d34a74c0ec 100755 --- a/src/stage2.rs +++ b/src/stage2.rs @@ -331,7 +331,9 @@ 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(), - igvm_params: u64::from(igvm_params_virt_address), + igvm_params_phys_addr: launch_info.igvm_params as u64, + igvm_params_virt_addr: u64::from(igvm_params_virt_address), + igvm_params_size: igvm_params_size as u64, }; let mem_info = memory_info(); diff --git a/src/svsm.rs b/src/svsm.rs index f8608e506e..483b97cc1f 100755 --- a/src/svsm.rs +++ b/src/svsm.rs @@ -425,8 +425,8 @@ pub extern "C" fn svsm_main() { //debug_break(); let launch_info = &*LAUNCH_INFO; - let config = if launch_info.igvm_params != 0 { - let igvm_params = IgvmParams::new(VirtAddr::from(launch_info.igvm_params)); + let config = if launch_info.igvm_params_virt_addr != 0 { + let igvm_params = IgvmParams::new(VirtAddr::from(launch_info.igvm_params_virt_addr)); SvsmConfig::IgvmConfig(igvm_params) } else { SvsmConfig::FirmwareConfig(FwCfg::new(&CONSOLE_IO)) diff --git a/src/svsm_paging.rs b/src/svsm_paging.rs index 4c49a2d612..3510bd0a36 100644 --- a/src/svsm_paging.rs +++ b/src/svsm_paging.rs @@ -23,8 +23,10 @@ pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64Fi // 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); + // from the physical memory region by the Stage2 loader, following + // the IGVM parameters (if any). + let igvm_params_size: usize = launch_info.igvm_params_size.try_into().unwrap(); + let mut phys = PhysAddr::from(launch_info.kernel_region_phys_start) + igvm_params_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); @@ -45,6 +47,20 @@ pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64Fi phys = phys + segment_len; } + // 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); + + pgtable + .map_region( + igvm_params_virt_addr, + igvm_params_virt_addr + igvm_params_size, + PhysAddr::from(launch_info.igvm_params_phys_addr), + PTEntryFlags::data(), + ) + .expect("Failed to map IGVM parameters"); + } + // Map subsequent heap area. pgtable .map_region(