summary refs log tree commit diff
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2020-01-29 18:06:01 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-01 08:50:23 +0000
commit95885316c25147ffe85700e4db5477aa8e516005 (patch)
tree40cb4ede10445093fb9f8a4ce28b55a5384b9af3
parent98419968d521b4e081dc79651f9602d46c6184ca (diff)
downloadcrosvm-95885316c25147ffe85700e4db5477aa8e516005.tar
crosvm-95885316c25147ffe85700e4db5477aa8e516005.tar.gz
crosvm-95885316c25147ffe85700e4db5477aa8e516005.tar.bz2
crosvm-95885316c25147ffe85700e4db5477aa8e516005.tar.lz
crosvm-95885316c25147ffe85700e4db5477aa8e516005.tar.xz
crosvm-95885316c25147ffe85700e4db5477aa8e516005.tar.zst
crosvm-95885316c25147ffe85700e4db5477aa8e516005.zip
linux: use ScopedEvent to trigger the `exit_evt` in vcpu threads
The VCPU thread can panic when there is a bug, and this should trigger
an exit in crosvm instead of hanging the VCPU thread forever.

BUG=None
TEST=run crosvm with kernel, trigger a vcpu exit using guest

Change-Id: I1df0e04eda73ad67fec20adeff893f6c00699318
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2029929
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Commit-Queue: Zach Reizner <zachr@chromium.org>
-rw-r--r--src/linux.rs15
1 files changed, 8 insertions, 7 deletions
diff --git a/src/linux.rs b/src/linux.rs
index 5d060b4..144345e 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -50,8 +50,8 @@ use sys_util::{
     self, block_signal, clear_signal, drop_capabilities, error, flock, get_blocked_signals,
     get_group_id, get_user_id, getegid, geteuid, info, register_rt_signal_handler,
     set_cpu_affinity, validate_raw_fd, warn, EventFd, FlockOperation, GuestAddress, GuestMemory,
-    Killable, MemoryMappingArena, PollContext, PollToken, Protection, SignalFd, Terminal, TimerFd,
-    WatchingEvents, SIGRTMIN,
+    Killable, MemoryMappingArena, PollContext, PollToken, Protection, ScopedEvent, SignalFd,
+    Terminal, TimerFd, WatchingEvents, SIGRTMIN,
 };
 use vhost;
 use vm_control::{
@@ -1325,6 +1325,10 @@ fn run_vcpu(
     thread::Builder::new()
         .name(format!("crosvm_vcpu{}", cpu_id))
         .spawn(move || {
+            // The VCPU thread must trigger the `exit_evt` in all paths, and a `ScopedEvent`'s Drop
+            // implementation accomplishes that.
+            let _scoped_exit_evt = ScopedEvent::from(exit_evt);
+
             if vcpu_affinity.len() != 0 {
                 if let Err(e) = set_cpu_affinity(vcpu_affinity) {
                     error!("Failed to set CPU affinity: {}", e);
@@ -1336,7 +1340,7 @@ fn run_vcpu(
             start_barrier.wait();
 
             if let Some(vcpu) = vcpu {
-                'vcpu_loop: loop {
+                loop {
                     let mut interrupted_by_signal = false;
                     match vcpu.run() {
                         Ok(VcpuExit::IoIn { port, mut size }) => {
@@ -1421,7 +1425,7 @@ fn run_vcpu(
                                         }
                                     }
                                 }
-                                VmRunMode::Exiting => break 'vcpu_loop,
+                                VmRunMode::Exiting => return,
                             }
                             // Give ownership of our exclusive lock to the condition variable that
                             // will block. When the condition variable is notified, `wait` will
@@ -1431,9 +1435,6 @@ fn run_vcpu(
                     }
                 }
             }
-            exit_evt
-                .write(1)
-                .expect("failed to signal vcpu exit eventfd");
         })
         .map_err(Error::SpawnVcpu)
 }