diff options
author | Dmitry Torokhov <dtor@chromium.org> | 2018-02-22 11:35:05 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-02-26 22:07:11 -0800 |
commit | 42d194de3f8211746c9d37f3ee4e35a4fffaac48 (patch) | |
tree | 03384b2836d8bf43487a56e74f50b83a4319a425 /kvm | |
parent | b7bb00297ca394edc7255b78552cfbe326c5f991 (diff) | |
download | crosvm-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.rs | 36 |
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 { |