Skip to content

Commit

Permalink
svsm: Invalidate IGVM parameter area after stage2
Browse files Browse the repository at this point in the history
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 <roy.hopkins@suse.com>
  • Loading branch information
roy-hopkins committed Jan 10, 2024
1 parent 571db22 commit ec7e283
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
2 changes: 2 additions & 0 deletions bootlib/src/kernel_launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion src/stage2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down
20 changes: 15 additions & 5 deletions src/svsm_paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand Down

0 comments on commit ec7e283

Please sign in to comment.