Skip to content

Commit

Permalink
scope startvp handling to cvms
Browse files Browse the repository at this point in the history
  • Loading branch information
sluck-msft committed Jan 25, 2025
1 parent 4ef4853 commit 8a29e28
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 63 deletions.
1 change: 1 addition & 0 deletions openhcl/virt_mshv_vtl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ impl WakeReason {
// Convenient constants.
const EXTINT: Self = Self::new().with_extint(true);
const MESSAGE_QUEUES: Self = Self::new().with_message_queues(true);
#[cfg(guest_arch = "x86_64")]
const HV_START_ENABLE_VP_VTL: Self = Self::new().with_hv_start_enable_vtl_vp(true); // StartVp/EnableVpVtl handling
const INTCON: Self = Self::new().with_intcon(true);
#[cfg(guest_arch = "x86_64")]
Expand Down
67 changes: 67 additions & 0 deletions openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,45 @@ impl<T, B: HardwareIsolatedBacking> hv1_hypercall::VtlReturn for UhHypercallHand
}
}

impl<T, B: HardwareIsolatedBacking>
hv1_hypercall::StartVirtualProcessor<hvdef::hypercall::InitialVpContextX64>
for UhHypercallHandler<'_, '_, T, B>
{
fn start_virtual_processor(
&mut self,
partition_id: u64,
target_vp: u32,
target_vtl: Vtl,
vp_context: &hvdef::hypercall::InitialVpContextX64,
) -> HvResult<()> {
tracing::debug!(
vp_index = self.vp.vp_index().index(),
target_vp,
?target_vtl,
"HvStartVirtualProcessor"
);

if partition_id != hvdef::HV_PARTITION_ID_SELF {
return Err(HvError::InvalidPartitionId);
}

if target_vp == self.vp.vp_index().index()
|| target_vp as usize >= self.vp.partition.vps.len()
{
return Err(HvError::InvalidVpIndex);
}

let target_vtl = self.target_vtl_no_higher(target_vtl)?;
let target_vp = &self.vp.partition.vps[target_vp as usize];

// TODO CVM GUEST VSM: probably some validation on vtl1_enabled
*target_vp.hv_start_enable_vtl_vp[target_vtl].lock() = Some(Box::new(*vp_context));
target_vp.wake(target_vtl, WakeReason::HV_START_ENABLE_VP_VTL);

Ok(())
}
}

impl<T, B: HardwareIsolatedBacking> hv1_hypercall::ModifyVtlProtectionMask
for UhHypercallHandler<'_, '_, T, B>
{
Expand Down Expand Up @@ -1214,6 +1253,34 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
Ok(reprocessing_required)
}

pub(crate) fn hcvm_handle_vp_start_enable_vtl(
&mut self,
vtl: GuestVtl,
) -> Result<(), UhRunVpError> {
if let Some(context) = self.inner.hv_start_enable_vtl_vp[vtl].lock().take() {
tracing::debug!(
vp_index = self.inner.cpu_index,
?vtl,
"starting vp with initial registers"
);
hv1_emulator::hypercall::set_x86_vp_context(
&mut self.access_state(vtl.into()),
&context,
)
.map_err(UhRunVpError::State)?;

if vtl == GuestVtl::Vtl1 {
assert!(self.partition.isolation.is_hardware_isolated());
// Should have already initialized the hv emulator for this vtl
assert!(self.backing.hv(vtl).is_some());

// TODO CVM GUEST VSM: Revisit during AP startup if we need to exit to VTL 1 here
}
}

Ok(())
}

fn get_vsm_vp_secure_config_vtl(
&mut self,
requesting_vtl: GuestVtl,
Expand Down
66 changes: 8 additions & 58 deletions openhcl/virt_mshv_vtl/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@ mod private {
dev: &impl CpuIo,
) -> Result<bool, UhRunVpError>;

fn handle_vp_start_enable_vtl_wake(
_this: &mut UhProcessor<'_, Self>,
_vtl: GuestVtl,
) -> Result<(), UhRunVpError> {
Ok(())
}

fn inspect_extra(_this: &mut UhProcessor<'_, Self>, _resp: &mut inspect::Response<'_>) {}

fn hv(&self, vtl: GuestVtl) -> Option<&ProcessorVtlHv>;
Expand Down Expand Up @@ -915,26 +922,7 @@ impl<'a, T: Backing> UhProcessor<'a, T> {

#[cfg(guest_arch = "x86_64")]
if wake_reasons.hv_start_enable_vtl_vp() {
if let Some(context) = self.inner.hv_start_enable_vtl_vp[vtl].lock().take() {
tracing::debug!(
vp_index = self.inner.cpu_index,
?vtl,
"starting vp with initial registers"
);
hv1_emulator::hypercall::set_x86_vp_context(
&mut self.access_state(vtl.into()),
&context,
)
.map_err(UhRunVpError::State)?;

if vtl == GuestVtl::Vtl1 {
assert!(self.partition.isolation.is_hardware_isolated());
// Should have already initialized the hv emulator for this vtl
assert!(self.backing.hv(vtl).is_some());

// TODO CVM GUEST VSM: Revisit during AP startup if we need to exit to VTL 1 here
}
}
T::handle_vp_start_enable_vtl_wake(self, vtl)?;
}

#[cfg(guest_arch = "x86_64")]
Expand Down Expand Up @@ -1324,44 +1312,6 @@ impl<T: CpuIo, B: Backing> Arm64RegisterState for UhHypercallHandler<'_, '_, T,
}
}

