Triggers the running of the current virtual CPU returning an exit reason.
(&mut self)
| 2369 | /// Triggers the running of the current virtual CPU returning an exit reason. |
| 2370 | /// |
| 2371 | fn run(&mut self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> { |
| 2372 | match self.fd.run() { |
| 2373 | Ok(run) => match run { |
| 2374 | #[cfg(target_arch = "x86_64")] |
| 2375 | VcpuExit::IoIn(addr, data) => { |
| 2376 | if let Some(vm_ops) = &self.vm_ops { |
| 2377 | return vm_ops |
| 2378 | .pio_read(addr.into(), data) |
| 2379 | .map(|_| cpu::VmExit::Ignore) |
| 2380 | .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into())); |
| 2381 | } |
| 2382 | |
| 2383 | Ok(cpu::VmExit::Ignore) |
| 2384 | } |
| 2385 | #[cfg(target_arch = "x86_64")] |
| 2386 | VcpuExit::IoOut(addr, data) => { |
| 2387 | if let Some(vm_ops) = &self.vm_ops { |
| 2388 | return vm_ops |
| 2389 | .pio_write(addr.into(), data) |
| 2390 | .map(|_| cpu::VmExit::Ignore) |
| 2391 | .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into())); |
| 2392 | } |
| 2393 | |
| 2394 | Ok(cpu::VmExit::Ignore) |
| 2395 | } |
| 2396 | #[cfg(target_arch = "x86_64")] |
| 2397 | VcpuExit::IoapicEoi(vector) => Ok(cpu::VmExit::IoapicEoi(vector)), |
| 2398 | #[cfg(target_arch = "x86_64")] |
| 2399 | VcpuExit::Shutdown => { |
| 2400 | error!("Guest likely triple-faulted"); |
| 2401 | Ok(cpu::VmExit::Reset) |
| 2402 | } |
| 2403 | // Practically unlikely, as KVM emulates the LAPIC and therefore HLT |
| 2404 | VcpuExit::Hlt => { |
| 2405 | error!("Received a HLT exit but KVM should handle this in kernel space"); |
| 2406 | Ok(cpu::VmExit::Reset) |
| 2407 | } |
| 2408 | |
| 2409 | #[cfg(target_arch = "aarch64")] |
| 2410 | VcpuExit::SystemEvent(event_type, flags) => { |
| 2411 | use kvm_bindings::{KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN}; |
| 2412 | // On Aarch64, when the VM is shutdown, run() returns |
| 2413 | // VcpuExit::SystemEvent with reason KVM_SYSTEM_EVENT_SHUTDOWN |
| 2414 | if event_type == KVM_SYSTEM_EVENT_RESET { |
| 2415 | Ok(cpu::VmExit::Reset) |
| 2416 | } else if event_type == KVM_SYSTEM_EVENT_SHUTDOWN { |
| 2417 | Ok(cpu::VmExit::Shutdown) |
| 2418 | } else { |
| 2419 | Err(cpu::HypervisorCpuError::RunVcpu(anyhow!( |
| 2420 | "Unexpected system event with type 0x{event_type:x}, flags 0x{flags:x?}", |
| 2421 | ))) |
| 2422 | } |
| 2423 | } |
| 2424 | |
| 2425 | VcpuExit::MmioRead(addr, data) => { |
| 2426 | if let Some(vm_ops) = &self.vm_ops { |
| 2427 | return vm_ops |
| 2428 | .mmio_read(addr, data) |
nothing calls this directly
no test coverage detected