From 9810ed4496434d768669e3fea5cf9fcac0033fd7 Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Thu, 14 Jul 2022 15:17:07 +0000 Subject: [PATCH] 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 --- hypervisor/src/cpu.rs | 3 --- hypervisor/src/kvm/mod.rs | 43 ++++++++++++++++++++++--------- hypervisor/src/lib.rs | 14 +++++++--- hypervisor/src/mshv/mod.rs | 15 ++++++++++- hypervisor/src/mshv/x86_64/mod.rs | 2 -- 5 files changed, 56 insertions(+), 21 deletions(-) diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index a7491cdb6..5e22bce0c 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -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; - #[cfg(feature = "kvm")] /// /// Returns the vcpu's current "multiprocessing state". /// fn get_mp_state(&self) -> Result; - #[cfg(feature = "kvm")] /// /// Sets the vcpu's current "multiprocessing state". /// diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 5f518eedb..f4364e4ca 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -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 for kvm_userspace_memory_region { } } +impl From for MpState { + fn from(s: kvm_mp_state) -> Self { + MpState::Kvm(s) + } +} + +impl From 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 { - 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 { 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 { 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(()) } diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index 28f85bda1..534abcc87 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -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 */ +} diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 0f0adfb8e..9e403a8e1 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -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 { + 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". diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index 63f235c2a..978739993 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -66,8 +66,6 @@ impl fmt::Display for VcpuMshvState { } } -pub struct MpState {} - impl SegmentRegisterOps for SegmentRegister { fn segment_type(&self) -> u8 { self.type_