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>
This commit is contained in:
Dmitry Torokhov 2018-02-22 11:35:05 -08:00 committed by chrome-bot
parent b7bb00297c
commit 42d194de3f
2 changed files with 36 additions and 2 deletions

View file

@ -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 {

View file

@ -24,7 +24,7 @@ mod poll;
mod struct_util;
mod tempdir;
mod terminal;
mod signal;
pub mod signal;
mod fork;
mod signalfd;
mod sock_ctrl_msg;