impl<T, B: Backing> hv1_hypercall::StartVirtualProcessor<hvdef::hypercall::InitialVpContextX64>
for UhHypercallHandler<'_, '_, T, B>
{
fn start_virtual_processor(
&mut self,
partition_id: u64,
target_vp: u32,
target_vtl: Vtl,
vp_context: &hvdef::hypercall::InitialVpContextX64,
) -> hvdef::HvResult<()> {
tracing::debug!(
vp_index = self.vp.vp_index().index(),
target_vp,
?target_vtl,
"HvStartVirtualProcessor"
);

if partition_id != hvdef::HV_PARTITION_ID_SELF {
return Err(HvError::InvalidPartitionId);
}

if target_vp == self.vp.vp_index().index()
|| target_vp as usize >= self.vp.partition.vps.len()
{
return Err(HvError::InvalidVpIndex);
}

let target_vtl = self.target_vtl_no_higher(target_vtl)?;
let target_vp = &self.vp.partition.vps[target_vp as usize];

// TODO CVM GUEST VSM: probably some validation on vtl1_enabled
*target_vp.hv_start_enable_vtl_vp[target_vtl].lock() = Some(Box::new(*vp_context));
target_vp.wake(target_vtl, WakeReason::HV_START_ENABLE_VP_VTL);

Ok(())
}
}

impl<T: CpuIo, B: Backing> hv1_hypercall::PostMessage for UhHypercallHandler<'_, '_, T, B> {
fn post_message(&mut self, connection_id: u32, message: &[u8]) -> hvdef::HvResult<()> {
tracing::trace!(
Expand Down
1 change: 0 additions & 1 deletion openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,6 @@ impl<T: CpuIo> UhHypercallHandler<'_, '_, T, HypervisorBackedArm64> {
hv1_hypercall::HvPostMessage,
hv1_hypercall::HvSignalEvent,
hv1_hypercall::HvRetargetDeviceInterrupt,
hv1_hypercall::HvX64StartVirtualProcessor,
hv1_hypercall::HvGetVpIndexFromApicId,
]
);
Expand Down
1 change: 0 additions & 1 deletion openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1651,7 +1651,6 @@ impl<T: CpuIo> UhHypercallHandler<'_, '_, T, HypervisorBackedX86> {
hv1_hypercall::HvPostMessage,
hv1_hypercall::HvSignalEvent,
hv1_hypercall::HvRetargetDeviceInterrupt,
hv1_hypercall::HvX64StartVirtualProcessor,
hv1_hypercall::HvGetVpIndexFromApicId,
hv1_hypercall::HvSetVpRegisters,
hv1_hypercall::HvModifyVtlProtectionMask
Expand Down
7 changes: 7 additions & 0 deletions openhcl/virt_mshv_vtl/src/processor/snp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,13 @@ impl BackingPrivate for SnpBacked {
fn untrusted_synic_mut(&mut self) -> Option<&mut ProcessorSynic> {
None
}

fn handle_vp_start_enable_vtl_wake(
this: &mut UhProcessor<'_, Self>,
vtl: GuestVtl,
) -> Result<(), UhRunVpError> {
this.hcvm_handle_vp_start_enable_vtl(vtl)
}
}

fn hv_seg_to_snp(val: &hvdef::HvX64SegmentRegister) -> SevSelector {
Expand Down
4 changes: 1 addition & 3 deletions vm/hv1/hv1_emulator/src/cpuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ pub fn hv_cpuid_leaves(
.with_access_apic_msrs(true)
.with_access_vp_runtime_msr(true)
.with_access_partition_reference_tsc(true)
.with_start_virtual_processor(true)
.with_start_virtual_processor(hardware_isolated)
.with_access_vsm(access_vsm)
// TODO GUEST_VSM: Not actually implemented yet, but this is
// needed for guest vsm bringup
.with_enable_extended_gva_ranges_flush_va_list(access_vsm);

if hardware_isolated {
Expand Down

0 comments on commit 8a29e28

Please sign in to comment.