From e4e749da302ebdffbf49504431b02355ef2181f6 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Thu, 27 Feb 2025 14:28:17 -0500 Subject: [PATCH] Enable partition and VP VTL hypercalls for TDX --- .../src/processor/hardware_cvm/mod.rs | 147 +++++++++--------- .../virt_mshv_vtl/src/processor/snp/mod.rs | 12 -- .../virt_mshv_vtl/src/processor/tdx/mod.rs | 5 +- 3 files changed, 76 insertions(+), 88 deletions(-) diff --git a/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs b/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs index 9ff768ba6..45aa3e2ed 100644 --- a/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs @@ -47,79 +47,6 @@ use virt_support_x86emu::translate::TranslateCachingInfo; use virt_support_x86emu::translate::TranslationRegisters; use zerocopy::FromZeros; -impl<'b, T, B: HardwareIsolatedBacking> UhHypercallHandler<'_, 'b, T, B> -where - UhProcessor<'b, B>: TlbFlushLockAccess, -{ - pub fn hcvm_enable_partition_vtl( - &mut self, - partition_id: u64, - target_vtl: Vtl, - flags: hvdef::hypercall::EnablePartitionVtlFlags, - ) -> HvResult<()> { - if partition_id != hvdef::HV_PARTITION_ID_SELF { - return Err(HvError::InvalidPartitionId); - } - - let target_vtl = GuestVtl::try_from(target_vtl).map_err(|_| HvError::AccessDenied)?; - if target_vtl != GuestVtl::Vtl1 { - return Err(HvError::AccessDenied); - } - - if flags.enable_supervisor_shadow_stack() || flags.enable_hardware_hvpt() { - return Err(HvError::InvalidParameter); - } - - let mut gvsm_state = self.vp.partition.guest_vsm.write(); - - match *gvsm_state { - GuestVsmState::NotPlatformSupported => return Err(HvError::AccessDenied), - GuestVsmState::NotGuestEnabled => (), - GuestVsmState::Enabled { vtl1: _ } => { - // VTL 1 cannot be already enabled - return Err(HvError::VtlAlreadyEnabled); - } - } - - self.vp.partition.hcl.enable_partition_vtl( - target_vtl, - // These flags are managed and enforced internally; CVMs can't rely - // on the hypervisor - 0.into(), - )?; - - *gvsm_state = GuestVsmState::Enabled { - vtl1: GuestVsmVtl1State::HardwareCvm { - state: crate::HardwareCvmVtl1State { - mbec_enabled: flags.enable_mbec(), - ..Default::default() - }, - }, - }; - - let protector = self - .vp - .partition - .isolated_memory_protector - .as_ref() - .expect("exists for a cvm"); - - // Grant VTL 1 access to lower VTL memory - tracing::debug!("Granting VTL 1 access to lower VTL memory"); - protector.change_default_vtl_protections( - GuestVtl::Vtl1, - hvdef::HV_MAP_GPA_PERMISSIONS_ALL, - self.vp, - )?; - - tracing::debug!("Successfully granted vtl 1 access to lower vtl memory"); - - tracing::info!("Enabled vtl 1 on the partition"); - - Ok(()) - } -} - impl UhHypercallHandler<'_, '_, T, B> { fn validate_register_access( &mut self, @@ -1055,6 +982,80 @@ where } } +impl<'b, T, B: HardwareIsolatedBacking> hv1_hypercall::EnablePartitionVtl + for UhHypercallHandler<'_, 'b, T, B> +where + UhProcessor<'b, B>: TlbFlushLockAccess, +{ + fn enable_partition_vtl( + &mut self, + partition_id: u64, + target_vtl: Vtl, + flags: hvdef::hypercall::EnablePartitionVtlFlags, + ) -> HvResult<()> { + if partition_id != hvdef::HV_PARTITION_ID_SELF { + return Err(HvError::InvalidPartitionId); + } + + let target_vtl = GuestVtl::try_from(target_vtl).map_err(|_| HvError::AccessDenied)?; + if target_vtl != GuestVtl::Vtl1 { + return Err(HvError::AccessDenied); + } + + if flags.enable_supervisor_shadow_stack() || flags.enable_hardware_hvpt() { + return Err(HvError::InvalidParameter); + } + + let mut gvsm_state = self.vp.partition.guest_vsm.write(); + + match *gvsm_state { + GuestVsmState::NotPlatformSupported => return Err(HvError::AccessDenied), + GuestVsmState::NotGuestEnabled => (), + GuestVsmState::Enabled { vtl1: _ } => { + // VTL 1 cannot be already enabled + return Err(HvError::VtlAlreadyEnabled); + } + } + + self.vp.partition.hcl.enable_partition_vtl( + target_vtl, + // These flags are managed and enforced internally; CVMs can't rely + // on the hypervisor + 0.into(), + )?; + + *gvsm_state = GuestVsmState::Enabled { + vtl1: GuestVsmVtl1State::HardwareCvm { + state: crate::HardwareCvmVtl1State { + mbec_enabled: flags.enable_mbec(), + ..Default::default() + }, + }, + }; + + let protector = self + .vp + .partition + .isolated_memory_protector + .as_ref() + .expect("exists for a cvm"); + + // Grant VTL 1 access to lower VTL memory + tracing::debug!("Granting VTL 1 access to lower VTL memory"); + protector.change_default_vtl_protections( + GuestVtl::Vtl1, + hvdef::HV_MAP_GPA_PERMISSIONS_ALL, + self.vp, + )?; + + tracing::debug!("Successfully granted vtl 1 access to lower vtl memory"); + + tracing::info!("Enabled vtl 1 on the partition"); + + Ok(()) + } +} + impl hv1_hypercall::EnableVpVtl for UhHypercallHandler<'_, '_, T, B> diff --git a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs index 762c2f4f4..747bf6d17 100644 --- a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs @@ -636,7 +636,6 @@ impl UhHypercallHandler<'_, '_, T, SnpBacked> { hv1_hypercall::HvSetVpRegisters, hv1_hypercall::HvModifyVtlProtectionMask, hv1_hypercall::HvX64TranslateVirtualAddress, - hv1_hypercall::HvX64StartVirtualProcessor, ], ); @@ -2168,17 +2167,6 @@ impl UhProcessor<'_, SnpBacked> { } } -impl hv1_hypercall::EnablePartitionVtl for UhHypercallHandler<'_, '_, T, SnpBacked> { - fn enable_partition_vtl( - &mut self, - partition_id: u64, - target_vtl: Vtl, - flags: hvdef::hypercall::EnablePartitionVtlFlags, - ) -> hvdef::HvResult<()> { - self.hcvm_enable_partition_vtl(partition_id, target_vtl, flags) - } -} - impl hv1_hypercall::VtlSwitchOps for UhHypercallHandler<'_, '_, T, SnpBacked> { fn advance_ip(&mut self) { let is_64bit = self.vp.long_mode(self.intercepted_vtl); diff --git a/openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs b/openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs index 781aeaab9..0a56c73fd 100644 --- a/openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs @@ -2720,11 +2720,10 @@ impl UhHypercallHandler<'_, '_, T, TdxBacked> { hv1_hypercall::HvPostMessage, hv1_hypercall::HvSignalEvent, hv1_hypercall::HvExtQueryCapabilities, - // TODO TDX: copied from SNP, enable individually as needed. hv1_hypercall::HvGetVpRegisters, hv1_hypercall::HvSetVpRegisters, - // hv1_hypercall::HvEnablePartitionVtl, - // hv1_hypercall::HvX64EnableVpVtl, + hv1_hypercall::HvEnablePartitionVtl, + hv1_hypercall::HvX64EnableVpVtl, // hv1_hypercall::HvVtlCall, // hv1_hypercall::HvVtlReturn, hv1_hypercall::HvModifyVtlProtectionMask,