hypervisor, vmm: Build and pass SNP ID block to launch finish

Add KvmSevSnpIdBlock and KvmSevSnpIdAuth structs matching the AMD
SEV-SNP Firmware ABI Spec (Rev 1.58), and build them from the IGVM
SNP ID block directive during launch finish. This properly populates
id_block_uaddr/id_auth_uaddr in KVM_SEV_SNP_LAUNCH_FINISH and derives
auth_key_en from the assembled author key, matching QEMU's behavior.

Thread the guest policy from sev_snp_init to launch_finish via an
atomic on KvmVm so the ID block gets the correct policy value.

Also track has_snp_id_block in IgvmLoadedInfo to enable the ID block
based on whether the IGVM file actually contains one, rather than
hardcoding it for KVM.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
This commit is contained in:
Ruben Hakobyan
2026-04-30 06:57:40 -07:00
committed by Rob Bradford
parent bfab43e252
commit c97d635d40
6 changed files with 228 additions and 9 deletions

View File

@@ -563,6 +563,8 @@ pub struct KvmVm {
msrs: Vec<MsrEntry>,
#[cfg(all(feature = "sev_snp", target_arch = "x86_64"))]
sev_fd: Option<x86_64::sev::SevFd>,
#[cfg(all(feature = "sev_snp", target_arch = "x86_64"))]
snp_guest_policy: std::sync::OnceLock<u64>,
dirty_log_slots: RwLock<HashMap<u32, KvmDirtyLogSlot>>,
guest_memfds: Option<RwLock<HashMap<u32, OwnedFd>>>,
}
@@ -689,7 +691,11 @@ impl vm::Vm for KvmVm {
.as_ref()
.unwrap()
.launch_start(&self.fd, guest_policy)
.map_err(|e| vm::HypervisorVmError::InitializeSevSnp(e.into()))
.map_err(|e| vm::HypervisorVmError::InitializeSevSnp(e.into()))?;
self.snp_guest_policy
.set(guest_policy.into_bits())
.expect("sev_snp_init called more than once");
Ok(())
}
#[cfg(all(feature = "sev_snp", target_arch = "x86_64"))]
@@ -736,15 +742,22 @@ impl vm::Vm for KvmVm {
snp_id_block: igvm_defs::IGVM_VHS_SNP_ID_BLOCK,
host_data: [u8; 32],
id_block_enabled: u8,
auth_key_enabled: u8,
) -> vm::Result<()> {
let guest_policy = *self
.snp_guest_policy
.get()
.expect("complete_isolated_import called before sev_snp_init");
self.sev_fd
.as_ref()
.unwrap()
.launch_finish(
&self.fd,
&snp_id_block,
host_data,
id_block_enabled,
snp_id_block.author_key_enabled,
auth_key_enabled,
guest_policy,
)
.map_err(|e| vm::HypervisorVmError::CompleteIsolatedImport(e.into()))
}
@@ -1606,6 +1619,8 @@ impl hypervisor::Hypervisor for KvmHypervisor {
dirty_log_slots: RwLock::new(HashMap::new()),
#[cfg(feature = "sev_snp")]
sev_fd,
#[cfg(feature = "sev_snp")]
snp_guest_policy: std::sync::OnceLock::new(),
guest_memfds,
}))
}