mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-07-04 17:02:36 +00:00
vmm: Implement VM rebooting on AArch64
The logic to handle AArch64 system event was: SHUTDOWN and RESET were all treated as RESET. Now we handle them differently: - RESET event will trigger Vmm::vm_reboot(), - SHUTDOWN event will trigger Vmm::vm_shutdown(). Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
69394c9c35
commit
093a581ee1
|
@ -194,6 +194,7 @@ pub enum VmExit<'a> {
|
||||||
MmioWrite(u64 /* address */, &'a [u8]),
|
MmioWrite(u64 /* address */, &'a [u8]),
|
||||||
Ignore,
|
Ignore,
|
||||||
Reset,
|
Reset,
|
||||||
|
Shutdown,
|
||||||
Hyperv,
|
Hyperv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -738,10 +738,10 @@ impl cpu::Vcpu for KvmVcpu {
|
||||||
use kvm_bindings::{KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN};
|
use kvm_bindings::{KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN};
|
||||||
// On Aarch64, when the VM is shutdown, run() returns
|
// On Aarch64, when the VM is shutdown, run() returns
|
||||||
// VcpuExit::SystemEvent with reason KVM_SYSTEM_EVENT_SHUTDOWN
|
// VcpuExit::SystemEvent with reason KVM_SYSTEM_EVENT_SHUTDOWN
|
||||||
if event_type == KVM_SYSTEM_EVENT_SHUTDOWN
|
if event_type == KVM_SYSTEM_EVENT_RESET {
|
||||||
|| event_type == KVM_SYSTEM_EVENT_RESET
|
|
||||||
{
|
|
||||||
Ok(cpu::VmExit::Reset)
|
Ok(cpu::VmExit::Reset)
|
||||||
|
} else if event_type == KVM_SYSTEM_EVENT_SHUTDOWN {
|
||||||
|
Ok(cpu::VmExit::Shutdown)
|
||||||
} else {
|
} else {
|
||||||
Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
|
Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
|
||||||
"Unexpected system event with type 0x{:x}, flags 0x{:x}",
|
"Unexpected system event with type 0x{:x}, flags 0x{:x}",
|
||||||
|
|
|
@ -398,6 +398,7 @@ pub struct CpuManager {
|
||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
vcpus_kill_signalled: Arc<AtomicBool>,
|
vcpus_kill_signalled: Arc<AtomicBool>,
|
||||||
vcpus_pause_signalled: Arc<AtomicBool>,
|
vcpus_pause_signalled: Arc<AtomicBool>,
|
||||||
|
exit_evt: EventFd,
|
||||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
vcpu_states: Vec<VcpuState>,
|
vcpu_states: Vec<VcpuState>,
|
||||||
|
@ -523,11 +524,13 @@ impl VcpuState {
|
||||||
|
|
||||||
impl CpuManager {
|
impl CpuManager {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: &CpusConfig,
|
config: &CpusConfig,
|
||||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
|
exit_evt: EventFd,
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
seccomp_action: SeccompAction,
|
seccomp_action: SeccompAction,
|
||||||
|
@ -557,6 +560,7 @@ impl CpuManager {
|
||||||
vcpus_kill_signalled: Arc::new(AtomicBool::new(false)),
|
vcpus_kill_signalled: Arc::new(AtomicBool::new(false)),
|
||||||
vcpus_pause_signalled: Arc::new(AtomicBool::new(false)),
|
vcpus_pause_signalled: Arc::new(AtomicBool::new(false)),
|
||||||
vcpu_states,
|
vcpu_states,
|
||||||
|
exit_evt,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
selected_cpu: 0,
|
selected_cpu: 0,
|
||||||
vcpus: Vec::with_capacity(usize::from(config.max_vcpus)),
|
vcpus: Vec::with_capacity(usize::from(config.max_vcpus)),
|
||||||
|
@ -723,6 +727,7 @@ impl CpuManager {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
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 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();
|
||||||
|
|
||||||
|
@ -810,6 +815,12 @@ impl CpuManager {
|
||||||
reset_evt.write(1).unwrap();
|
reset_evt.write(1).unwrap();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
VmExit::Shutdown => {
|
||||||
|
debug!("VmExit::Shutdown");
|
||||||
|
vcpu_run_interrupted.store(true, Ordering::SeqCst);
|
||||||
|
exit_evt.write(1).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("VCPU generated error: {:?}", Error::UnexpectedVmExit);
|
error!("VCPU generated error: {:?}", Error::UnexpectedVmExit);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -432,7 +432,8 @@ impl Vmm {
|
||||||
|
|
||||||
fn vm_reboot(&mut self) -> result::Result<(), VmError> {
|
fn vm_reboot(&mut self) -> result::Result<(), VmError> {
|
||||||
// Without ACPI, a reset is equivalent to a shutdown
|
// Without ACPI, a reset is equivalent to a shutdown
|
||||||
#[cfg(not(feature = "acpi"))]
|
// On AArch64, before ACPI is supported, we simply jump over this check and continue to reset.
|
||||||
|
#[cfg(all(target_arch = "x86_64", not(feature = "acpi")))]
|
||||||
{
|
{
|
||||||
if self.vm.is_some() {
|
if self.vm.is_some() {
|
||||||
self.exit_evt.write(1).unwrap();
|
self.exit_evt.write(1).unwrap();
|
||||||
|
|
|
@ -512,11 +512,13 @@ impl Vm {
|
||||||
});
|
});
|
||||||
vm.set_vmmops(vm_ops).map_err(Error::SetVmmOpsInterface)?;
|
vm.set_vmmops(vm_ops).map_err(Error::SetVmmOpsInterface)?;
|
||||||
|
|
||||||
|
let exit_evt_clone = exit_evt.try_clone().map_err(Error::EventFdClone)?;
|
||||||
let cpu_manager = cpu::CpuManager::new(
|
let cpu_manager = cpu::CpuManager::new(
|
||||||
&config.lock().unwrap().cpus.clone(),
|
&config.lock().unwrap().cpus.clone(),
|
||||||
&device_manager,
|
&device_manager,
|
||||||
&memory_manager,
|
&memory_manager,
|
||||||
vm.clone(),
|
vm.clone(),
|
||||||
|
exit_evt_clone,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
hypervisor,
|
hypervisor,
|
||||||
seccomp_action.clone(),
|
seccomp_action.clone(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user