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 <hruben@meta.com>
This commit is contained in:
Ruben Hakobyan
2026-07-13 16:59:42 -07:00
committed by Rob Bradford
parent 3ddcf50149
commit 6d2d66bcd3
3 changed files with 12 additions and 18 deletions

View File

@@ -785,11 +785,6 @@ impl vm::Vm for KvmVm {
return Ok(()); return Ok(());
} }
assert_eq!(pfns.len(), uaddrs.len()); 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() { for i in 0..pfns.len() {
self.fd self.fd
.set_memory_attributes(kvm_memory_attributes { .set_memory_attributes(kvm_memory_attributes {

View File

@@ -23,8 +23,6 @@ const KVM_SEV_INIT2: u32 = 22;
const KVM_SEV_SNP_LAUNCH_START: u32 = 100; const KVM_SEV_SNP_LAUNCH_START: u32 = 100;
const KVM_SEV_SNP_LAUNCH_UPDATE: u32 = 101; const KVM_SEV_SNP_LAUNCH_UPDATE: u32 = 101;
const KVM_SEV_SNP_LAUNCH_FINISH: u32 = 102; 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 // See AMD Spec Section 8.17 — SNP_LAUNCH_UPDATE
// The last 12 bits are metadata about the guest context // The last 12 bits are metadata about the guest context

View File

@@ -128,8 +128,6 @@ pub enum Error {
#[cfg(feature = "kvm")] #[cfg(feature = "kvm")]
const KVM_SNP_PAGE_TYPE_NORMAL: u32 = 1; const KVM_SNP_PAGE_TYPE_NORMAL: u32 = 1;
#[cfg(feature = "kvm")] #[cfg(feature = "kvm")]
const KVM_SNP_PAGE_TYPE_VMSA: u32 = 2;
#[cfg(feature = "kvm")]
const KVM_SNP_PAGE_TYPE_ZERO: u32 = 3; const KVM_SNP_PAGE_TYPE_ZERO: u32 = 3;
#[cfg(feature = "kvm")] #[cfg(feature = "kvm")]
const KVM_SNP_PAGE_TYPE_UNMEASURED: u32 = 4; const KVM_SNP_PAGE_TYPE_UNMEASURED: u32 = 4;
@@ -147,7 +145,7 @@ struct PageTypeConfig {
unmeasured: u32, unmeasured: u32,
cpuid: u32, cpuid: u32,
secrets: u32, secrets: u32,
vmsa: u32, vmsa: Option<u32>,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@@ -277,7 +275,7 @@ pub fn load_igvm(
#[cfg(feature = "sev_snp")] host_data: &Option<String>, #[cfg(feature = "sev_snp")] host_data: &Option<String>,
) -> Result<Box<IgvmLoadedInfo>, Error> { ) -> Result<Box<IgvmLoadedInfo>, Error> {
let hypervisor_type = cpu_manager.lock().unwrap().hypervisor_type(); 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")] #[cfg(feature = "mshv")]
HypervisorType::Mshv => PageTypeConfig { HypervisorType::Mshv => PageTypeConfig {
isolated_page_size_4kb: mshv_bindings::hv_isolated_page_size_HV_ISOLATED_PAGE_SIZE_4KB, 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, unmeasured: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_UNMEASURED,
cpuid: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_CPUID, cpuid: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_CPUID,
secrets: mshv_bindings::hv_isolated_page_type_HV_ISOLATED_PAGE_TYPE_SECRETS, 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")] #[cfg(feature = "kvm")]
HypervisorType::Kvm => PageTypeConfig { HypervisorType::Kvm => PageTypeConfig {
@@ -296,7 +294,8 @@ pub fn load_igvm(
unmeasured: KVM_SNP_PAGE_TYPE_UNMEASURED, unmeasured: KVM_SNP_PAGE_TYPE_UNMEASURED,
cpuid: KVM_SNP_PAGE_TYPE_CPUID, cpuid: KVM_SNP_PAGE_TYPE_CPUID,
secrets: KVM_SNP_PAGE_TYPE_SECRETS, 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 { if let Some(vmsa_page_type) = page_types.vmsa {
gpa: *gpa, gpas.push(GpaPages {
page_type: page_types.vmsa, gpa: *gpa,
page_size: page_types.isolated_page_size_4kb, page_type: vmsa_page_type,
}); page_size: page_types.isolated_page_size_4kb,
});
}
} }
IgvmDirectiveHeader::SnpIdBlock { IgvmDirectiveHeader::SnpIdBlock {
compatibility_mask, compatibility_mask,