From 6a8fdd9f8e23545619a7da330f1baf6cc34c552c Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Wed, 16 Jan 2019 14:38:41 -0800 Subject: crosvm: add suspend/resume commands This change adds the suspend and resume commands to crosvm, as well as corresponding VmRequest variants and VCPU loop support. When a request triggers a VmRunMode change, the Mutex guarded shared VmRunMode variable is mutated and the associated Condvar is notified. Each VCPU thread is interrupted to kick it out of the KVM_RUN call and checks the VmRunMode, If the VCPU was already suspended by waiting for the Condvar, the notify_all call will wake up the thread, upon which the VCPU thread can respond to the new mode. TEST=crosvm suspend/crosvm resume BUG=chromium:920875 Change-Id: Ibbeb748ab0d64402c7196890815e8e1cb4dfca38 Reviewed-on: https://chromium-review.googlesource.com/1416317 Commit-Ready: Zach Reizner Tested-by: kokoro Tested-by: Zach Reizner Reviewed-by: Dylan Reid --- vm_control/src/lib.rs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'vm_control') diff --git a/vm_control/src/lib.rs b/vm_control/src/lib.rs index e2fe995..09e1ea2 100644 --- a/vm_control/src/lib.rs +++ b/vm_control/src/lib.rs @@ -67,6 +67,23 @@ impl MsgOnSocket for MaybeOwnedFd { } } +/// Mode of execution for the VM. +#[derive(Debug)] +pub enum VmRunMode { + /// The default run mode indicating the VCPUs are running. + Running, + /// Indicates that the VCPUs are suspending execution until the `Running` mode is set. + Suspending, + /// Indicates that the VM is exiting all processes. + Exiting, +} + +impl Default for VmRunMode { + fn default() -> Self { + VmRunMode::Running + } +} + /// A request to the main process to perform some operation on the VM. /// /// Unless otherwise noted, each request should expect a `VmResponse::Ok` to be received on success. @@ -76,6 +93,10 @@ pub enum VmRequest { BalloonAdjust(u64), /// Break the VM's run loop and exit. Exit, + /// Suspend the VM's VCPUs until resume. + Suspend, + /// Resume the VM's VCPUs that were previously suspended. + Resume, /// Register the given ioevent address along with given datamatch to trigger the `EventFd`. RegisterIoevent(EventFd, IoeventAddress, u32), /// Register the given IRQ number to be triggered when the `EventFd` is triggered. @@ -126,7 +147,7 @@ impl VmRequest { /// # Arguments /// * `vm` - The `Vm` to perform the request on. /// * `allocator` - Used to allocate addresses. - /// * `running` - Out argument that is set to false if the request was to stop running the VM. + /// * `run_mode` - Out argument that is set to a run mode if one was requested. /// /// This does not return a result, instead encapsulating the success or failure in a /// `VmResponse` with the intended purpose of sending the response back over the socket that @@ -135,14 +156,21 @@ impl VmRequest { &self, vm: &mut Vm, sys_allocator: &mut SystemAllocator, - running: &mut bool, + run_mode: &mut Option, balloon_host_socket: &UnixDatagram, disk_host_sockets: &[MsgSocket], ) -> VmResponse { - *running = true; match *self { VmRequest::Exit => { - *running = false; + *run_mode = Some(VmRunMode::Exiting); + VmResponse::Ok + } + VmRequest::Suspend => { + *run_mode = Some(VmRunMode::Suspending); + VmResponse::Ok + } + VmRequest::Resume => { + *run_mode = Some(VmRunMode::Running); VmResponse::Ok } VmRequest::RegisterIoevent(ref evt, addr, datamatch) => { -- cgit 1.4.1