From 69394c9c35dbec2a03dba8e290b54028ece198c0 Mon Sep 17 00:00:00 2001 From: Michael Zhao Date: Fri, 30 Oct 2020 21:01:53 +0800 Subject: [PATCH] vmm: Handle hypervisor VCPU run result from Vcpu to VcpuManager Now Vcpu::run() returns a boolean value to VcpuManager, indicating whether the VM is going to reboot (false) or just continue (true). Moving the handling of hypervisor VCPU run result from Vcpu to VcpuManager gives us the flexibility to handle more scenarios like shutting down on AArch64. Signed-off-by: Michael Zhao --- vmm/src/cpu.rs | 84 +++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index df0f9257e..332988e3f 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -34,7 +34,7 @@ use devices::interrupt_controller::InterruptController; use hypervisor::kvm::kvm_bindings; #[cfg(target_arch = "x86_64")] use hypervisor::CpuId; -use hypervisor::{CpuState, VmExit}; +use hypervisor::{CpuState, HypervisorCpuError, VmExit}; use seccomp::{SeccompAction, SeccompFilter}; use libc::{c_void, siginfo_t}; @@ -213,8 +213,6 @@ pub struct Vcpu { // The hypervisor abstracted CPU. vcpu: Arc, id: u8, - #[cfg_attr(target_arch = "aarch64", allow(dead_code))] - interrupt_controller: Option>>, #[cfg(target_arch = "aarch64")] mpidr: u64, saved_state: Option, @@ -227,11 +225,7 @@ impl Vcpu { /// /// * `id` - Represents the CPU number between [0, max vcpus). /// * `vm` - The virtual machine this vcpu will get attached to. - pub fn new( - id: u8, - vm: &Arc, - interrupt_controller: Option>>, - ) -> Result>> { + pub fn new(id: u8, vm: &Arc) -> Result>> { let vcpu = vm .create_vcpu(id) .map_err(|e| Error::VcpuCreate(e.into()))?; @@ -239,7 +233,6 @@ impl Vcpu { Ok(Arc::new(Mutex::new(Vcpu { vcpu, id, - interrupt_controller, #[cfg(target_arch = "aarch64")] mpidr: 0, saved_state: None, @@ -323,28 +316,8 @@ impl Vcpu { /// /// Note that the state of the VCPU and associated VM must be setup first for this to do /// anything useful. - pub fn run(&self) -> Result { - match self.vcpu.run() { - Ok(run) => match run { - #[cfg(target_arch = "x86_64")] - VmExit::IoapicEoi(vector) => { - if let Some(interrupt_controller) = &self.interrupt_controller { - interrupt_controller - .lock() - .unwrap() - .end_of_interrupt(vector); - } - Ok(true) - } - VmExit::Ignore => Ok(true), - VmExit::Reset => Ok(false), - // No need to handle anything from a KVM HyperV exit - VmExit::Hyperv => Ok(true), - _ => Err(Error::UnexpectedVmExit), - }, - - Err(e) => Err(Error::VcpuRun(e.into())), - } + pub fn run(&self) -> std::result::Result { + self.vcpu.run() } } @@ -679,13 +652,7 @@ impl CpuManager { ) -> Result>> { info!("Creating vCPU: cpu_id = {}", cpu_id); - let interrupt_controller = if let Some(interrupt_controller) = &self.interrupt_controller { - Some(interrupt_controller.clone()) - } else { - None - }; - - let vcpu = Vcpu::new(cpu_id, &self.vm, interrupt_controller)?; + let vcpu = Vcpu::new(cpu_id, &self.vm)?; if let Some(snapshot) = snapshot { // AArch64 vCPUs should be initialized after created. @@ -770,6 +737,14 @@ impl CpuManager { let vcpu_seccomp_filter = get_seccomp_filter(&self.seccomp_action, Thread::Vcpu) .map_err(Error::CreateSeccompFilter)?; + #[cfg(target_arch = "x86_64")] + let interrupt_controller_clone = + if let Some(interrupt_controller) = &self.interrupt_controller { + Some(interrupt_controller.clone()) + } else { + None + }; + let handle = Some( thread::Builder::new() .name(format!("vcpu{}", cpu_id)) @@ -816,14 +791,33 @@ impl CpuManager { // vcpu.run() returns false on a triple-fault so trigger a reset match vcpu.lock().unwrap().run() { + Ok(run) => match run { + #[cfg(target_arch = "x86_64")] + VmExit::IoapicEoi(vector) => { + if let Some(interrupt_controller) = &interrupt_controller_clone + { + interrupt_controller + .lock() + .unwrap() + .end_of_interrupt(vector); + } + } + VmExit::Ignore => {} + VmExit::Hyperv => {} + VmExit::Reset => { + debug!("VmExit::Reset"); + vcpu_run_interrupted.store(true, Ordering::SeqCst); + reset_evt.write(1).unwrap(); + break; + } + _ => { + error!("VCPU generated error: {:?}", Error::UnexpectedVmExit); + break; + } + }, + Err(e) => { - error!("VCPU generated error: {:?}", e); - break; - } - Ok(true) => {} - Ok(false) => { - vcpu_run_interrupted.store(true, Ordering::SeqCst); - reset_evt.write(1).unwrap(); + error!("VCPU generated error: {:?}", Error::VcpuRun(e.into())); break; } }