vmm: parse IGVM file early and thread it through VM setup

Move IGVM file parsing from load_igvm() into a dedicated parse_igvm()
helper in igvm/mod.rs, and parse the file upfront in Vm::new() so the
resulting IgvmFile struct is available throughout VM initialization.

This is a prerequisite for extracting VMSA SEV features from the parsed
IGVM before issuing KVM_SEV_INIT2, which needs sev_features.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
This commit is contained in:
Ruben Hakobyan
2026-04-09 16:58:58 -07:00
committed by Rob Bradford
parent 4f1119a788
commit 425609a8b5
4 changed files with 52 additions and 19 deletions
+4 -10
View File
@@ -4,12 +4,11 @@
//
use std::collections::HashMap;
use std::ffi::CString;
use std::io::{Read, Seek, SeekFrom};
use std::mem::size_of;
use std::sync::{Arc, Mutex};
use igvm::snp_defs::SevVmsa;
use igvm::{IgvmDirectiveHeader, IgvmFile, IgvmPlatformHeader, IsolationType};
use igvm::{IgvmDirectiveHeader, IgvmFile, IgvmPlatformHeader};
#[cfg(feature = "sev_snp")]
use igvm_defs::{IGVM_VHS_MEMORY_MAP_ENTRY, MemoryMapEntryType};
use igvm_defs::{
@@ -51,6 +50,8 @@ pub enum Error {
FailedToDecodeHostData(#[source] hex::FromHexError),
#[error("Error allocating address space")]
MemoryManager(MemoryManagerError),
#[error("IGVM file not provided")]
MissingIgvm,
}
#[allow(dead_code)]
@@ -135,7 +136,7 @@ fn import_parameter(
/// any isolation.
#[allow(clippy::needless_pass_by_value)]
pub fn load_igvm(
mut file: &std::fs::File,
igvm_file: IgvmFile,
memory_manager: Arc<Mutex<MemoryManager>>,
cpu_manager: Arc<Mutex<CpuManager>>,
cmdline: &str,
@@ -143,7 +144,6 @@ pub fn load_igvm(
) -> Result<Box<IgvmLoadedInfo>, Error> {
let mut loaded_info: Box<IgvmLoadedInfo> = Box::default();
let command_line = CString::new(cmdline).map_err(Error::InvalidCommandLine)?;
let mut file_contents = Vec::new();
let memory = memory_manager.lock().as_ref().unwrap().guest_memory();
let mut gpas: Vec<GpaPages> = Vec::new();
let proc_count = cpu_manager.lock().unwrap().vcpus().len() as u32;
@@ -156,12 +156,6 @@ pub fn load_igvm(
.map_err(Error::FailedToDecodeHostData)?;
}
file.seek(SeekFrom::Start(0)).map_err(Error::Igvm)?;
file.read_to_end(&mut file_contents).map_err(Error::Igvm)?;
let igvm_file = IgvmFile::new_from_binary(&file_contents, Some(IsolationType::Snp))
.map_err(Error::InvalidIgvmFile)?;
let mask = match &igvm_file.platforms()[0] {
IgvmPlatformHeader::SupportedPlatform(info) => {
debug_assert!(info.platform_type == IgvmPlatformType::SEV_SNP);
+9
View File
@@ -27,10 +27,19 @@
pub mod igvm_loader;
mod loader;
use std::path::Path;
use igvm::snp_defs::SevVmsa;
use igvm::{IgvmFile, IsolationType};
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
use zerocopy::FromZeros;
pub fn parse_igvm(igvm_path: &Path) -> Result<IgvmFile, igvm_loader::Error> {
let file_contents = std::fs::read(igvm_path).map_err(igvm_loader::Error::Igvm)?;
IgvmFile::new_from_binary(&file_contents, Some(IsolationType::Snp))
.map_err(igvm_loader::Error::InvalidIgvmFile)
}
#[derive(Debug, Clone)]
pub struct IgvmLoadedInfo {
pub gpas: Vec<u64>,