vmm, hypervisor: Initialize SEV-SNP VM

As part of this initialization for a SEV-SNP VM on MSHV, it is required
that we transition the guest state to secure state using partition
hypercall. This implies all the created VPs will transition to secure
state and could access the guest encrypted memory.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
Jinank Jain 2023-10-12 11:01:02 +00:00 committed by Rob Bradford
parent 311fc05417
commit 1b59ab3d7b
3 changed files with 36 additions and 0 deletions

View File

@ -1266,4 +1266,14 @@ impl vm::Vm for MshvVm {
fn as_any(&self) -> &dyn Any {
self
}
/// Initialize the SEV-SNP VM
#[cfg(feature = "sev_snp")]
fn sev_snp_init(&self) -> vm::Result<()> {
self.fd
.set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_ISOLATION_STATE,
hv_partition_isolation_state_HV_PARTITION_ISOLATION_SECURE as u64,
)
.map_err(|e| vm::HypervisorVmError::InitializeSevSnp(e.into()))
}
}

View File

@ -190,6 +190,13 @@ pub enum HypervisorVmError {
#[error("Failed to assert virtual Interrupt: {0}")]
AsserttVirtualInterrupt(#[source] anyhow::Error),
#[cfg(feature = "sev_snp")]
///
/// Error initializing SEV-SNP on the VM
///
#[error("Failed to initialize SEV-SNP: {0}")]
InitializeSevSnp(#[source] std::io::Error),
#[cfg(feature = "tdx")]
///
/// Error initializing TDX on the VM
@ -324,6 +331,11 @@ pub trait Vm: Send + Sync + Any {
fn stop_dirty_log(&self) -> Result<()>;
/// Get dirty pages bitmap
fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>;
#[cfg(feature = "sev_snp")]
/// Initialize SEV-SNP on this VM
fn sev_snp_init(&self) -> Result<()> {
unimplemented!()
}
#[cfg(feature = "tdx")]
/// Initialize TDX on this VM
fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> {

View File

@ -245,6 +245,10 @@ pub enum Error {
#[error("Failed to copy firmware to memory: {0}")]
FirmwareLoad(#[source] vm_memory::GuestMemoryError),
#[cfg(feature = "sev_snp")]
#[error("Error enabling SEV-SNP VM: {0}")]
InitializeSevSnpVm(#[source] hypervisor::HypervisorVmError),
#[cfg(feature = "tdx")]
#[error("Error performing I/O on TDX firmware file: {0}")]
LoadTdvf(#[source] std::io::Error),
@ -491,6 +495,8 @@ impl Vm {
#[cfg(feature = "tdx")]
let tdx_enabled = config.lock().unwrap().is_tdx_enabled();
#[cfg(feature = "sev_snp")]
let sev_snp_enabled = config.lock().unwrap().is_sev_snp_enabled();
#[cfg(feature = "tdx")]
let force_iommu = tdx_enabled;
#[cfg(not(feature = "tdx"))]
@ -558,6 +564,14 @@ impl Vm {
.create_boot_vcpus(snapshot_from_id(snapshot.as_ref(), CPU_MANAGER_SNAPSHOT_ID))
.map_err(Error::CpuManager)?;
// This initial SEV-SNP configuration must be done immediately after
// vCPUs are created. As part of this initialization we are
// transitioning the guest into secure state.
#[cfg(feature = "sev_snp")]
if sev_snp_enabled {
vm.sev_snp_init().map_err(Error::InitializeSevSnpVm)?;
}
#[cfg(feature = "tdx")]
let dynamic = !tdx_enabled;
#[cfg(not(feature = "tdx"))]