summary refs log tree commit diff
path: root/src/plugin/vcpu.rs
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2018-02-13 15:53:18 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-16 15:12:24 -0800
commit0db8f412452ac12353d4a81a71968f84ae58c1c1 (patch)
tree05b6a3128fa0b7edb7c7c7e6dbbadf2e2b19d934 /src/plugin/vcpu.rs
parentee0d67cc5ef36f278d5a0926d491498f125c0afa (diff)
downloadcrosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar.gz
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar.bz2
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar.lz
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar.xz
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.tar.zst
crosvm-0db8f412452ac12353d4a81a71968f84ae58c1c1.zip
Ensure we are not holding per-cpu data lock when pausing VCPU
We may want to issue additional crosvm_pause_vcpu() requests while VCPUs
are waiting to be resumed, so we need to make sure we are not holding
lock while waiting.

TEST=cargo test --features plugin
BUG=chromium:800626

Change-Id: Ia74836a567fc565fbd868abdcaa6d0174a4341ad
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/917426
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/plugin/vcpu.rs')
-rw-r--r--src/plugin/vcpu.rs22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/plugin/vcpu.rs b/src/plugin/vcpu.rs
index ea830bf..e175d8a 100644
--- a/src/plugin/vcpu.rs
+++ b/src/plugin/vcpu.rs
@@ -284,18 +284,18 @@ impl PluginVcpu {
     /// The VCPU thread should call this before rerunning a VM in order to handle pending requests
     /// to this VCPU.
     pub fn pre_run(&self, vcpu: &Vcpu) -> SysResult<()> {
-        match self.per_vcpu_state.lock() {
-            Ok(mut per_vcpu_state) => {
-                if let Some(user) = per_vcpu_state.pause_request.take() {
-                    let mut wait_reason = VcpuResponse_Wait::new();
-                    wait_reason.mut_user().user = user;
-                    self.wait_reason.set(Some(wait_reason));
-                    self.handle_until_resume(vcpu)?;
-                }
-                Ok(())
-            }
-            Err(_) => Err(SysError::new(-EDEADLK)),
+        let request = {
+            let mut lock = self.per_vcpu_state.lock().map_err(|_| SysError::new(-EDEADLK))?;
+            lock.pause_request.take()
+        };
+
+        if let Some(user_data) = request {
+            let mut wait_reason = VcpuResponse_Wait::new();
+            wait_reason.mut_user().user = user_data;
+            self.wait_reason.set(Some(wait_reason));
+            self.handle_until_resume(vcpu)?;
         }
+        Ok(())
     }
 
     fn process(&self, io_space: IoSpace, addr: u64, mut data: VcpuRunData, vcpu: &Vcpu) -> bool {