hypervisor: provide a generic CpuState structure

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2022-07-14 15:20:21 +00:00 committed by Liu Wei
parent dd592e86fd
commit 72d552e5e1
4 changed files with 64 additions and 15 deletions

View File

@ -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<u64> {
*/
let mut gicr_typers: Vec<u64> = 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

View File

@ -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<IoEventAddress> for kvm_ioctls::IoEventAddress {
}
}
impl From<VcpuKvmState> for CpuState {
fn from(s: VcpuKvmState) -> Self {
CpuState::Kvm(s)
}
}
impl From<CpuState> 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<CpuState> {
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())?;

View File

@ -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),
}

View File

@ -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<IoEventAddress> for mshv_ioctls::IoEventAddress {
}
}
impl From<VcpuMshvState> for CpuState {
fn from(s: VcpuMshvState) -> Self {
CpuState::Mshv(s)
}
}
impl From<CpuState> 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")]
///