diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index 09f076af0..8d6b9adb7 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -53,6 +53,8 @@ pub enum Error { ImportIsolatedPages(#[source] hypervisor::HypervisorVmError), #[error("Error completing importing isolated pages: {0}")] CompleteIsolatedImport(#[source] hypervisor::HypervisorVmError), + #[error("Error decoding host data: {0}")] + FailedToDecodeHostData(#[source] hex::FromHexError), } #[allow(dead_code)] @@ -141,6 +143,7 @@ pub fn load_igvm( memory_manager: Arc>, cpu_manager: Arc>, cmdline: &str, + #[cfg(feature = "sev_snp")] host_data: &Option, ) -> Result, Error> { let mut loaded_info: Box = Box::default(); let command_line = CString::new(cmdline).map_err(Error::InvalidCommandLine)?; @@ -149,6 +152,14 @@ pub fn load_igvm( let mut gpas: Vec = Vec::new(); let proc_count = cpu_manager.lock().unwrap().vcpus().len() as u32; + #[cfg(feature = "sev_snp")] + let mut host_data_contents = [0; 32]; + #[cfg(feature = "sev_snp")] + if let Some(host_data_str) = host_data { + hex::decode_to_slice(host_data_str, &mut host_data_contents as &mut [u8]) + .map_err(Error::FailedToDecodeHostData)?; + } + file.seek(SeekFrom::Start(0)).map_err(Error::Igvm)?; file.read_to_end(&mut file_contents).map_err(Error::Igvm)?; @@ -470,12 +481,11 @@ pub fn load_igvm( now = Instant::now(); // Call Complete Isolated Import since we are done importing isolated pages - let host_data: [u8; 32] = [0; 32]; memory_manager .lock() .unwrap() .vm - .complete_isolated_import(loaded_info.snp_id_block, host_data, 1) + .complete_isolated_import(loaded_info.snp_id_block, host_data_contents, 1) .map_err(Error::CompleteIsolatedImport)?; info!( diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 53a6721ca..da8a627e3 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -574,7 +574,13 @@ impl Vm { // per cpuid through cpu_manager. #[cfg(feature = "igvm")] let load_payload_handle = if snapshot.is_none() { - Self::load_payload_async(&memory_manager, &config, &cpu_manager)? + Self::load_payload_async( + &memory_manager, + &config, + &cpu_manager, + #[cfg(feature = "sev_snp")] + sev_snp_enabled, + )? } else { None }; @@ -1006,9 +1012,17 @@ impl Vm { igvm: File, memory_manager: Arc>, cpu_manager: Arc>, + #[cfg(feature = "sev_snp")] host_data: &Option, ) -> Result { - let res = igvm_loader::load_igvm(&igvm, memory_manager, cpu_manager.clone(), "") - .map_err(Error::IgvmLoad)?; + let res = igvm_loader::load_igvm( + &igvm, + memory_manager, + cpu_manager.clone(), + "", + #[cfg(feature = "sev_snp")] + host_data, + ) + .map_err(Error::IgvmLoad)?; cfg_if::cfg_if! { if #[cfg(feature = "sev_snp")] { @@ -1087,12 +1101,20 @@ impl Vm { payload: &PayloadConfig, memory_manager: Arc>, #[cfg(feature = "igvm")] cpu_manager: Arc>, + #[cfg(feature = "sev_snp")] sev_snp_enabled: bool, ) -> Result { trace_scoped!("load_payload"); #[cfg(feature = "igvm")] - if let Some(_igvm_file) = &payload.igvm { - let igvm = File::open(_igvm_file).map_err(Error::IgvmFile)?; - return Self::load_igvm(igvm, memory_manager, cpu_manager); + { + if let Some(_igvm_file) = &payload.igvm { + let igvm = File::open(_igvm_file).map_err(Error::IgvmFile)?; + #[cfg(feature = "sev_snp")] + if sev_snp_enabled { + return Self::load_igvm(igvm, memory_manager, cpu_manager, &payload.host_data); + } + #[cfg(not(feature = "sev_snp"))] + return Self::load_igvm(igvm, memory_manager, cpu_manager); + } } match ( &payload.firmware, @@ -1135,6 +1157,7 @@ impl Vm { memory_manager: &Arc>, config: &Arc>, #[cfg(feature = "igvm")] cpu_manager: &Arc>, + #[cfg(feature = "sev_snp")] sev_snp_enabled: bool, ) -> Result>>> { // Kernel with TDX is loaded in a different manner #[cfg(feature = "tdx")] @@ -1161,6 +1184,8 @@ impl Vm { memory_manager, #[cfg(feature = "igvm")] cpu_manager, + #[cfg(feature = "sev_snp")] + sev_snp_enabled, ) }) .map_err(Error::KernelLoadThreadSpawn)