diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index 51bea90ee..f2fead3fa 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -139,6 +139,11 @@ pub enum HypervisorCpuError { /// #[error("Failed to init vcpu: {0}")] GetOneReg(#[source] anyhow::Error), + /// + /// Getting guest clock paused error + /// + #[error("Failed to notify guest its clock was paused: {0}")] + NotifyGuestClockPaused(#[source] anyhow::Error), } /// @@ -248,6 +253,12 @@ pub trait Vcpu: Send + Sync { /// states of the vcpu. /// fn get_vcpu_events(&self) -> Result; + #[cfg(target_arch = "x86_64")] + /// + /// Let the guest know that it has been paused, which prevents from + /// potential soft lockups when being resumed. + /// + fn notify_guest_clock_paused(&self) -> Result<()>; /// /// Sets the type of CPU to be exposed to the guest and optional features. /// diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 366914e2a..25e0b9c5e 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -525,6 +525,16 @@ impl cpu::Vcpu for KvmVcpu { .get_vcpu_events() .map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into())) } + #[cfg(target_arch = "x86_64")] + /// + /// Let the guest know that it has been paused, which prevents from + /// potential soft lockups when being resumed. + /// + fn notify_guest_clock_paused(&self) -> cpu::Result<()> { + self.fd + .kvmclock_ctrl() + .map_err(|e| cpu::HypervisorCpuError::NotifyGuestClockPaused(e.into())) + } #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> { self.fd