mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
vmm: cpu_manager: Implement the Pausable trait
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
35dd1523c9
commit
9756fc2dd0
@ -25,6 +25,7 @@ use devices::{ioapic, BusDevice};
|
||||
use kvm_bindings::CpuId;
|
||||
use kvm_ioctls::*;
|
||||
|
||||
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||
use vm_memory::{Address, GuestAddress, GuestMemoryMmap};
|
||||
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
@ -627,34 +628,6 @@ impl CpuManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pause(&self) -> Result<()> {
|
||||
// Tell the vCPUs to pause themselves next time they exit
|
||||
self.vcpus_pause_signalled.store(true, Ordering::SeqCst);
|
||||
|
||||
// Signal to the spawned threads (vCPUs and console signal handler). For the vCPU threads
|
||||
// this will interrupt the KVM_RUN ioctl() allowing the loop to check the boolean set
|
||||
// above.
|
||||
for state in self.vcpu_states.iter() {
|
||||
state.signal_thread();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn resume(&self) -> Result<()> {
|
||||
// Toggle the vCPUs pause boolean
|
||||
self.vcpus_pause_signalled.store(false, Ordering::SeqCst);
|
||||
|
||||
// Unpark all the VCPU threads.
|
||||
// Once unparked, the next thing they will do is checking for the pause
|
||||
// boolean. Since it'll be set to false, they will exit their pause loop
|
||||
// and go back to vmx root.
|
||||
for state in self.vcpu_states.iter() {
|
||||
state.unpark_thread();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn boot_vcpus(&self) -> u8 {
|
||||
self.boot_vcpus
|
||||
}
|
||||
@ -900,3 +873,36 @@ impl Aml for CpuManager {
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl Pausable for CpuManager {
|
||||
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
// Tell the vCPUs to pause themselves next time they exit
|
||||
self.vcpus_pause_signalled.store(true, Ordering::SeqCst);
|
||||
|
||||
// Signal to the spawned threads (vCPUs and console signal handler). For the vCPU threads
|
||||
// this will interrupt the KVM_RUN ioctl() allowing the loop to check the boolean set
|
||||
// above.
|
||||
for state in self.vcpu_states.iter() {
|
||||
state.signal_thread();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resume(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
// Toggle the vCPUs pause boolean
|
||||
self.vcpus_pause_signalled.store(false, Ordering::SeqCst);
|
||||
|
||||
// Unpark all the VCPU threads.
|
||||
// Once unparked, the next thing they will do is checking for the pause
|
||||
// boolean. Since it'll be set to false, they will exit their pause loop
|
||||
// and go back to vmx root.
|
||||
for state in self.vcpu_states.iter() {
|
||||
state.unpark_thread();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Snapshotable for CpuManager {}
|
||||
impl Migratable for CpuManager {}
|
||||
|
@ -152,6 +152,12 @@ pub enum Error {
|
||||
|
||||
/// Cannot resume devices
|
||||
ResumeDevices(MigratableError),
|
||||
|
||||
/// Cannot pause CPUs
|
||||
PauseCpus(MigratableError),
|
||||
|
||||
/// Cannot resume cpus
|
||||
ResumeCpus(MigratableError),
|
||||
}
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
@ -633,7 +639,7 @@ impl Vm {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pause()
|
||||
.map_err(Error::CpuManager)?;
|
||||
.map_err(Error::PauseCpus)?;
|
||||
self.devices.pause().map_err(Error::PauseDevices)?;
|
||||
|
||||
*state = new_state;
|
||||
@ -652,7 +658,7 @@ impl Vm {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.resume()
|
||||
.map_err(Error::CpuManager)?;
|
||||
.map_err(Error::ResumeCpus)?;
|
||||
|
||||
// And we're back to the Running state.
|
||||
*state = new_state;
|
||||
|
Loading…
x
Reference in New Issue
Block a user