From d71ef33b83ed69db9eeceb83f57a514f006f297c Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Mon, 6 Jul 2026 13:43:44 -0700 Subject: [PATCH] vmm: decouple igvm loader from mshv IGVM no longer implies the MSHV backend at the feature layer. Gate the loader paths that use MSHV page types, MSHV SNP launch defaults, or MSHV-specific CPUID page rewriting on the MSHV feature. This preserves existing MSHV behavior while letting KVM SEV-SNP use the shared IGVM loader without compiling the full MSHV backend. Assisted-by: Copilot:GPT-5.5 Signed-off-by: Wei Liu --- vmm/src/igvm/igvm_loader.rs | 60 +++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index 31d965096..a6d9be43d 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -6,7 +6,7 @@ use std::cmp; use std::collections::HashMap; use std::ffi::CString; -#[cfg(feature = "kvm")] +#[cfg(all(feature = "kvm", feature = "sev_snp"))] use std::iter; use std::sync::{Arc, Mutex}; use std::{ffi, io}; @@ -723,25 +723,24 @@ pub fn load_igvm( ParameterAreaState::Inserted => panic!("igvmfile is invalid, multiple insert"), } *area = ParameterAreaState::Inserted; - match hypervisor_type { - #[cfg(feature = "kvm")] - HypervisorType::Kvm => { - for page_index in 0..page_count { - gpas.push(GpaPages { - gpa: *gpa + page_index * HV_PAGE_SIZE, - page_type: page_types.unmeasured, - page_size: page_types.isolated_page_size_4kb, - }); - } - } - _ => { + #[cfg(feature = "kvm")] + if hypervisor_type == HypervisorType::Kvm { + for page_index in 0..page_count { gpas.push(GpaPages { - gpa: *gpa, + gpa: *gpa + page_index * HV_PAGE_SIZE, page_type: page_types.unmeasured, page_size: page_types.isolated_page_size_4kb, }); } } + #[cfg(feature = "mshv")] + if hypervisor_type == HypervisorType::Mshv { + gpas.push(GpaPages { + gpa: *gpa, + page_type: page_types.unmeasured, + page_size: page_types.isolated_page_size_4kb, + }); + } } IgvmDirectiveHeader::ErrorRange { .. } => { todo!("Error Range not supported") @@ -786,24 +785,28 @@ pub fn load_igvm( let mut now = Instant::now(); - // KVM: preserve original IGVM ordering — the SNP launch digest is order-sensitive. - // MSHV: sort by GPA to group pages by type for fewer hypercalls. - match hypervisor_type { - #[cfg(feature = "kvm")] - HypervisorType::Kvm => {} - _ => gpas.sort_by_key(|a| a.gpa), + #[cfg(feature = "mshv")] + { + // KVM preserves original IGVM ordering because the SNP launch digest + // is order-sensitive. MSHV sorts by GPA for fewer hypercalls. + if hypervisor_type == HypervisorType::Mshv { + gpas.sort_by_key(|a| a.gpa); + } } let gpas_grouped = gpas .iter() .fold(Vec::>::new(), |mut acc, gpa| { + #[cfg(feature = "kvm")] + let same_page_size = hypervisor_type != HypervisorType::Kvm + || acc + .last() + .is_some_and(|last_vec| last_vec[0].page_size == gpa.page_size); + #[cfg(not(feature = "kvm"))] + let same_page_size = true; if let Some(last_vec) = acc.last_mut() && last_vec[0].page_type == gpa.page_type - && match hypervisor_type { - #[cfg(feature = "kvm")] - HypervisorType::Kvm => last_vec[0].page_size == gpa.page_size, - _ => true, - } + && same_page_size { last_vec.push(*gpa); return acc; @@ -891,16 +894,23 @@ pub fn load_igvm( gpas.len() ); + #[cfg(feature = "mshv")] let id_block_enabled = if hypervisor_type == HypervisorType::Mshv { 1 } else { u8::from(loaded_info.has_snp_id_block) }; + #[cfg(not(feature = "mshv"))] + let id_block_enabled = u8::from(loaded_info.has_snp_id_block); + + #[cfg(feature = "mshv")] let auth_key_enabled = if hypervisor_type == HypervisorType::Mshv { 0 } else { loaded_info.snp_id_block.author_key_enabled }; + #[cfg(not(feature = "mshv"))] + let auth_key_enabled = loaded_info.snp_id_block.author_key_enabled; now = Instant::now(); // Call Complete Isolated Import since we are done importing isolated pages