vmm: cpu: Shutdown VMM on vCPU thread panic

If the vCPU thread panics then catch it and trigger the shutdown of the
VMM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-08-12 15:39:43 +01:00 committed by Sebastien Boeuf
parent ea5a050341
commit 9d35a10fd4

View File

@ -700,6 +700,7 @@ impl CpuManager {
let cpu_id = vcpu.lock().unwrap().id; let cpu_id = vcpu.lock().unwrap().id;
let reset_evt = self.reset_evt.try_clone().unwrap(); let reset_evt = self.reset_evt.try_clone().unwrap();
let exit_evt = self.exit_evt.try_clone().unwrap(); let exit_evt = self.exit_evt.try_clone().unwrap();
let panic_exit_evt = self.exit_evt.try_clone().unwrap();
let vcpu_kill_signalled = self.vcpus_kill_signalled.clone(); let vcpu_kill_signalled = self.vcpus_kill_signalled.clone();
let vcpu_pause_signalled = self.vcpus_pause_signalled.clone(); let vcpu_pause_signalled = self.vcpus_pause_signalled.clone();
@ -707,6 +708,7 @@ impl CpuManager {
let vcpu_run_interrupted = self.vcpu_states[usize::from(cpu_id)] let vcpu_run_interrupted = self.vcpu_states[usize::from(cpu_id)]
.vcpu_run_interrupted .vcpu_run_interrupted
.clone(); .clone();
let panic_vcpu_run_interrupted = vcpu_run_interrupted.clone();
info!("Starting vCPU: cpu_id = {}", cpu_id); info!("Starting vCPU: cpu_id = {}", cpu_id);
@ -728,15 +730,14 @@ impl CpuManager {
error!("Error applying seccomp filter: {:?}", e); error!("Error applying seccomp filter: {:?}", e);
return; return;
} }
extern "C" fn handle_signal(_: i32, _: *mut siginfo_t, _: *mut c_void) {} extern "C" fn handle_signal(_: i32, _: *mut siginfo_t, _: *mut c_void) {}
// This uses an async signal safe handler to kill the vcpu handles. // This uses an async signal safe handler to kill the vcpu handles.
register_signal_handler(SIGRTMIN(), handle_signal) register_signal_handler(SIGRTMIN(), handle_signal)
.expect("Failed to register vcpu signal handler"); .expect("Failed to register vcpu signal handler");
// Block until all CPUs are ready. // Block until all CPUs are ready.
vcpu_thread_barrier.wait(); vcpu_thread_barrier.wait();
std::panic::catch_unwind(move || {
loop { loop {
// If we are being told to pause, we park the thread // If we are being told to pause, we park the thread
// until the pause boolean is toggled. // until the pause boolean is toggled.
@ -771,7 +772,8 @@ impl CpuManager {
Ok(run) => match run { Ok(run) => match run {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
VmExit::IoapicEoi(vector) => { VmExit::IoapicEoi(vector) => {
if let Some(interrupt_controller) = &interrupt_controller_clone if let Some(interrupt_controller) =
&interrupt_controller_clone
{ {
interrupt_controller interrupt_controller
.lock() .lock()
@ -794,7 +796,10 @@ impl CpuManager {
break; break;
} }
_ => { _ => {
error!("VCPU generated error: {:?}", Error::UnexpectedVmExit); error!(
"VCPU generated error: {:?}",
Error::UnexpectedVmExit
);
break; break;
} }
}, },
@ -814,6 +819,13 @@ impl CpuManager {
} }
} }
}) })
.or_else(|_| {
panic_vcpu_run_interrupted.store(true, Ordering::SeqCst);
error!("vCPU thread panicked");
panic_exit_evt.write(1)
})
.ok();
})
.map_err(Error::VcpuSpawn)?, .map_err(Error::VcpuSpawn)?,
); );