From a16414dc8771bee6a2b99e0abaf52e414450ba3b Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 22 Jun 2020 15:13:45 +0200 Subject: [PATCH] vmm: Restore vCPUs in "paused" state To follow a symmetrical model, and avoid potential race conditions, it's important to restore a previously snapshot VM in a "paused" state. The snapshot operation being valid only if the VM has been previously paused. Signed-off-by: Sebastien Boeuf --- vmm/src/cpu.rs | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 136b3f6f4..3b8e9f48a 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -790,28 +790,6 @@ impl CpuManager { vcpu_thread_barrier.wait(); loop { - // vcpu.run() returns false on a KVM_EXIT_SHUTDOWN (triple-fault) so trigger a reset - match vcpu.lock().unwrap().run() { - Err(e) => { - error!("VCPU generated error: {:?}", e); - break; - } - Ok(true) => {} - Ok(false) => { - vcpu_run_interrupted.store(true, Ordering::SeqCst); - reset_evt.write(1).unwrap(); - break; - } - } - - // We've been told to terminate - if vcpu_kill_signalled.load(Ordering::SeqCst) - || vcpu_kill.load(Ordering::SeqCst) - { - vcpu_run_interrupted.store(true, Ordering::SeqCst); - break; - } - // If we are being told to pause, we park the thread // until the pause boolean is toggled. // The resume operation is responsible for toggling @@ -834,6 +812,28 @@ impl CpuManager { vcpu_run_interrupted.store(true, Ordering::SeqCst); break; } + + // vcpu.run() returns false on a KVM_EXIT_SHUTDOWN (triple-fault) so trigger a reset + match vcpu.lock().unwrap().run() { + Err(e) => { + error!("VCPU generated error: {:?}", e); + break; + } + Ok(true) => {} + Ok(false) => { + vcpu_run_interrupted.store(true, Ordering::SeqCst); + reset_evt.write(1).unwrap(); + break; + } + } + + // We've been told to terminate + if vcpu_kill_signalled.load(Ordering::SeqCst) + || vcpu_kill.load(Ordering::SeqCst) + { + vcpu_run_interrupted.store(true, Ordering::SeqCst); + break; + } } }) .map_err(Error::VcpuSpawn)?, @@ -1332,6 +1332,9 @@ impl Snapshottable for CpuManager { fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { let vcpu_thread_barrier = Arc::new(Barrier::new((snapshot.snapshots.len() + 1) as usize)); + // Restore the vCPUs in "paused" state. + self.vcpus_pause_signalled.store(true, Ordering::SeqCst); + for (cpu_id, snapshot) in snapshot.snapshots.iter() { debug!("Restoring VCPU {}", cpu_id); let vcpu = self