summary refs log tree commit diff
path: root/kvm
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2018-02-22 11:35:05 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-26 22:07:11 -0800
commit42d194de3f8211746c9d37f3ee4e35a4fffaac48 (patch)
tree03384b2836d8bf43487a56e74f50b83a4319a425 /kvm
parentb7bb00297ca394edc7255b78552cfbe326c5f991 (diff)
downloadcrosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar.gz
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar.bz2
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar.lz
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar.xz
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.tar.zst
crosvm-42d194de3f8211746c9d37f3ee4e35a4fffaac48.zip
kvm: plumb in KVM_SET_SIGNAL_MASK ioctl
We need this ioctl to implement race-free support for kicking/pausing VCPUs.

TEST=cargo test --features plugin; cargo test -p kvm; ./build_test
BUG=chromium:800626

Change-Id: I5dcff54f7eb34568a8d8503e0dde86b6a36ac693
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/932443
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'kvm')
-rw-r--r--kvm/src/lib.rs36
1 files changed, 35 insertions, 1 deletions
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs
index 7eb290e..d1488d6 100644
--- a/kvm/src/lib.rs
+++ b/kvm/src/lib.rs
@@ -19,10 +19,12 @@ use std::os::raw::*;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 
 use libc::{open, O_RDWR, O_CLOEXEC, EINVAL, ENOSPC, ENOENT};
+use libc::sigset_t;
 
 use kvm_sys::*;
 
-use sys_util::{GuestAddress, GuestMemory, MemoryMapping, EventFd, Error, Result, pagesize};
+use sys_util::{GuestAddress, GuestMemory, MemoryMapping, EventFd,
+               signal, Error, Result, pagesize};
 #[allow(unused_imports)]
 use sys_util::{ioctl, ioctl_with_val, ioctl_with_ref, ioctl_with_mut_ref, ioctl_with_ptr,
                ioctl_with_mut_ptr};
@@ -939,6 +941,38 @@ impl Vcpu {
         }
         Ok(())
     }
+
+    /// Specifies set of signals that are blocked during execution of KVM_RUN.
+    /// Signals that are not blocked will will cause KVM_RUN to return
+    /// with -EINTR.
+    ///
+    /// See the documentation for KVM_SET_SIGNAL_MASK
+    pub fn set_signal_mask(&self, signals: &[c_int]) -> Result<()> {
+        let sigset = signal::create_sigset(signals)?;
+
+        let vec_size_bytes = size_of::<kvm_signal_mask>() + size_of::<sigset_t>();
+        let vec: Vec<u8> = vec![0; vec_size_bytes];
+        let kvm_sigmask: &mut kvm_signal_mask = unsafe {
+            // Converting the vector's memory to a struct is unsafe.
+            // Carefully using the read-only vector to size and set the members
+            // ensures no out-of-bounds errors below.
+            &mut *(vec.as_ptr() as *mut kvm_signal_mask)
+        };
+        kvm_sigmask.len = size_of::<sigset_t>() as u32;
+        unsafe {
+            std::ptr::copy(&sigset, kvm_sigmask.sigset.as_mut_ptr() as *mut sigset_t, 1);
+        }
+
+        let ret = unsafe {
+            // The ioctl is safe because the kernel will only read from the
+            // kvm_signal_mask structure.
+            ioctl_with_ref(self, KVM_SET_SIGNAL_MASK(), kvm_sigmask)
+        };
+        if ret < 0 {
+            return errno_result();
+        }
+        Ok(())
+    }
 }
 
 impl AsRawFd for Vcpu {