xref: /cloud-hypervisor/hypervisor/src/mshv/x86_64/mod.rs (revision 4ff0686d379ab4b666b901babe704143b4cf6f07)
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