hypervisor: simplify LapicState

Both KVM and MSHV share the same layout. We can drop one level of
indirection.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2022-07-27 22:58:47 +00:00 committed by Rob Bradford
parent ddc9004471
commit bec47ebcc9
3 changed files with 45 additions and 47 deletions

View File

@ -252,34 +252,51 @@ pub struct FpuState {
pub mxcsr: u32,
}
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub enum LapicState {
#[cfg(feature = "kvm")]
Kvm(kvm_bindings::kvm_lapic_state),
#[cfg(feature = "mshv")]
Mshv(mshv_bindings::LapicState),
#[derive(Debug, Clone)]
pub struct LapicState {
pub(crate) regs: [::std::os::raw::c_char; 1024usize],
}
impl Default for LapicState {
fn default() -> Self {
// SAFETY: this is plain old data structure
unsafe { ::std::mem::zeroed() }
}
}
impl<'de> serde::Deserialize<'de> for LapicState {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let regs: Vec<::std::os::raw::c_char> = Vec::deserialize(deserializer)?;
let mut val = LapicState::default();
// This panics if the source and destination have different lengths.
val.regs.copy_from_slice(&regs[..]);
Ok(val)
}
}
impl serde::Serialize for LapicState {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let regs = &self.regs[..];
regs.serialize(serializer)
}
}
#[cfg(any(feature = "kvm", feature = "mshv"))]
impl LapicState {
pub fn get_klapic_reg(&self, reg_offset: usize) -> u32 {
use byteorder::{LittleEndian, ReadBytesExt};
use std::io::Cursor;
use std::mem;
let sliceu8 = match self {
#[cfg(feature = "kvm")]
LapicState::Kvm(s) => unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&[i8], &[u8]>(&s.regs[reg_offset..])
},
#[cfg(feature = "mshv")]
LapicState::Mshv(s) => unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&[i8], &[u8]>(&s.regs[reg_offset..])
},
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&[i8], &[u8]>(&self.regs[reg_offset..])
};
let mut reader = Cursor::new(sliceu8);
@ -294,19 +311,10 @@ impl LapicState {
use std::io::Cursor;
use std::mem;
let sliceu8 = match self {
#[cfg(feature = "kvm")]
LapicState::Kvm(s) => unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&mut [i8], &mut [u8]>(&mut s.regs[reg_offset..])
},
#[cfg(feature = "mshv")]
LapicState::Mshv(s) => unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&mut [i8], &mut [u8]>(&mut s.regs[reg_offset..])
},
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&mut [i8], &mut [u8]>(&mut self.regs[reg_offset..])
};
let mut writer = Cursor::new(sliceu8);

View File

@ -298,18 +298,13 @@ impl From<FpuState> for kvm_fpu {
impl From<LapicState> for kvm_lapic_state {
fn from(s: LapicState) -> Self {
match s {
LapicState::Kvm(s) => s,
/* Needed in case other hypervisors are enabled */
#[allow(unreachable_patterns)]
_ => panic!("LapicState is not valid"),
}
Self { regs: s.regs }
}
}
impl From<kvm_lapic_state> for LapicState {
fn from(s: kvm_lapic_state) -> Self {
LapicState::Kvm(s)
Self { regs: s.regs }
}
}

View File

@ -289,18 +289,13 @@ impl From<FpuState> for FloatingPointUnit {
impl From<LapicState> for MshvLapicState {
fn from(s: LapicState) -> Self {
match s {
LapicState::Mshv(s) => s,
/* Needed in case other hypervisors are enabled */
#[allow(unreachable_patterns)]
_ => panic!("LapicState is not valid"),
}
Self { regs: s.regs }
}
}
impl From<MshvLapicState> for LapicState {
fn from(s: MshvLapicState) -> Self {
LapicState::Mshv(s)
Self { regs: s.regs }
}
}