diff --git a/hypervisor/src/kvm/aarch64/gic/redist_regs.rs b/hypervisor/src/kvm/aarch64/gic/redist_regs.rs index b33ab8768..afc3ef859 100644 --- a/hypervisor/src/kvm/aarch64/gic/redist_regs.rs +++ b/hypervisor/src/kvm/aarch64/gic/redist_regs.rs @@ -4,6 +4,7 @@ use crate::arch::aarch64::gic::{Error, Result}; use crate::kvm::kvm_bindings::{kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS}; +use crate::kvm::VcpuKvmState; use crate::{CpuState, Device}; use std::sync::Arc; @@ -190,6 +191,7 @@ pub fn construct_gicr_typers(vcpu_states: &[CpuState]) -> Vec { */ let mut gicr_typers: Vec = Vec::new(); for (index, state) in vcpu_states.iter().enumerate() { + let state: VcpuKvmState = state.clone().into(); let last = { if index == vcpu_states.len() - 1 { 1 diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 3923af3f8..a90b82017 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -13,7 +13,7 @@ use crate::aarch64::gic::KvmGicV3Its; #[cfg(target_arch = "aarch64")] pub use crate::aarch64::{ check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuInit, - VcpuKvmState as CpuState, MPIDR_EL1, + VcpuKvmState, MPIDR_EL1, }; #[cfg(target_arch = "aarch64")] use crate::arch::aarch64::gic::Vgic; @@ -49,7 +49,7 @@ pub mod x86_64; #[cfg(target_arch = "x86_64")] use crate::arch::x86::NUM_IOAPIC_PINS; use crate::{ - IoEventAddress, MpState, UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, + CpuState, IoEventAddress, MpState, UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, }; #[cfg(target_arch = "aarch64")] @@ -63,8 +63,8 @@ use kvm_bindings::{ use x86_64::{check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters}; #[cfg(target_arch = "x86_64")] pub use x86_64::{ - CpuId, CpuIdEntry, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState as CpuState, - Xsave, CPUID_FLAG_VALID_INDEX, + CpuId, CpuIdEntry, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState, Xsave, + CPUID_FLAG_VALID_INDEX, }; // aarch64 dependencies #[cfg(target_arch = "aarch64")] @@ -246,6 +246,23 @@ impl From for kvm_ioctls::IoEventAddress { } } +impl From for CpuState { + fn from(s: VcpuKvmState) -> Self { + CpuState::Kvm(s) + } +} + +impl From for VcpuKvmState { + fn from(s: CpuState) -> Self { + match s { + CpuState::Kvm(s) => s, + /* Needed in case other hypervisors are enabled */ + #[allow(unreachable_patterns)] + _ => panic!("CpuState is not valid"), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct KvmVmState {} @@ -1826,7 +1843,7 @@ impl cpu::Vcpu for KvmVcpu { let vcpu_events = self.get_vcpu_events()?; - Ok(CpuState { + Ok(VcpuKvmState { cpuid, msrs, vcpu_events, @@ -1837,14 +1854,15 @@ impl cpu::Vcpu for KvmVcpu { xsave, xcrs, mp_state, - }) + } + .into()) } /// /// Get the current AArch64 CPU state /// #[cfg(target_arch = "aarch64")] fn state(&self) -> cpu::Result { - let mut state = CpuState { + let mut state = VcpuKvmState { mp_state: self.get_mp_state()?.into(), mpidr: self.read_mpidr()?, ..Default::default() @@ -1852,7 +1870,7 @@ impl cpu::Vcpu for KvmVcpu { state.core_regs = self.get_regs()?; state.sys_regs = self.get_sys_regs()?; - Ok(state) + Ok(state.into()) } #[cfg(target_arch = "x86_64")] /// @@ -1895,6 +1913,7 @@ impl cpu::Vcpu for KvmVcpu { /// vcpu.set_state(&state).unwrap(); /// ``` fn set_state(&self, state: &CpuState) -> cpu::Result<()> { + let state: VcpuKvmState = state.clone().into(); self.set_cpuid2(&state.cpuid)?; self.set_mp_state(state.mp_state.into())?; self.set_regs(&state.regs)?; @@ -1943,6 +1962,7 @@ impl cpu::Vcpu for KvmVcpu { /// #[cfg(target_arch = "aarch64")] fn set_state(&self, state: &CpuState) -> cpu::Result<()> { + let state: VcpuKvmState = state.clone().into(); self.set_regs(&state.core_regs)?; self.set_sys_regs(&state.sys_regs)?; self.set_mp_state(state.mp_state.into())?; diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index b2732e1e1..a30b5d3cf 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -59,12 +59,12 @@ pub use kvm::x86_64; pub use kvm::{aarch64, GicState}; // Aliased types exposed from both hypervisors #[cfg(feature = "kvm")] -pub use kvm::{ClockData, CpuState, CreateDevice, DeviceAttr, DeviceFd, IrqRoutingEntry, VmState}; +pub use kvm::{ClockData, CreateDevice, DeviceAttr, DeviceFd, IrqRoutingEntry, VmState}; #[cfg(all(feature = "mshv", target_arch = "x86_64"))] pub use mshv::x86_64; // Aliased types exposed from both hypervisors #[cfg(all(feature = "mshv", target_arch = "x86_64"))] -pub use mshv::{CpuState, CreateDevice, DeviceAttr, DeviceFd, IrqRoutingEntry, VmState}; +pub use mshv::{CreateDevice, DeviceAttr, DeviceFd, IrqRoutingEntry, VmState}; use std::sync::Arc; pub use vm::{ DataMatch, HypervisorVmError, InterruptSourceConfig, LegacyIrqSourceConfig, MsiIrqSourceConfig, @@ -144,3 +144,11 @@ pub enum IoEventAddress { Pio(u64), Mmio(u64), } + +#[derive(Clone, serde::Serialize, serde::Deserialize)] +pub enum CpuState { + #[cfg(feature = "kvm")] + Kvm(kvm::VcpuKvmState), + #[cfg(all(feature = "mshv", target_arch = "x86_64"))] + Mshv(mshv::VcpuMshvState), +} diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 8571a9813..dcbeb724c 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -24,12 +24,12 @@ use vm::DataMatch; pub mod x86_64; use crate::device; use crate::{ - IoEventAddress, MpState, UserMemoryRegion, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, - USER_MEMORY_REGION_WRITE, + CpuState, IoEventAddress, MpState, UserMemoryRegion, USER_MEMORY_REGION_EXECUTE, + USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, }; use vmm_sys_util::eventfd::EventFd; #[cfg(target_arch = "x86_64")] -pub use x86_64::VcpuMshvState as CpuState; +pub use x86_64::VcpuMshvState; #[cfg(target_arch = "x86_64")] pub use x86_64::*; @@ -115,6 +115,23 @@ impl From for mshv_ioctls::IoEventAddress { } } +impl From for CpuState { + fn from(s: VcpuMshvState) -> Self { + CpuState::Mshv(s) + } +} + +impl From for VcpuMshvState { + fn from(s: CpuState) -> Self { + match s { + CpuState::Mshv(s) => s, + /* Needed in case other hypervisors are enabled */ + #[allow(unreachable_patterns)] + _ => panic!("CpuState is not valid"), + } + } +} + #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] pub struct HvState { hypercall_page: u64, @@ -593,6 +610,7 @@ impl cpu::Vcpu for MshvVcpu { /// Set CPU state /// fn set_state(&self, state: &CpuState) -> cpu::Result<()> { + let state: VcpuMshvState = state.clone().into(); self.set_msrs(&state.msrs)?; self.set_vcpu_events(&state.vcpu_events)?; self.set_regs(&state.regs)?; @@ -635,7 +653,7 @@ impl cpu::Vcpu for MshvVcpu { .get_debug_regs() .map_err(|e| cpu::HypervisorCpuError::GetDebugRegs(e.into()))?; - Ok(CpuState { + Ok(VcpuMshvState { msrs, vcpu_events, regs, @@ -646,7 +664,8 @@ impl cpu::Vcpu for MshvVcpu { dbg, xsave, misc, - }) + } + .into()) } #[cfg(target_arch = "x86_64")] ///