From 4847f5c4f606f3cf0c93d18d8e4e5c3172780e69 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Wed, 17 Apr 2024 11:42:55 -0700 Subject: [PATCH] hypervisor: implement clock data for MSHV This PR implement time reference for Microsoft Hypervisor based partition/VM. Signed-off-by: Muminul Islam --- hypervisor/src/lib.rs | 2 +- hypervisor/src/mshv/mod.rs | 35 ++++++++++++++++++++++++++++--- hypervisor/src/mshv/x86_64/mod.rs | 5 +++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index 88f3c7e6f..0c4d78d0a 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -165,7 +165,7 @@ pub enum ClockData { #[cfg(feature = "kvm")] Kvm(kvm_bindings::kvm_clock_data), #[cfg(feature = "mshv")] - Mshv, /* MSHV does not support ClockData yet */ + Mshv(mshv::MshvClockData), } #[cfg(target_arch = "x86_64")] diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index d8628ebcb..b1b3a9c6c 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -92,6 +92,25 @@ impl From for UserMemoryRegion { } } +#[cfg(target_arch = "x86_64")] +impl From for ClockData { + fn from(d: MshvClockData) -> Self { + ClockData::Mshv(d) + } +} + +#[cfg(target_arch = "x86_64")] +impl From for MshvClockData { + fn from(ms: ClockData) -> Self { + match ms { + ClockData::Mshv(s) => s, + /* Needed in case other hypervisors are enabled */ + #[allow(unreachable_patterns)] + _ => unreachable!("MSHV clock data is not valid"), + } + } +} + impl From for mshv_user_mem_region { fn from(region: UserMemoryRegion) -> Self { let mut flags: u32 = 0; @@ -1930,13 +1949,23 @@ impl vm::Vm for MshvVm { /// Retrieve guest clock. #[cfg(target_arch = "x86_64")] fn get_clock(&self) -> vm::Result { - Ok(ClockData::Mshv) + let val = self + .fd + .get_partition_property(hv_partition_property_code_HV_PARTITION_PROPERTY_REFERENCE_TIME) + .map_err(|e| vm::HypervisorVmError::GetClock(e.into()))?; + Ok(MshvClockData { ref_time: val }.into()) } /// Set guest clock. #[cfg(target_arch = "x86_64")] - fn set_clock(&self, _data: &ClockData) -> vm::Result<()> { - Ok(()) + fn set_clock(&self, data: &ClockData) -> vm::Result<()> { + let data: MshvClockData = (*data).into(); + self.fd + .set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_REFERENCE_TIME, + data.ref_time, + ) + .map_err(|e| vm::HypervisorVmError::SetClock(e.into())) } /// Downcast to the underlying MshvVm type diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index d9e19d7b5..2c42e1456 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -43,6 +43,11 @@ pub struct VcpuMshvState { pub vp_states: AllVpStateComponents, } +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] +pub struct MshvClockData { + pub ref_time: u64, +} + impl fmt::Display for VcpuMshvState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let expected_num_msrs = self.msrs.len();