From 6d2d66bcd31aee39d331d2a8098b6344fd41d8f0 Mon Sep 17 00:00:00 2001 From: Ruben Hakobyan Date: Mon, 13 Jul 2026 16:59:42 -0700 Subject: [PATCH] vmm, hypervisor: Make the VMSA page type optional KVM builds the VMSA internally, so the logic in igvm-loader passing a VMSA page for KVM is misleading. The page is silently dropped later in import_isolated_pages(). Only MSHV actually imports it. Make PageTypeConfig::vmsa an Option that is None on KVM and push the VMSA page only when it is set. As KVM no longer produces a VMSA page, remove the now-dead skip in import_isolated_pages(). Signed-off-by: Ruben Hakobyan --- hypervisor/src/kvm/mod.rs | 5 ----- hypervisor/src/kvm/x86_64/sev.rs | 2 -- vmm/src/igvm/igvm_loader.rs | 23 ++++++++++++----------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 5c66aba2f..8a09de5ff 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -785,11 +785,6 @@ impl vm::Vm for KvmVm { return Ok(()); } assert_eq!(pfns.len(), uaddrs.len()); - // VMSA pages are not supported by launch_update - // https://elixir.bootlin.com/linux/v6.11/source/arch/x86/kvm/svm/sev.c#L2377 - if page_type == sev::SNP_PAGE_TYPE_VMSA { - return Ok(()); - } for i in 0..pfns.len() { self.fd .set_memory_attributes(kvm_memory_attributes { diff --git a/hypervisor/src/kvm/x86_64/sev.rs b/hypervisor/src/kvm/x86_64/sev.rs index 9c4b621bc..64dddb083 100644 --- a/hypervisor/src/kvm/x86_64/sev.rs +++ b/hypervisor/src/kvm/x86_64/sev.rs @@ -23,8 +23,6 @@ const KVM_SEV_INIT2: u32 = 22; const KVM_SEV_SNP_LAUNCH_START: u32 = 100; const KVM_SEV_SNP_LAUNCH_UPDATE: u32 = 101; const KVM_SEV_SNP_LAUNCH_FINISH: u32 = 102; -// SNP_LAUNCH_UPDATE page types — linux/arch/x86/include/uapi/asm/sev-guest.h -pub const SNP_PAGE_TYPE_VMSA: u32 = 2; // See AMD Spec Section 8.17 — SNP_LAUNCH_UPDATE // The last 12 bits are metadata about the guest context diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index a6d9be43d..ae3f4a88d 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -128,8 +128,6 @@ pub enum Error { #[cfg(feature = "kvm")] const KVM_SNP_PAGE_TYPE_NORMAL: u32 = 1; #[cfg(feature = "kvm")] -const KVM_SNP_PAGE_TYPE_VMSA: u32 = 2; -#[cfg(feature = "kvm")] const KVM_SNP_PAGE_TYPE_ZERO: u32 = 3; #[cfg(feature = "kvm")] const KVM_SNP_PAGE_TYPE_UNMEASURED: u32 = 4; @@ -147,7 +145,7 @@ struct PageTypeConfig { unmeasured: u32, cpuid: u32, secrets: u32, - vmsa: u32, + vmsa: Option, } #[derive(Copy, Clone)] @@ -277,7 +275,7 @@ pub fn load_igvm( #[cfg(feature = "sev_snp")] host_data: &Option, ) -> Result, Error> { let hypervisor_type = cpu_manager.lock().unwrap().hypervisor_type(); - let page_types = match hypervisor_type { + let page_types: PageTypeConfig = match hypervisor_type { #[cfg(feature = "mshv")] HypervisorType::Mshv => PageTypeConfig { isolated_page_size_4kb: mshv_bindings::hv_isolated_page_size_HV_ISOLATED_PAGE_SIZE_4KB, @@ -286,7 +284,7 @@ pub fn load_igvm( unmeasured: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_UNMEASURED, cpuid: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_CPUID, secrets: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_SECRETS, - vmsa: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_VMSA, + vmsa: Some(mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_VMSA), }, #[cfg(feature = "kvm")] HypervisorType::Kvm => PageTypeConfig { @@ -296,7 +294,8 @@ pub fn load_igvm( unmeasured: KVM_SNP_PAGE_TYPE_UNMEASURED, cpuid: KVM_SNP_PAGE_TYPE_CPUID, secrets: KVM_SNP_PAGE_TYPE_SECRETS, - vmsa: KVM_SNP_PAGE_TYPE_VMSA, + // KVM doesn't import a VMSA page, it instead constructs it internally + vmsa: None, }, }; @@ -627,11 +626,13 @@ pub fn load_igvm( } } - gpas.push(GpaPages { - gpa: *gpa, - page_type: page_types.vmsa, - page_size: page_types.isolated_page_size_4kb, - }); + if let Some(vmsa_page_type) = page_types.vmsa { + gpas.push(GpaPages { + gpa: *gpa, + page_type: vmsa_page_type, + page_size: page_types.isolated_page_size_4kb, + }); + } } IgvmDirectiveHeader::SnpIdBlock { compatibility_mask,