hypervisor: provide a generic MpState structure

It is however only used for KVM right now because MSHV does not need it
yet.

Nonetheless a stub MSHV constructor should be there and get/set
functions should be implemented for MSHV.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2022-07-14 15:17:07 +00:00 committed by Liu Wei
parent 02866fccb0
commit 9810ed4496
5 changed files with 56 additions and 21 deletions

View File

@ -27,7 +27,6 @@ use crate::x86_64::{
use crate::CpuState;
#[cfg(target_arch = "aarch64")]
use crate::DeviceAttr;
#[cfg(feature = "kvm")]
use crate::MpState;
use thiserror::Error;
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
@ -351,12 +350,10 @@ pub trait Vcpu: Send + Sync {
/// Setup the model-specific registers (MSR) for this vCPU.
///
fn set_msrs(&self, msrs: &MsrEntries) -> Result<usize>;
#[cfg(feature = "kvm")]
///
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> Result<MpState>;
#[cfg(feature = "kvm")]
///
/// Sets the vcpu's current "multiprocessing state".
///

View File

@ -49,7 +49,7 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")]
use crate::arch::x86::NUM_IOAPIC_PINS;
use crate::{
UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ,
MpState, UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ,
USER_MEMORY_REGION_WRITE,
};
#[cfg(target_arch = "aarch64")]
@ -74,7 +74,7 @@ pub use kvm_bindings;
use kvm_bindings::KVMIO;
pub use kvm_bindings::{
kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO, kvm_irq_routing, kvm_irq_routing_entry,
kvm_userspace_memory_region, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
kvm_mp_state, kvm_userspace_memory_region, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_READONLY, KVM_MSI_VALID_DEVID,
};
#[cfg(target_arch = "aarch64")]
@ -95,9 +95,9 @@ use vmm_sys_util::{ioctl::ioctl_with_val, ioctl_expr, ioctl_ioc_nr, ioctl_iowr_n
pub use {
kvm_bindings::kvm_clock_data as ClockData, kvm_bindings::kvm_create_device as CreateDevice,
kvm_bindings::kvm_device_attr as DeviceAttr,
kvm_bindings::kvm_irq_routing_entry as IrqRoutingEntry, kvm_bindings::kvm_mp_state as MpState,
kvm_bindings::kvm_run, kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_ioctls::DeviceFd,
kvm_ioctls::IoEventAddress, kvm_ioctls::VcpuExit,
kvm_bindings::kvm_irq_routing_entry as IrqRoutingEntry, kvm_bindings::kvm_run,
kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_ioctls::DeviceFd, kvm_ioctls::IoEventAddress,
kvm_ioctls::VcpuExit,
};
#[cfg(target_arch = "x86_64")]
@ -212,6 +212,23 @@ impl From<UserMemoryRegion> for kvm_userspace_memory_region {
}
}
impl From<kvm_mp_state> for MpState {
fn from(s: kvm_mp_state) -> Self {
MpState::Kvm(s)
}
}
impl From<MpState> for kvm_mp_state {
fn from(ms: MpState) -> Self {
match ms {
MpState::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 {}
@ -1302,16 +1319,18 @@ impl cpu::Vcpu for KvmVcpu {
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> cpu::Result<MpState> {
self.fd
Ok(self
.fd
.get_mp_state()
.map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))
.map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))?
.into())
}
///
/// Sets the vcpu's current "multiprocessing state".
///
fn set_mp_state(&self, mp_state: MpState) -> cpu::Result<()> {
self.fd
.set_mp_state(mp_state)
.set_mp_state(mp_state.into())
.map_err(|e| cpu::HypervisorCpuError::SetMpState(e.into()))
}
#[cfg(target_arch = "x86_64")]
@ -1710,7 +1729,7 @@ impl cpu::Vcpu for KvmVcpu {
/// ```
fn state(&self) -> cpu::Result<CpuState> {
let cpuid = self.get_cpuid2(kvm_bindings::KVM_MAX_CPUID_ENTRIES)?;
let mp_state = self.get_mp_state()?;
let mp_state = self.get_mp_state()?.into();
let regs = self.get_regs()?;
let sregs = self.get_sregs()?;
let xsave = self.get_xsave()?;
@ -1807,7 +1826,7 @@ impl cpu::Vcpu for KvmVcpu {
#[cfg(target_arch = "aarch64")]
fn state(&self) -> cpu::Result<CpuState> {
let mut state = CpuState {
mp_state: self.get_mp_state()?,
mp_state: self.get_mp_state()?.into(),
mpidr: self.read_mpidr()?,
..Default::default()
};
@ -1858,7 +1877,7 @@ impl cpu::Vcpu for KvmVcpu {
/// ```
fn set_state(&self, state: &CpuState) -> cpu::Result<()> {
self.set_cpuid2(&state.cpuid)?;
self.set_mp_state(state.mp_state)?;
self.set_mp_state(state.mp_state.into())?;
self.set_regs(&state.regs)?;
self.set_sregs(&state.sregs)?;
self.set_xsave(&state.xsave)?;
@ -1907,7 +1926,7 @@ impl cpu::Vcpu for KvmVcpu {
fn set_state(&self, state: &CpuState) -> cpu::Result<()> {
self.set_regs(&state.core_regs)?;
self.set_sys_regs(&state.sys_regs)?;
self.set_mp_state(state.mp_state)?;
self.set_mp_state(state.mp_state.into())?;
Ok(())
}

View File

@ -61,15 +61,15 @@ pub use kvm::{aarch64, GicState};
#[cfg(feature = "kvm")]
pub use kvm::{
ClockData, CpuState, CreateDevice, DeviceAttr, DeviceFd, IoEventAddress, IrqRoutingEntry,
MpState, VcpuEvents, VmState,
VcpuEvents, 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, IoEventAddress, IrqRoutingEntry, MpState,
VcpuEvents, VmState,
CpuState, CreateDevice, DeviceAttr, DeviceFd, IoEventAddress, IrqRoutingEntry, VcpuEvents,
VmState,
};
use std::sync::Arc;
pub use vm::{
@ -136,3 +136,11 @@ pub const USER_MEMORY_REGION_READ: u32 = 1;
pub const USER_MEMORY_REGION_WRITE: u32 = 1 << 1;
pub const USER_MEMORY_REGION_EXECUTE: u32 = 1 << 2;
pub const USER_MEMORY_REGION_LOG_DIRTY: u32 = 1 << 3;
#[derive(Debug)]
pub enum MpState {
#[cfg(feature = "kvm")]
Kvm(kvm_bindings::kvm_mp_state),
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
Mshv, /* MSHV does not supprt MpState yet */
}

View File

@ -25,7 +25,8 @@ use vm::DataMatch;
pub mod x86_64;
use crate::device;
use crate::{
UserMemoryRegion, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
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")]
@ -541,6 +542,18 @@ impl cpu::Vcpu for MshvVcpu {
.set_lapic(lapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
}
///
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> cpu::Result<MpState> {
Ok(MpState::Mshv)
}
///
/// Sets the vcpu's current "multiprocessing state".
///
fn set_mp_state(&self, _mp_state: MpState) -> cpu::Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xsave struct".

View File

@ -66,8 +66,6 @@ impl fmt::Display for VcpuMshvState {
}
}
pub struct MpState {}
impl SegmentRegisterOps for SegmentRegister {
fn segment_type(&self) -> u8 {
self.type_