summary refs log tree commit diff
path: root/vm_control
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-01-16 14:38:41 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-23 20:40:38 -0800
commit6a8fdd9f8e23545619a7da330f1baf6cc34c552c (patch)
tree6d1a50c0e488629e5c41fdef614e9563ae5adf8e /vm_control
parent5694c62885554ccbad171e27a59462020f51fc0b (diff)
downloadcrosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar.gz
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar.bz2
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar.lz
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar.xz
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.tar.zst
crosvm-6a8fdd9f8e23545619a7da330f1baf6cc34c552c.zip
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 <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'vm_control')
-rw-r--r--vm_control/src/lib.rs36
1 files changed, 32 insertions, 4 deletions
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<VmRunMode>,
         balloon_host_socket: &UnixDatagram,
         disk_host_sockets: &[MsgSocket<VmRequest, VmResponse>],
     ) -> 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) => {