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
+12
View File
@@ -87,6 +87,8 @@ pub enum Error {
Igvm(#[source] std::io::Error),
#[error("invalid igvm file")]
InvalidIgvmFile(#[source] igvm::Error),
#[error("multiple SNP ID blocks in IGVM file")]
DuplicateSnpIdBlock,
#[error("invalid guest memory map")]
InvalidGuestMemmap(#[source] arch::Error),
#[error("loader error")]
@@ -678,6 +680,9 @@ pub fn load_igvm(
author_key_signature,
author_public_key,
} => {
if loaded_info.has_snp_id_block {
return Err(Error::DuplicateSnpIdBlock);
}
loaded_info.snp_id_block.compatibility_mask = *compatibility_mask;
loaded_info.snp_id_block.author_key_enabled = *author_key_enabled;
loaded_info.snp_id_block.reserved = *reserved;
@@ -692,6 +697,7 @@ pub fn load_igvm(
loaded_info.snp_id_block.id_public_key = **id_public_key;
loaded_info.snp_id_block.author_key_signature = **author_key_signature;
loaded_info.snp_id_block.author_public_key = **author_public_key;
loaded_info.has_snp_id_block = true;
}
IgvmDirectiveHeader::X64VbsVpContext {
vtl: _,
@@ -929,7 +935,12 @@ pub fn load_igvm(
let id_block_enabled = if hypervisor_type == HypervisorType::Mshv {
1
} else {
u8::from(loaded_info.has_snp_id_block)
};
let auth_key_enabled = if hypervisor_type == HypervisorType::Mshv {
0
} else {
loaded_info.snp_id_block.author_key_enabled
};
now = Instant::now();
@@ -942,6 +953,7 @@ pub fn load_igvm(
loaded_info.snp_id_block,
host_data_contents,
id_block_enabled,
auth_key_enabled,
)
.map_err(Error::CompleteIsolatedImport)?;
+2
View File
@@ -45,6 +45,7 @@ pub struct IgvmLoadedInfo {
pub gpas: Vec<u64>,
pub vmsa_gpa: u64,
pub snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
pub has_snp_id_block: bool,
pub vmsa: SevVmsa,
}
@@ -54,6 +55,7 @@ impl Default for IgvmLoadedInfo {
gpas: Vec::new(),
vmsa_gpa: 0,
snp_id_block: IGVM_VHS_SNP_ID_BLOCK::new_zeroed(),
has_snp_id_block: false,
vmsa: SevVmsa::new_zeroed(),
}
}