1 // Copyright © 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 4 // 5 // Copyright © 2020, Microsoft Corporation 6 // 7 // Copyright 2018-2019 CrowdStrike, Inc. 8 // 9 // 10 use crate::arch::x86::{msr_index, SegmentRegisterOps, MTRR_ENABLE, MTRR_MEM_TYPE_WB}; 11 use serde_derive::{Deserialize, Serialize}; 12 use std::fmt; 13 14 /// 15 /// Export generically-named wrappers of mshv_bindings for Unix-based platforms 16 /// 17 pub use { 18 mshv_bindings::hv_cpuid_entry as CpuIdEntry, 19 mshv_bindings::mshv_user_mem_region as MemoryRegion, mshv_bindings::msr_entry as MsrEntry, 20 mshv_bindings::CpuId, mshv_bindings::DebugRegisters, 21 mshv_bindings::FloatingPointUnit as FpuState, mshv_bindings::LapicState, 22 mshv_bindings::MiscRegs as MiscRegisters, mshv_bindings::MsrList, 23 mshv_bindings::Msrs as MsrEntries, mshv_bindings::Msrs, mshv_bindings::SegmentRegister, 24 mshv_bindings::SpecialRegisters, mshv_bindings::StandardRegisters, 25 mshv_bindings::SuspendRegisters, mshv_bindings::VcpuEvents, mshv_bindings::XSave as Xsave, 26 mshv_bindings::Xcrs as ExtendedControlRegisters, 27 }; 28 29 pub const CPUID_FLAG_VALID_INDEX: u32 = 0; 30 31 #[derive(Clone, Serialize, Deserialize)] 32 pub struct VcpuMshvState { 33 pub msrs: MsrEntries, 34 pub vcpu_events: VcpuEvents, 35 pub regs: StandardRegisters, 36 pub sregs: SpecialRegisters, 37 pub fpu: FpuState, 38 pub xcrs: ExtendedControlRegisters, 39 pub lapic: LapicState, 40 pub dbg: DebugRegisters, 41 pub xsave: Xsave, 42 pub misc: MiscRegisters, 43 } 44 45 impl fmt::Display for VcpuMshvState { 46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 47 let expected_num_msrs = self.msrs.as_fam_struct_ref().nmsrs as usize; 48 let mut msr_entries = vec![vec![0; 2]; expected_num_msrs]; 49 50 for (i, entry) in self.msrs.as_slice().iter().enumerate() { 51 msr_entries[i][1] = entry.data; 52 msr_entries[i][0] = entry.index as u64; 53 } 54 write!(f, "Number of MSRs: {}: MSRs: {:#010X?}, -- VCPU Events: {:?} -- Standard registers: {:?} Special Registers: {:?} ---- Floating Point Unit: {:?} --- Extended Control Register: {:?} --- Local APIC: {:?} --- DBG: {:?} --- Xsave: {:?}", 55 msr_entries.len(), 56 msr_entries, 57 self.vcpu_events, 58 self.regs, 59 self.sregs, 60 self.fpu, 61 self.xcrs, 62 self.lapic, 63 self.dbg, 64 self.xsave, 65 ) 66 } 67 } 68 69 pub struct IrqRouting {} 70 pub enum VcpuExit {} 71 pub struct MpState {} 72 73 impl SegmentRegisterOps for SegmentRegister { 74 fn segment_type(&self) -> u8 { 75 self.type_ 76 } 77 fn set_segment_type(&mut self, val: u8) { 78 self.type_ = val; 79 } 80 81 fn dpl(&self) -> u8 { 82 self.dpl 83 } 84 85 fn set_dpl(&mut self, val: u8) { 86 self.dpl = val; 87 } 88 89 fn present(&self) -> u8 { 90 self.present 91 } 92 93 fn set_present(&mut self, val: u8) { 94 self.present = val; 95 } 96 97 fn long(&self) -> u8 { 98 self.l 99 } 100 101 fn set_long(&mut self, val: u8) { 102 self.l = val; 103 } 104 105 fn avl(&self) -> u8 { 106 self.avl 107 } 108 109 fn set_avl(&mut self, val: u8) { 110 self.avl = val; 111 } 112 113 fn desc_type(&self) -> u8 { 114 self.s 115 } 116 117 fn set_desc_type(&mut self, val: u8) { 118 self.s = val; 119 } 120 121 fn granularity(&self) -> u8 { 122 self.g 123 } 124 125 fn set_granularity(&mut self, val: u8) { 126 self.g = val; 127 } 128 129 fn db(&self) -> u8 { 130 self.db 131 } 132 133 fn set_db(&mut self, val: u8) { 134 self.db = val; 135 } 136 } 137 138 pub fn boot_msr_entries() -> MsrEntries { 139 MsrEntries::from_entries(&[ 140 msr!(msr_index::MSR_IA32_SYSENTER_CS), 141 msr!(msr_index::MSR_IA32_SYSENTER_ESP), 142 msr!(msr_index::MSR_IA32_SYSENTER_EIP), 143 msr!(msr_index::MSR_STAR), 144 msr!(msr_index::MSR_CSTAR), 145 msr!(msr_index::MSR_LSTAR), 146 msr!(msr_index::MSR_KERNEL_GS_BASE), 147 msr!(msr_index::MSR_SYSCALL_MASK), 148 msr!(msr_index::MSR_IA32_TSC), 149 msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB), 150 ]) 151 .unwrap() 152 } 153