diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 0af463b7f..37c1b3d24 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -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())) + } } diff --git a/hypervisor/src/vm.rs b/hypervisor/src/vm.rs index 6b53d65a6..319885cd0 100644 --- a/hypervisor/src/vm.rs +++ b/hypervisor/src/vm.rs @@ -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>; + #[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<()> { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index d3219529d..81a0382a0 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -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"))]