diff --git a/hypervisor/src/arch/x86/mod.rs b/hypervisor/src/arch/x86/mod.rs index 491cd6c31..8bf0843cc 100644 --- a/hypervisor/src/arch/x86/mod.rs +++ b/hypervisor/src/arch/x86/mod.rs @@ -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(deserializer: D) -> std::result::Result + 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(®s[..]); + Ok(val) + } +} + +impl serde::Serialize for LapicState { + fn serialize(&self, serializer: S) -> std::result::Result + 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); diff --git a/hypervisor/src/kvm/x86_64/mod.rs b/hypervisor/src/kvm/x86_64/mod.rs index b3094e3c6..8106340d3 100644 --- a/hypervisor/src/kvm/x86_64/mod.rs +++ b/hypervisor/src/kvm/x86_64/mod.rs @@ -298,18 +298,13 @@ impl From for kvm_fpu { impl From 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 for LapicState { fn from(s: kvm_lapic_state) -> Self { - LapicState::Kvm(s) + Self { regs: s.regs } } } diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index 43fd2c30b..af4bf3991 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -289,18 +289,13 @@ impl From for FloatingPointUnit { impl From 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 for LapicState { fn from(s: MshvLapicState) -> Self { - LapicState::Mshv(s) + Self { regs: s.regs } } }