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(());
}
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 {

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_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

View File

@@ -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<u32>,
}
#[derive(Copy, Clone)]
@@ -277,7 +275,7 @@ pub fn load_igvm(
#[cfg(feature = "sev_snp")] host_data: &Option<String>,
) -> Result<Box<IgvmLoadedInfo>, 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,