summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2019-10-22 18:30:36 +0300
committerCommit Bot <commit-bot@chromium.org>2019-12-10 05:16:06 +0000
commitbb30b2f7cf2721b32da71adfa7f7482bfce7b915 (patch)
treee364b4b3d1e605ec1aa7ba032e1d3211cd12ca18 /src/linux.rs
parent7434c0002022541f34a929d9a8e3bfaaf4dfc2d9 (diff)
downloadcrosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.gz
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.bz2
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.lz
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.xz
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.zst
crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.zip
Add runnable vcpu
Add a new type `RunnableVcpu` for a vcpu that is bound to a thread. This
adds type safety to ensure that vcpus are only ever run on one thread
because RunnableVcpu can't `Send`. It also ensures multiple vcpus can't
run on the same thread.

Change-Id: Ia50dc127bc7a4ea4ce3ca99ef1062edbcaa912d0
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1898909
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs59
1 files changed, 33 insertions, 26 deletions
diff --git a/src/linux.rs b/src/linux.rs
index 1dd1004..f692ea0 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -1207,8 +1207,38 @@ impl VcpuRunMode {
     }
 }
 
+// Converts a vcpu into a runnable vcpu if possible. On failure, returns `None`.
+fn runnable_vcpu(vcpu: Vcpu, use_kvm_signals: bool, cpu_id: u32) -> Option<RunnableVcpu> {
+    if use_kvm_signals {
+        match get_blocked_signals() {
+            Ok(mut v) => {
+                v.retain(|&x| x != SIGRTMIN() + 0);
+                if let Err(e) = vcpu.set_signal_mask(&v) {
+                    error!(
+                        "Failed to set the KVM_SIGNAL_MASK for vcpu {} : {}",
+                        cpu_id, e
+                    );
+                    return None;
+                }
+            }
+            Err(e) => {
+                error!("Failed to retrieve signal mask for vcpu {} : {}", cpu_id, e);
+                return None;
+            }
+        };
+    }
+
+    match vcpu.to_runnable(Some(SIGRTMIN() + 0)) {
+        Ok(v) => Some(v),
+        Err(e) => {
+            error!("Failed to set thread id for vcpu {} : {}", cpu_id, e);
+            None
+        }
+    }
+}
+
 fn run_vcpu(
-    mut vcpu: Vcpu,
+    vcpu: Vcpu,
     cpu_id: u32,
     vcpu_affinity: Vec<usize>,
     start_barrier: Arc<Barrier>,
@@ -1228,34 +1258,11 @@ fn run_vcpu(
                 }
             }
 
-            let mut sig_ok = true;
-            if use_kvm_signals {
-                match get_blocked_signals() {
-                    Ok(mut v) => {
-                        v.retain(|&x| x != SIGRTMIN() + 0);
-                        if let Err(e) = vcpu.set_signal_mask(&v) {
-                            error!(
-                                "Failed to set the KVM_SIGNAL_MASK for vcpu {} : {}",
-                                cpu_id, e
-                            );
-                            sig_ok = false;
-                        }
-                    }
-                    Err(e) => {
-                        error!(
-                            "Failed to retrieve signal mask for vcpu {} : {}",
-                            cpu_id, e
-                        );
-                        sig_ok = false;
-                    }
-                };
-            } else {
-                vcpu.set_thread_id(SIGRTMIN() + 0);
-            }
+            let vcpu = runnable_vcpu(vcpu, use_kvm_signals, cpu_id);
 
             start_barrier.wait();
 
-            if sig_ok {
+            if let Some(vcpu) = vcpu {
                 'vcpu_loop: loop {
                     let mut interrupted_by_signal = false;
                     match vcpu.run() {