From f21fc1dcb69e3300fdfe495fb8a1b65795391b8f Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Tue, 19 Jul 2022 21:41:00 +0000 Subject: [PATCH] hypervisor: x86: provide a generic MsrEntry structure Signed-off-by: Wei Liu --- hypervisor/src/arch/x86/mod.rs | 8 ++++++-- hypervisor/src/cpu.rs | 6 +++--- hypervisor/src/kvm/mod.rs | 20 ++++++++++++++------ hypervisor/src/kvm/x86_64/mod.rs | 23 +++++++++++++++++++++-- hypervisor/src/mshv/mod.rs | 17 +++++++++++++---- hypervisor/src/mshv/x86_64/mod.rs | 23 +++++++++++++++++++++-- vmm/src/cpu.rs | 7 +++---- 7 files changed, 81 insertions(+), 23 deletions(-) diff --git a/hypervisor/src/arch/x86/mod.rs b/hypervisor/src/arch/x86/mod.rs index e866cac5e..68528e2f0 100644 --- a/hypervisor/src/arch/x86/mod.rs +++ b/hypervisor/src/arch/x86/mod.rs @@ -161,7 +161,6 @@ macro_rules! msr { MsrEntry { index: $msr, data: 0x0, - ..Default::default() } }; } @@ -171,7 +170,6 @@ macro_rules! msr_data { MsrEntry { index: $msr, data: $data, - ..Default::default() } }; } @@ -319,3 +317,9 @@ impl LapicState { .expect("Failed to write klapic register") } } + +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] +pub struct MsrEntry { + pub index: u32, + pub data: u64, +} diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index a21b82f72..eb2c24460 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -13,11 +13,11 @@ use crate::aarch64::VcpuInit; #[cfg(target_arch = "aarch64")] use crate::aarch64::{RegList, Register, StandardRegisters}; #[cfg(target_arch = "x86_64")] -use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, SpecialRegisters, StandardRegisters}; +use crate::arch::x86::{ + CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, +}; #[cfg(feature = "tdx")] use crate::kvm::{TdxExitDetails, TdxExitStatus}; -#[cfg(target_arch = "x86_64")] -use crate::x86_64::MsrEntry; use crate::CpuState; #[cfg(target_arch = "aarch64")] use crate::DeviceAttr; diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 85ce689da..9bfff097d 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -47,7 +47,8 @@ use vmm_sys_util::eventfd::EventFd; pub mod x86_64; #[cfg(target_arch = "x86_64")] use crate::arch::x86::{ - CpuIdEntry, FpuState, LapicState, SpecialRegisters, StandardRegisters, NUM_IOAPIC_PINS, + CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, + NUM_IOAPIC_PINS, }; #[cfg(target_arch = "x86_64")] use crate::ClockData; @@ -65,7 +66,7 @@ use kvm_bindings::{ #[cfg(target_arch = "x86_64")] use x86_64::check_required_kvm_extensions; #[cfg(target_arch = "x86_64")] -pub use x86_64::{CpuId, ExtendedControlRegisters, MsrEntries, MsrEntry, VcpuKvmState, Xsave}; +pub use x86_64::{CpuId, ExtendedControlRegisters, MsrEntries, VcpuKvmState, Xsave}; // aarch64 dependencies #[cfg(target_arch = "aarch64")] pub mod aarch64; @@ -1403,13 +1404,19 @@ impl cpu::Vcpu for KvmVcpu { /// Returns the model-specific registers (MSR) for this vCPU. /// fn get_msrs(&self, msrs: &mut Vec) -> cpu::Result { - let mut kvm_msrs = MsrEntries::from_entries(msrs).unwrap(); + let kvm_msrs: Vec = msrs.iter().map(|e| (*e).into()).collect(); + let mut kvm_msrs = MsrEntries::from_entries(&kvm_msrs).unwrap(); let succ = self .fd .get_msrs(&mut kvm_msrs) .map_err(|e| cpu::HypervisorCpuError::GetMsrEntries(e.into()))?; - msrs[..succ].copy_from_slice(&kvm_msrs.as_slice()[..succ]); + msrs[..succ].copy_from_slice( + &kvm_msrs.as_slice()[..succ] + .iter() + .map(|e| (*e).into()) + .collect::>(), + ); Ok(succ) } @@ -1419,7 +1426,8 @@ impl cpu::Vcpu for KvmVcpu { /// Returns the number of MSR entries actually written. /// fn set_msrs(&self, msrs: &[MsrEntry]) -> cpu::Result { - let kvm_msrs = MsrEntries::from_entries(msrs).unwrap(); + let kvm_msrs: Vec = msrs.iter().map(|e| (*e).into()).collect(); + let kvm_msrs = MsrEntries::from_entries(&kvm_msrs).unwrap(); self.fd .set_msrs(&kvm_msrs) .map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into())) @@ -1812,7 +1820,7 @@ impl cpu::Vcpu for KvmVcpu { index, ..Default::default() }; - msr_entries.push(msr); + msr_entries.push(msr.into()); } } diff --git a/hypervisor/src/kvm/x86_64/mod.rs b/hypervisor/src/kvm/x86_64/mod.rs index c1dbe0742..b3094e3c6 100644 --- a/hypervisor/src/kvm/x86_64/mod.rs +++ b/hypervisor/src/kvm/x86_64/mod.rs @@ -9,7 +9,7 @@ // use crate::arch::x86::{ - CpuIdEntry, DescriptorTable, FpuState, LapicState, SegmentRegister, SpecialRegisters, + CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters, StandardRegisters, CPUID_FLAG_VALID_INDEX, }; use crate::kvm::{Cap, Kvm, KvmError, KvmResult}; @@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize}; pub use { kvm_bindings::kvm_cpuid_entry2, kvm_bindings::kvm_dtable, kvm_bindings::kvm_fpu, kvm_bindings::kvm_lapic_state, kvm_bindings::kvm_mp_state as MpState, - kvm_bindings::kvm_msr_entry as MsrEntry, kvm_bindings::kvm_regs, kvm_bindings::kvm_segment, + kvm_bindings::kvm_msr_entry, kvm_bindings::kvm_regs, kvm_bindings::kvm_segment, kvm_bindings::kvm_sregs, kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave as Xsave, kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries, @@ -312,3 +312,22 @@ impl From for LapicState { LapicState::Kvm(s) } } + +impl From for MsrEntry { + fn from(e: kvm_msr_entry) -> Self { + Self { + index: e.index, + data: e.data, + } + } +} + +impl From for kvm_msr_entry { + fn from(e: MsrEntry) -> Self { + Self { + index: e.index, + data: e.data, + ..Default::default() + } + } +} diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 07e9c07a6..5a45bb213 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -37,7 +37,9 @@ use std::fs::File; use std::os::unix::io::AsRawFd; #[cfg(target_arch = "x86_64")] -use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, SpecialRegisters, StandardRegisters}; +use crate::arch::x86::{ + CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, +}; const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4; const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8; @@ -346,13 +348,19 @@ impl cpu::Vcpu for MshvVcpu { /// Returns the model-specific registers (MSR) for this vCPU. /// fn get_msrs(&self, msrs: &mut Vec) -> cpu::Result { - let mut mshv_msrs = MsrEntries::from_entries(msrs).unwrap(); + let mshv_msrs: Vec = msrs.iter().map(|e| (*e).into()).collect(); + let mut mshv_msrs = MsrEntries::from_entries(&mshv_msrs).unwrap(); let succ = self .fd .get_msrs(&mut mshv_msrs) .map_err(|e| cpu::HypervisorCpuError::GetMsrEntries(e.into()))?; - msrs[..succ].copy_from_slice(&mshv_msrs.as_slice()[..succ]); + msrs[..succ].copy_from_slice( + &mshv_msrs.as_slice()[..succ] + .iter() + .map(|e| (*e).into()) + .collect::>(), + ); Ok(succ) } @@ -362,7 +370,8 @@ impl cpu::Vcpu for MshvVcpu { /// Returns the number of MSR entries actually written. /// fn set_msrs(&self, msrs: &[MsrEntry]) -> cpu::Result { - let mshv_msrs = MsrEntries::from_entries(msrs).unwrap(); + let mshv_msrs: Vec = msrs.iter().map(|e| (*e).into()).collect(); + let mshv_msrs = MsrEntries::from_entries(&mshv_msrs).unwrap(); self.fd .set_msrs(&mshv_msrs) .map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into())) diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index 90e71b894..43fd2c30b 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -8,7 +8,7 @@ // // use crate::arch::x86::{ - CpuIdEntry, DescriptorTable, FpuState, LapicState, SegmentRegister, SpecialRegisters, + CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters, StandardRegisters, }; use serde::{Deserialize, Serialize}; @@ -19,7 +19,7 @@ use std::fmt; /// pub use { mshv_bindings::hv_cpuid_entry, mshv_bindings::mshv_user_mem_region as MemoryRegion, - mshv_bindings::msr_entry as MsrEntry, mshv_bindings::CpuId, mshv_bindings::DebugRegisters, + 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, @@ -303,3 +303,22 @@ impl From for LapicState { LapicState::Mshv(s) } } + +impl From for MsrEntry { + fn from(e: msr_entry) -> Self { + Self { + index: e.index, + data: e.data, + } + } +} + +impl From for msr_entry { + fn from(e: MsrEntry) -> Self { + Self { + index: e.index, + data: e.data, + ..Default::default() + } + } +} diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index deb9f3fa3..bd3f87d12 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -38,14 +38,14 @@ use gdbstub_arch::x86::reg::{X86SegmentRegs, X86_64CoreRegs}; use hypervisor::arch::x86::msr_index; #[cfg(target_arch = "x86_64")] use hypervisor::arch::x86::CpuIdEntry; +#[cfg(feature = "guest_debug")] +use hypervisor::arch::x86::MsrEntry; #[cfg(all(target_arch = "x86_64", feature = "gdb"))] use hypervisor::arch::x86::{SpecialRegisters, StandardRegisters}; #[cfg(target_arch = "aarch64")] use hypervisor::kvm::kvm_bindings; #[cfg(feature = "tdx")] use hypervisor::kvm::{TdxExitDetails, TdxExitStatus}; -#[cfg(feature = "guest_debug")] -use hypervisor::x86_64::MsrEntry; use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps}; use libc::{c_void, siginfo_t}; #[cfg(feature = "guest_debug")] @@ -2387,8 +2387,7 @@ mod tests { #[test] fn test_setup_msrs() { - use hypervisor::arch::x86::msr_index; - use hypervisor::x86_64::MsrEntry; + use hypervisor::arch::x86::{msr_index, MsrEntry}; let hv = hypervisor::new().unwrap(); let vm = hv.create_vm().expect("new VM fd creation failed");