From 1b59ab3d7b7881caf5971b0bfc0583d22194e93f Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Thu, 12 Oct 2023 11:01:02 +0000 Subject: [PATCH] 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 --- hypervisor/src/mshv/mod.rs | 10 ++++++++++ hypervisor/src/vm.rs | 12 ++++++++++++ vmm/src/vm.rs | 14 ++++++++++++++ 3 files changed, 36 insertions(+) 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"))]