From bfab43e252d31bff9cadc5fb10a772fb397e902e Mon Sep 17 00:00:00 2001 From: Ruben Hakobyan Date: Fri, 1 May 2026 09:25:24 -0700 Subject: [PATCH] vmm: Parse guest policy from IGVM initialization headers Extract the SNP guest policy from IGVM initialization headers when available, falling back to the default policy. This matches QEMU's behaviour where only a non-zero IGVM policy overrides the default. Signed-off-by: Ruben Hakobyan --- vmm/src/igvm/igvm_loader.rs | 16 ++++++++++++++++ vmm/src/vm.rs | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index 760c9c9b0..f24fe9c28 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -8,6 +8,8 @@ use std::mem::size_of; use std::sync::{Arc, Mutex}; use hypervisor::HypervisorType; +#[cfg(feature = "sev_snp")] +use igvm::IgvmInitializationHeader; use igvm::snp_defs::SevVmsa; use igvm::{IgvmDirectiveHeader, IgvmFile, IgvmPlatformHeader}; #[cfg(feature = "sev_snp")] @@ -229,6 +231,20 @@ fn import_parameter( Ok(()) } +/// +/// Extract guest policy from the IGVM initialization headers. +#[cfg(feature = "sev_snp")] +pub fn extract_guest_policy(igvm_file: &IgvmFile) -> Option { + for header in igvm_file.initializations() { + if let IgvmInitializationHeader::GuestPolicy { policy, .. } = header + && *policy != 0 + { + return Some(igvm_defs::SnpPolicy::from_bits(*policy)); + } + } + None +} + /// /// Extract sev_features from the boot CPU (vp_index 0) VMSA. /// diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index df23e37e1..bd6c9bee4 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1012,8 +1012,16 @@ impl Vm { .create_boot_vcpus(snapshot_from_id(snapshot, CPU_MANAGER_SNAPSHOT_ID)) .map_err(Error::CpuManager)?; - // Initialize SEV-SNP - transitions guest into secure state - vm.sev_snp_init(Self::get_default_sev_snp_guest_policy()) + // Extract guest policy from IGVM if available, otherwise use default. + #[cfg(feature = "igvm")] + let guest_policy = igvm_file + .as_ref() + .and_then(igvm_loader::extract_guest_policy) + .unwrap_or_else(Self::get_default_sev_snp_guest_policy); + #[cfg(not(feature = "igvm"))] + let guest_policy = Self::get_default_sev_snp_guest_policy(); + + vm.sev_snp_init(guest_policy) .map_err(Error::InitializeSevSnpVm)?; // Load payload for SEV-SNP (IGVM parser needs cpu_manager for cpuid)