diff options
-rw-r--r-- | src/plugin/mod.rs | 18 | ||||
-rw-r--r-- | tests/plugin_vcpu_pause.c | 15 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 853b7e5..4528df8 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -26,7 +26,7 @@ use io_jail::{self, Minijail}; use kvm::{Kvm, Vm, Vcpu, VcpuExit, IoeventAddress, NoDatamatch}; use sys_util::{EventFd, MmapError, Killable, SignalFd, SignalFdError, Poller, Pollable, GuestMemory, Result as SysResult, Error as SysError, - register_signal_handler, SIGRTMIN, + register_signal_handler, block_signal, clear_signal, SIGRTMIN, geteuid, getegid}; use Config; @@ -307,10 +307,21 @@ pub fn run_vcpus(kvm: &Kvm, unsafe { extern "C" fn handle_signal() {} // Our signal handler does nothing and is trivially async signal safe. + // We need to install this signal handler even though we do block + // the signal below, to ensure that this signal will interrupt + // execution of KVM_RUN (this is implementation issue). register_signal_handler(SIGRTMIN() + 0, handle_signal) .expect("failed to register vcpu signal handler"); } + // We do not really want the signal handler to run... + block_signal(SIGRTMIN() + 0) + .expect("failed to block signal"); + // Tell KVM to not block anything when entering kvm run + // because we will be using first RT signal to kick the VCPU. + vcpu.set_signal_mask(&[]) + .expect("failed to set up KVM VCPU signal mask"); + let res = vcpu_plugin.init(&vcpu); vcpu_thread_barrier.wait(); if let Err(e) = res { @@ -356,6 +367,11 @@ pub fn run_vcpus(kvm: &Kvm, break; } + // Try to clear the signal that we use to kick VCPU if it is + // pending before attempting to handle pause requests. + clear_signal(SIGRTMIN() + 0) + .expect("failed to clear pending signal"); + if let Err(e) = vcpu_plugin.pre_run(&vcpu) { error!("failed to process pause on vcpu {}: {:?}", cpu_id, e); break; diff --git a/tests/plugin_vcpu_pause.c b/tests/plugin_vcpu_pause.c index a9a27f8..ff69b04 100644 --- a/tests/plugin_vcpu_pause.c +++ b/tests/plugin_vcpu_pause.c @@ -238,6 +238,21 @@ int main(int argc, char** argv) { return 1; } + signal_unpause(crosvm, false); + + /* Wait until VCPU thread tells us that it is no longer paused */ + read(g_kill_evt, &dummy, sizeof(dummy)); + + /* + * Try pausing VCPUs 3rd time to see if we will miss pause + * request as we are exiting previous pause. + */ + ret = signal_pause(crosvm); + if (ret) { + fprintf(stderr, "failed to pause vcpus (2nd time): %d\n", ret); + return 1; + } + signal_unpause(crosvm, true); /* Wait until VCPU thread tells us that it is no longer paused */ |