hypervisor: rework VP state components

On Microsoft Hypervisor, we need to save/restore five
VP state components which are as follows:
    1. Local APIC
    2. Xsave
    3. Synthetic Message Page
    4. Synthetic Event Flags Page
    5. Synthetic Timers

In the MSHV crate we created a single struct for all the
components and API to get/set the states.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2024-04-15 14:06:48 -07:00 committed by Bo Chen
parent e7e856d8ac
commit 512591ba1c
3 changed files with 30 additions and 36 deletions

View File

@ -107,14 +107,28 @@ pub enum HypervisorCpuError {
///
/// Setting Saved Processor Extended States error
///
#[cfg(feature = "kvm")]
#[error("Failed to set Saved Processor Extended States: {0}")]
SetXsaveState(#[source] anyhow::Error),
///
/// Getting Saved Processor Extended States error
///
#[cfg(feature = "kvm")]
#[error("Failed to get Saved Processor Extended States: {0}")]
GetXsaveState(#[source] anyhow::Error),
///
/// Getting the VP state components error
///
#[cfg(feature = "mshv")]
#[error("Failed to get VP State Components: {0}")]
GetAllVpStateComponents(#[source] anyhow::Error),
///
/// Setting the VP state components error
///
#[cfg(feature = "mshv")]
#[error("Failed to set VP State Components: {0}")]
SetAllVpStateComponents(#[source] anyhow::Error),
///
/// Setting Extended Control Registers error
///
#[error("Failed to set Extended Control Registers: {0}")]

View File

@ -1280,15 +1280,13 @@ impl cpu::Vcpu for MshvVcpu {
/// Set CPU state for x86_64 guest.
///
fn set_state(&self, state: &CpuState) -> cpu::Result<()> {
let state: VcpuMshvState = state.clone().into();
let mut state: VcpuMshvState = state.clone().into();
self.set_msrs(&state.msrs)?;
self.set_vcpu_events(&state.vcpu_events)?;
self.set_regs(&state.regs.into())?;
self.set_sregs(&state.sregs.into())?;
self.set_fpu(&state.fpu)?;
self.set_xcrs(&state.xcrs)?;
self.set_lapic(&state.lapic)?;
self.set_xsave(&state.xsave)?;
// These registers are global and needed to be set only for first VCPU
// as Microsoft Hypervisor allows setting this regsier for only one VCPU
if self.vp_index == 0 {
@ -1299,6 +1297,9 @@ impl cpu::Vcpu for MshvVcpu {
self.fd
.set_debug_regs(&state.dbg)
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))?;
self.fd
.set_all_vp_state_components(&mut state.vp_states)
.map_err(|e| cpu::HypervisorCpuError::SetAllVpStateComponents(e.into()))?;
Ok(())
}
@ -1322,8 +1323,6 @@ impl cpu::Vcpu for MshvVcpu {
let vcpu_events = self.get_vcpu_events()?;
let mut msrs = self.msrs.clone();
self.get_msrs(&mut msrs)?;
let lapic = self.get_lapic()?;
let xsave = self.get_xsave()?;
let misc = self
.fd
.get_misc_regs()
@ -1332,6 +1331,10 @@ impl cpu::Vcpu for MshvVcpu {
.fd
.get_debug_regs()
.map_err(|e| cpu::HypervisorCpuError::GetDebugRegs(e.into()))?;
let vp_states = self
.fd
.get_all_vp_state_components()
.map_err(|e| cpu::HypervisorCpuError::GetAllVpStateComponents(e.into()))?;
Ok(VcpuMshvState {
msrs,
@ -1340,10 +1343,9 @@ impl cpu::Vcpu for MshvVcpu {
sregs: sregs.into(),
fpu,
xcrs,
lapic,
dbg,
xsave,
misc,
vp_states,
}
.into())
}
@ -1425,26 +1427,6 @@ impl cpu::Vcpu for MshvVcpu {
}
impl MshvVcpu {
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xsave struct".
///
fn get_xsave(&self) -> cpu::Result<Xsave> {
self.fd
.get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xsave struct".
///
fn set_xsave(&self, xsave: &Xsave) -> cpu::Result<()> {
self.fd
.set_xsave(xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xcrs".

View File

@ -19,10 +19,10 @@ use std::fmt;
///
pub use {
mshv_bindings::hv_cpuid_entry, mshv_bindings::mshv_user_mem_region as MemoryRegion,
mshv_bindings::msr_entry, mshv_bindings::CpuId, mshv_bindings::DebugRegisters,
mshv_bindings::FloatingPointUnit, mshv_bindings::LapicState as MshvLapicState,
mshv_bindings::MiscRegs as MiscRegisters, mshv_bindings::MsrList,
mshv_bindings::Msrs as MsrEntries, mshv_bindings::Msrs,
mshv_bindings::msr_entry, mshv_bindings::AllVpStateComponents, mshv_bindings::CpuId,
mshv_bindings::DebugRegisters, mshv_bindings::FloatingPointUnit,
mshv_bindings::LapicState as MshvLapicState, mshv_bindings::MiscRegs as MiscRegisters,
mshv_bindings::MsrList, mshv_bindings::Msrs as MsrEntries, mshv_bindings::Msrs,
mshv_bindings::SegmentRegister as MshvSegmentRegister,
mshv_bindings::SpecialRegisters as MshvSpecialRegisters,
mshv_bindings::StandardRegisters as MshvStandardRegisters, mshv_bindings::SuspendRegisters,
@ -38,10 +38,9 @@ pub struct VcpuMshvState {
pub sregs: MshvSpecialRegisters,
pub fpu: FpuState,
pub xcrs: ExtendedControlRegisters,
pub lapic: LapicState,
pub dbg: DebugRegisters,
pub xsave: Xsave,
pub misc: MiscRegisters,
pub vp_states: AllVpStateComponents,
}
impl fmt::Display for VcpuMshvState {
@ -53,7 +52,7 @@ impl fmt::Display for VcpuMshvState {
msr_entries[i][1] = entry.data;
msr_entries[i][0] = entry.index as u64;
}
write!(f, "Number of MSRs: {}: MSRs: {:#010X?}, -- VCPU Events: {:?} -- Standard registers: {:?} Special Registers: {:?} ---- Floating Point Unit: {:?} --- Extended Control Register: {:?} --- Local APIC: {:?} --- DBG: {:?} --- Xsave: {:?}",
write!(f, "Number of MSRs: {}: MSRs: {:#010X?}, -- VCPU Events: {:?} -- Standard registers: {:?} Special Registers: {:?} ---- Floating Point Unit: {:?} --- Extended Control Register: {:?} --- DBG: {:?} --- VP States: {:?}",
msr_entries.len(),
msr_entries,
self.vcpu_events,
@ -61,9 +60,8 @@ impl fmt::Display for VcpuMshvState {
self.sregs,
self.fpu,
self.xcrs,
self.lapic,
self.dbg,
self.xsave,
self.vp_states,
)
}
}