xref: /aosp_15_r20/external/crosvm/hypervisor/src/haxm.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::CpuidResult;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::__cpuid;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::atomic::AtomicBool;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::atomic::Ordering;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor;
11*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor;
12*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
13*bb4ee6a4SAndroid Build Coastguard Worker use base::SafeDescriptor;
14*bb4ee6a4SAndroid Build Coastguard Worker 
15*bb4ee6a4SAndroid Build Coastguard Worker use crate::CpuId;
16*bb4ee6a4SAndroid Build Coastguard Worker use crate::CpuIdEntry;
17*bb4ee6a4SAndroid Build Coastguard Worker use crate::Hypervisor;
18*bb4ee6a4SAndroid Build Coastguard Worker use crate::HypervisorCap;
19*bb4ee6a4SAndroid Build Coastguard Worker use crate::HypervisorX86_64;
20*bb4ee6a4SAndroid Build Coastguard Worker 
21*bb4ee6a4SAndroid Build Coastguard Worker mod haxm_sys;
22*bb4ee6a4SAndroid Build Coastguard Worker // This is a HAXM-specific capability, so it's not present in the VmCap enum, and the
23*bb4ee6a4SAndroid Build Coastguard Worker // register_vm_log function does not exist on the Vm trait. But windows.rs will use it when
24*bb4ee6a4SAndroid Build Coastguard Worker // creating Haxm Vm instances, so we expose the cap constant here.
25*bb4ee6a4SAndroid Build Coastguard Worker pub use haxm_sys::HAX_CAP_VM_LOG;
26*bb4ee6a4SAndroid Build Coastguard Worker use haxm_sys::*;
27*bb4ee6a4SAndroid Build Coastguard Worker 
28*bb4ee6a4SAndroid Build Coastguard Worker mod vcpu;
29*bb4ee6a4SAndroid Build Coastguard Worker pub use vcpu::*;
30*bb4ee6a4SAndroid Build Coastguard Worker mod vm;
31*bb4ee6a4SAndroid Build Coastguard Worker pub use vm::*;
32*bb4ee6a4SAndroid Build Coastguard Worker 
33*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)]
34*bb4ee6a4SAndroid Build Coastguard Worker mod win;
35*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)]
36*bb4ee6a4SAndroid Build Coastguard Worker use win::*;
37*bb4ee6a4SAndroid Build Coastguard Worker 
38*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))]
39*bb4ee6a4SAndroid Build Coastguard Worker mod linux;
40*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))]
41*bb4ee6a4SAndroid Build Coastguard Worker use linux::*;
42*bb4ee6a4SAndroid Build Coastguard Worker 
43*bb4ee6a4SAndroid Build Coastguard Worker static USE_GHAXM: AtomicBool = AtomicBool::new(true);
44*bb4ee6a4SAndroid Build Coastguard Worker 
45*bb4ee6a4SAndroid Build Coastguard Worker /// Returns whether ghaxm variant is in use vs. the upstream haxm variant.
get_use_ghaxm() -> bool46*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_use_ghaxm() -> bool {
47*bb4ee6a4SAndroid Build Coastguard Worker     USE_GHAXM.load(Ordering::Relaxed)
48*bb4ee6a4SAndroid Build Coastguard Worker }
49*bb4ee6a4SAndroid Build Coastguard Worker 
50*bb4ee6a4SAndroid Build Coastguard Worker /// Sets whether to use ghaxm variant vs. the upstream haxm variant.
set_use_ghaxm(use_ghaxm: bool)51*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_use_ghaxm(use_ghaxm: bool) {
52*bb4ee6a4SAndroid Build Coastguard Worker     USE_GHAXM.store(use_ghaxm, Ordering::Relaxed);
53*bb4ee6a4SAndroid Build Coastguard Worker }
54*bb4ee6a4SAndroid Build Coastguard Worker 
55*bb4ee6a4SAndroid Build Coastguard Worker pub struct Haxm {
56*bb4ee6a4SAndroid Build Coastguard Worker     haxm: SafeDescriptor,
57*bb4ee6a4SAndroid Build Coastguard Worker }
58*bb4ee6a4SAndroid Build Coastguard Worker 
59*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Haxm {
as_raw_descriptor(&self) -> RawDescriptor60*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
61*bb4ee6a4SAndroid Build Coastguard Worker         self.haxm.as_raw_descriptor()
62*bb4ee6a4SAndroid Build Coastguard Worker     }
63*bb4ee6a4SAndroid Build Coastguard Worker }
64*bb4ee6a4SAndroid Build Coastguard Worker 
65*bb4ee6a4SAndroid Build Coastguard Worker impl Haxm {
66*bb4ee6a4SAndroid Build Coastguard Worker     /// Opens HAXM device and returns a Haxm object on success.
new() -> Result<Haxm>67*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new() -> Result<Haxm> {
68*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Haxm {
69*bb4ee6a4SAndroid Build Coastguard Worker             haxm: open_haxm_device(get_use_ghaxm())?,
70*bb4ee6a4SAndroid Build Coastguard Worker         })
71*bb4ee6a4SAndroid Build Coastguard Worker     }
72*bb4ee6a4SAndroid Build Coastguard Worker }
73*bb4ee6a4SAndroid Build Coastguard Worker 
74*bb4ee6a4SAndroid Build Coastguard Worker impl Hypervisor for Haxm {
check_capability(&self, cap: HypervisorCap) -> bool75*bb4ee6a4SAndroid Build Coastguard Worker     fn check_capability(&self, cap: HypervisorCap) -> bool {
76*bb4ee6a4SAndroid Build Coastguard Worker         // under haxm, guests rely on this leaf to calibrate their
77*bb4ee6a4SAndroid Build Coastguard Worker         // clocksource.
78*bb4ee6a4SAndroid Build Coastguard Worker         matches!(
79*bb4ee6a4SAndroid Build Coastguard Worker             cap,
80*bb4ee6a4SAndroid Build Coastguard Worker             HypervisorCap::UserMemory | HypervisorCap::CalibratedTscLeafRequired
81*bb4ee6a4SAndroid Build Coastguard Worker         )
82*bb4ee6a4SAndroid Build Coastguard Worker     }
83*bb4ee6a4SAndroid Build Coastguard Worker 
84*bb4ee6a4SAndroid Build Coastguard Worker     /// Makes a shallow clone of this `Hypervisor`.
try_clone(&self) -> Result<Self>85*bb4ee6a4SAndroid Build Coastguard Worker     fn try_clone(&self) -> Result<Self> {
86*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Haxm {
87*bb4ee6a4SAndroid Build Coastguard Worker             haxm: self.haxm.try_clone()?,
88*bb4ee6a4SAndroid Build Coastguard Worker         })
89*bb4ee6a4SAndroid Build Coastguard Worker     }
90*bb4ee6a4SAndroid Build Coastguard Worker }
91*bb4ee6a4SAndroid Build Coastguard Worker 
92*bb4ee6a4SAndroid Build Coastguard Worker impl HypervisorX86_64 for Haxm {
get_supported_cpuid(&self) -> Result<CpuId>93*bb4ee6a4SAndroid Build Coastguard Worker     fn get_supported_cpuid(&self) -> Result<CpuId> {
94*bb4ee6a4SAndroid Build Coastguard Worker         // Start with cpuids that HAXM supports from
95*bb4ee6a4SAndroid Build Coastguard Worker         // https://github.com/intel/haxm/blob/v7.6.1/core/cpuid.c#L170
96*bb4ee6a4SAndroid Build Coastguard Worker         let mut supported_features_1_ecx = (Feature1Ecx::SSE3
97*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::SSSE3
98*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::PCID
99*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::SSE41
100*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::SSE42
101*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::CMPXCHG16B
102*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::MOVBE
103*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::AESNI
104*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::PCLMULQDQ
105*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::POPCNT
106*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::FMA
107*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::XSAVE
108*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::OSXSAVE
109*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::AVX
110*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::F16C
111*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Ecx::RDRAND)
112*bb4ee6a4SAndroid Build Coastguard Worker             .bits();
113*bb4ee6a4SAndroid Build Coastguard Worker         let mut supported_features_1_edx = (Feature1Edx::PAT
114*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::FPU
115*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::VME
116*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::DE
117*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::TSC
118*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::MSR
119*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::PAE
120*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::MCE
121*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::CX8
122*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::APIC
123*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::SEP
124*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::MTRR
125*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::PGE
126*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::MCA
127*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::CMOV
128*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::CLFSH
129*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::MMX
130*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::FXSR
131*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::SSE
132*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::SSE2
133*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::SS
134*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::PSE
135*bb4ee6a4SAndroid Build Coastguard Worker             | Feature1Edx::HTT)
136*bb4ee6a4SAndroid Build Coastguard Worker             .bits();
137*bb4ee6a4SAndroid Build Coastguard Worker 
138*bb4ee6a4SAndroid Build Coastguard Worker         let mut supported_features_80000001_edx = (Feature80000001Edx::NX
139*bb4ee6a4SAndroid Build Coastguard Worker             | Feature80000001Edx::SYSCALL
140*bb4ee6a4SAndroid Build Coastguard Worker             | Feature80000001Edx::RDTSCP
141*bb4ee6a4SAndroid Build Coastguard Worker             | Feature80000001Edx::EM64T)
142*bb4ee6a4SAndroid Build Coastguard Worker             .bits();
143*bb4ee6a4SAndroid Build Coastguard Worker 
144*bb4ee6a4SAndroid Build Coastguard Worker         let mut supported_features_80000001_ecx =
145*bb4ee6a4SAndroid Build Coastguard Worker             (Feature80000001Ecx::LAHF | Feature80000001Ecx::ABM | Feature80000001Ecx::PREFETCHW)
146*bb4ee6a4SAndroid Build Coastguard Worker                 .bits();
147*bb4ee6a4SAndroid Build Coastguard Worker 
148*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
149*bb4ee6a4SAndroid Build Coastguard Worker         let result = unsafe { __cpuid(0x1) };
150*bb4ee6a4SAndroid Build Coastguard Worker 
151*bb4ee6a4SAndroid Build Coastguard Worker         // Filter HAXM supported cpuids by host-supported cpuids
152*bb4ee6a4SAndroid Build Coastguard Worker         supported_features_1_ecx &= result.ecx;
153*bb4ee6a4SAndroid Build Coastguard Worker         supported_features_1_edx &= result.edx;
154*bb4ee6a4SAndroid Build Coastguard Worker 
155*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
156*bb4ee6a4SAndroid Build Coastguard Worker         let result = unsafe { __cpuid(0x80000001) };
157*bb4ee6a4SAndroid Build Coastguard Worker 
158*bb4ee6a4SAndroid Build Coastguard Worker         supported_features_80000001_edx &= result.edx;
159*bb4ee6a4SAndroid Build Coastguard Worker         supported_features_80000001_ecx &= result.ecx;
160*bb4ee6a4SAndroid Build Coastguard Worker 
161*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
162*bb4ee6a4SAndroid Build Coastguard Worker         let cpuid_7 = unsafe { __cpuid(0x7) };
163*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
164*bb4ee6a4SAndroid Build Coastguard Worker         let cpuid_15 = unsafe { __cpuid(0x15) };
165*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
166*bb4ee6a4SAndroid Build Coastguard Worker         let cpuid_16 = unsafe { __cpuid(0x16) };
167*bb4ee6a4SAndroid Build Coastguard Worker 
168*bb4ee6a4SAndroid Build Coastguard Worker         Ok(CpuId {
169*bb4ee6a4SAndroid Build Coastguard Worker             cpu_id_entries: vec![
170*bb4ee6a4SAndroid Build Coastguard Worker                 CpuIdEntry {
171*bb4ee6a4SAndroid Build Coastguard Worker                     function: 0x1,
172*bb4ee6a4SAndroid Build Coastguard Worker                     index: 0,
173*bb4ee6a4SAndroid Build Coastguard Worker                     flags: 0,
174*bb4ee6a4SAndroid Build Coastguard Worker                     cpuid: CpuidResult {
175*bb4ee6a4SAndroid Build Coastguard Worker                         eax: 0,
176*bb4ee6a4SAndroid Build Coastguard Worker                         ebx: 0,
177*bb4ee6a4SAndroid Build Coastguard Worker                         ecx: supported_features_1_ecx,
178*bb4ee6a4SAndroid Build Coastguard Worker                         edx: supported_features_1_edx,
179*bb4ee6a4SAndroid Build Coastguard Worker                     },
180*bb4ee6a4SAndroid Build Coastguard Worker                 },
181*bb4ee6a4SAndroid Build Coastguard Worker                 CpuIdEntry {
182*bb4ee6a4SAndroid Build Coastguard Worker                     function: 0x7,
183*bb4ee6a4SAndroid Build Coastguard Worker                     index: 0,
184*bb4ee6a4SAndroid Build Coastguard Worker                     flags: 0,
185*bb4ee6a4SAndroid Build Coastguard Worker                     cpuid: CpuidResult {
186*bb4ee6a4SAndroid Build Coastguard Worker                         eax: cpuid_7.eax,
187*bb4ee6a4SAndroid Build Coastguard Worker                         ebx: cpuid_7.ebx,
188*bb4ee6a4SAndroid Build Coastguard Worker                         ecx: cpuid_7.ecx,
189*bb4ee6a4SAndroid Build Coastguard Worker                         edx: cpuid_7.edx,
190*bb4ee6a4SAndroid Build Coastguard Worker                     },
191*bb4ee6a4SAndroid Build Coastguard Worker                 },
192*bb4ee6a4SAndroid Build Coastguard Worker                 CpuIdEntry {
193*bb4ee6a4SAndroid Build Coastguard Worker                     function: 0x15,
194*bb4ee6a4SAndroid Build Coastguard Worker                     index: 0,
195*bb4ee6a4SAndroid Build Coastguard Worker                     flags: 0,
196*bb4ee6a4SAndroid Build Coastguard Worker                     cpuid: CpuidResult {
197*bb4ee6a4SAndroid Build Coastguard Worker                         eax: cpuid_15.eax,
198*bb4ee6a4SAndroid Build Coastguard Worker                         ebx: cpuid_15.ebx,
199*bb4ee6a4SAndroid Build Coastguard Worker                         ecx: cpuid_15.ecx,
200*bb4ee6a4SAndroid Build Coastguard Worker                         edx: cpuid_15.edx,
201*bb4ee6a4SAndroid Build Coastguard Worker                     },
202*bb4ee6a4SAndroid Build Coastguard Worker                 },
203*bb4ee6a4SAndroid Build Coastguard Worker                 CpuIdEntry {
204*bb4ee6a4SAndroid Build Coastguard Worker                     function: 0x16,
205*bb4ee6a4SAndroid Build Coastguard Worker                     index: 0,
206*bb4ee6a4SAndroid Build Coastguard Worker                     flags: 0,
207*bb4ee6a4SAndroid Build Coastguard Worker                     cpuid: CpuidResult {
208*bb4ee6a4SAndroid Build Coastguard Worker                         eax: cpuid_16.eax,
209*bb4ee6a4SAndroid Build Coastguard Worker                         ebx: cpuid_16.ebx,
210*bb4ee6a4SAndroid Build Coastguard Worker                         ecx: cpuid_16.ecx,
211*bb4ee6a4SAndroid Build Coastguard Worker                         edx: cpuid_16.edx,
212*bb4ee6a4SAndroid Build Coastguard Worker                     },
213*bb4ee6a4SAndroid Build Coastguard Worker                 },
214*bb4ee6a4SAndroid Build Coastguard Worker                 CpuIdEntry {
215*bb4ee6a4SAndroid Build Coastguard Worker                     function: 0x80000001,
216*bb4ee6a4SAndroid Build Coastguard Worker                     index: 0,
217*bb4ee6a4SAndroid Build Coastguard Worker                     flags: 0,
218*bb4ee6a4SAndroid Build Coastguard Worker                     cpuid: CpuidResult {
219*bb4ee6a4SAndroid Build Coastguard Worker                         eax: 0,
220*bb4ee6a4SAndroid Build Coastguard Worker                         ebx: 0,
221*bb4ee6a4SAndroid Build Coastguard Worker                         ecx: supported_features_80000001_ecx,
222*bb4ee6a4SAndroid Build Coastguard Worker                         edx: supported_features_80000001_edx,
223*bb4ee6a4SAndroid Build Coastguard Worker                     },
224*bb4ee6a4SAndroid Build Coastguard Worker                 },
225*bb4ee6a4SAndroid Build Coastguard Worker             ],
226*bb4ee6a4SAndroid Build Coastguard Worker         })
227*bb4ee6a4SAndroid Build Coastguard Worker     }
228*bb4ee6a4SAndroid Build Coastguard Worker 
229*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the list of supported MSRs.
get_msr_index_list(&self) -> Result<Vec<u32>>230*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr_index_list(&self) -> Result<Vec<u32>> {
231*bb4ee6a4SAndroid Build Coastguard Worker         // HAXM supported MSRs come from
232*bb4ee6a4SAndroid Build Coastguard Worker         // https://github.com/intel/haxm/blob/v7.6.1/core/vcpu.c#L3296
233*bb4ee6a4SAndroid Build Coastguard Worker         let mut msrs = vec![
234*bb4ee6a4SAndroid Build Coastguard Worker             IA32_TSC,
235*bb4ee6a4SAndroid Build Coastguard Worker             IA32_FEATURE_CONTROL,
236*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PLATFORM_ID,
237*bb4ee6a4SAndroid Build Coastguard Worker             IA32_APIC_BASE,
238*bb4ee6a4SAndroid Build Coastguard Worker             IA32_EFER,
239*bb4ee6a4SAndroid Build Coastguard Worker             IA32_STAR,
240*bb4ee6a4SAndroid Build Coastguard Worker             IA32_LSTAR,
241*bb4ee6a4SAndroid Build Coastguard Worker             IA32_CSTAR,
242*bb4ee6a4SAndroid Build Coastguard Worker             IA32_SF_MASK,
243*bb4ee6a4SAndroid Build Coastguard Worker             IA32_KERNEL_GS_BASE,
244*bb4ee6a4SAndroid Build Coastguard Worker             IA32_TSC_AUX,
245*bb4ee6a4SAndroid Build Coastguard Worker             IA32_FS_BASE,
246*bb4ee6a4SAndroid Build Coastguard Worker             IA32_GS_BASE,
247*bb4ee6a4SAndroid Build Coastguard Worker             IA32_SYSENTER_CS,
248*bb4ee6a4SAndroid Build Coastguard Worker             IA32_SYSENTER_ESP,
249*bb4ee6a4SAndroid Build Coastguard Worker             IA32_SYSENTER_EIP,
250*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MTRRCAP,
251*bb4ee6a4SAndroid Build Coastguard Worker             MTRRFIX64K_00000,
252*bb4ee6a4SAndroid Build Coastguard Worker             IA32_CR_PAT,
253*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MTRR_DEF_TYPE,
254*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MCG_CAP,
255*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MCG_STATUS,
256*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MCG_CTL,
257*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MC0_CTL,
258*bb4ee6a4SAndroid Build Coastguard Worker             IA32_P5_MC_TYPE,
259*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MC0_STATUS,
260*bb4ee6a4SAndroid Build Coastguard Worker             IA32_P5_MC_ADDR,
261*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MC0_ADDR,
262*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MC0_MISC,
263*bb4ee6a4SAndroid Build Coastguard Worker             IA32_THERM_DIODE_OFFSET,
264*bb4ee6a4SAndroid Build Coastguard Worker             IA32_FSB_FREQ,
265*bb4ee6a4SAndroid Build Coastguard Worker             IA32_TEMP_TARGET,
266*bb4ee6a4SAndroid Build Coastguard Worker             IA32_BBL_CR_CTL3,
267*bb4ee6a4SAndroid Build Coastguard Worker             IA32_DEBUGCTL,
268*bb4ee6a4SAndroid Build Coastguard Worker             IA32_CPUID_FEATURE_MASK,
269*bb4ee6a4SAndroid Build Coastguard Worker             IA32_EBC_FREQUENCY_ID,
270*bb4ee6a4SAndroid Build Coastguard Worker             IA32_EBC_HARD_POWERON,
271*bb4ee6a4SAndroid Build Coastguard Worker             IA32_EBC_SOFT_POWERON,
272*bb4ee6a4SAndroid Build Coastguard Worker             IA32_BIOS_SIGN_ID,
273*bb4ee6a4SAndroid Build Coastguard Worker             IA32_MISC_ENABLE,
274*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PERF_CAPABILITIES,
275*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PMC0,
276*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PMC1,
277*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PMC2,
278*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PMC3,
279*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PERFEVTSEL0,
280*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PERFEVTSEL1,
281*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PERFEVTSEL2,
282*bb4ee6a4SAndroid Build Coastguard Worker             IA32_PERFEVTSEL3,
283*bb4ee6a4SAndroid Build Coastguard Worker         ];
284*bb4ee6a4SAndroid Build Coastguard Worker         msrs.extend(IA32_MTRR_PHYSBASE0..IA32_MTRR_PHYSMASK9);
285*bb4ee6a4SAndroid Build Coastguard Worker         msrs.extend(MTRRFIX16K_80000..MTRRFIX16K_A0000);
286*bb4ee6a4SAndroid Build Coastguard Worker         msrs.extend(MTRRFIX4K_C0000..MTRRFIX4K_F8000);
287*bb4ee6a4SAndroid Build Coastguard Worker         msrs.extend(IA32_MC0_CTL2..IA32_MC8_CTL2);
288*bb4ee6a4SAndroid Build Coastguard Worker         Ok(msrs)
289*bb4ee6a4SAndroid Build Coastguard Worker     }
290*bb4ee6a4SAndroid Build Coastguard Worker }
291*bb4ee6a4SAndroid Build Coastguard Worker 
292*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b:241252288): Enable tests disabled with dummy feature flag - enable_haxm_tests.
293*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
294*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "enable_haxm_tests")]
295*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
296*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
297*bb4ee6a4SAndroid Build Coastguard Worker 
298*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
new_haxm()299*bb4ee6a4SAndroid Build Coastguard Worker     fn new_haxm() {
300*bb4ee6a4SAndroid Build Coastguard Worker         Haxm::new().expect("failed to instantiate HAXM");
301*bb4ee6a4SAndroid Build Coastguard Worker     }
302*bb4ee6a4SAndroid Build Coastguard Worker 
303*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
check_capability()304*bb4ee6a4SAndroid Build Coastguard Worker     fn check_capability() {
305*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
306*bb4ee6a4SAndroid Build Coastguard Worker         assert!(haxm.check_capability(HypervisorCap::UserMemory));
307*bb4ee6a4SAndroid Build Coastguard Worker         assert!(!haxm.check_capability(HypervisorCap::ImmediateExit));
308*bb4ee6a4SAndroid Build Coastguard Worker     }
309*bb4ee6a4SAndroid Build Coastguard Worker 
310*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
check_supported_cpuid()311*bb4ee6a4SAndroid Build Coastguard Worker     fn check_supported_cpuid() {
312*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
313*bb4ee6a4SAndroid Build Coastguard Worker         let cpuid = haxm
314*bb4ee6a4SAndroid Build Coastguard Worker             .get_supported_cpuid()
315*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get supported cupid");
316*bb4ee6a4SAndroid Build Coastguard Worker 
317*bb4ee6a4SAndroid Build Coastguard Worker         // HAXM returns five leaves: 0x1, 0x7, 0x15, 0x16, and 0x80000001
318*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(cpuid.cpu_id_entries.len(), 5);
319*bb4ee6a4SAndroid Build Coastguard Worker 
320*bb4ee6a4SAndroid Build Coastguard Worker         // Check some simple cpuids that we know should be enabled
321*bb4ee6a4SAndroid Build Coastguard Worker         let entry = cpuid
322*bb4ee6a4SAndroid Build Coastguard Worker             .cpu_id_entries
323*bb4ee6a4SAndroid Build Coastguard Worker             .iter()
324*bb4ee6a4SAndroid Build Coastguard Worker             .find(|entry| entry.function == 0x1)
325*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get leaf 0x1");
326*bb4ee6a4SAndroid Build Coastguard Worker 
327*bb4ee6a4SAndroid Build Coastguard Worker         // FPU should definitely exist
328*bb4ee6a4SAndroid Build Coastguard Worker         assert_ne!(entry.cpuid.edx & Feature1Edx::FPU.bits(), 0);
329*bb4ee6a4SAndroid Build Coastguard Worker         // SSSE3 almost certainly set
330*bb4ee6a4SAndroid Build Coastguard Worker         assert_ne!(entry.cpuid.ecx & Feature1Ecx::SSSE3.bits(), 0);
331*bb4ee6a4SAndroid Build Coastguard Worker         // VMX should not be set, HAXM does not support nested virt
332*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(entry.cpuid.ecx & Feature1Ecx::VMX.bits(), 0);
333*bb4ee6a4SAndroid Build Coastguard Worker 
334*bb4ee6a4SAndroid Build Coastguard Worker         // Check that leaf 0x15 is in the results
335*bb4ee6a4SAndroid Build Coastguard Worker         cpuid
336*bb4ee6a4SAndroid Build Coastguard Worker             .cpu_id_entries
337*bb4ee6a4SAndroid Build Coastguard Worker             .iter()
338*bb4ee6a4SAndroid Build Coastguard Worker             .find(|entry| entry.function == 0x15)
339*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get leaf 0x15");
340*bb4ee6a4SAndroid Build Coastguard Worker 
341*bb4ee6a4SAndroid Build Coastguard Worker         // Check that leaf 0x16 is in the results
342*bb4ee6a4SAndroid Build Coastguard Worker         cpuid
343*bb4ee6a4SAndroid Build Coastguard Worker             .cpu_id_entries
344*bb4ee6a4SAndroid Build Coastguard Worker             .iter()
345*bb4ee6a4SAndroid Build Coastguard Worker             .find(|entry| entry.function == 0x16)
346*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get leaf 0x16");
347*bb4ee6a4SAndroid Build Coastguard Worker 
348*bb4ee6a4SAndroid Build Coastguard Worker         let entry = cpuid
349*bb4ee6a4SAndroid Build Coastguard Worker             .cpu_id_entries
350*bb4ee6a4SAndroid Build Coastguard Worker             .iter()
351*bb4ee6a4SAndroid Build Coastguard Worker             .find(|entry| entry.function == 0x80000001)
352*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get leaf 0x80000001");
353*bb4ee6a4SAndroid Build Coastguard Worker         // NX should be set, Windows 8+ and HAXM require it
354*bb4ee6a4SAndroid Build Coastguard Worker         assert_ne!(entry.cpuid.edx & Feature80000001Edx::NX.bits(), 0);
355*bb4ee6a4SAndroid Build Coastguard Worker     }
356*bb4ee6a4SAndroid Build Coastguard Worker 
357*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
check_msr_index_list()358*bb4ee6a4SAndroid Build Coastguard Worker     fn check_msr_index_list() {
359*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
360*bb4ee6a4SAndroid Build Coastguard Worker         let msr_index_list = haxm
361*bb4ee6a4SAndroid Build Coastguard Worker             .get_msr_index_list()
362*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get HAXM msr index list");
363*bb4ee6a4SAndroid Build Coastguard Worker 
364*bb4ee6a4SAndroid Build Coastguard Worker         assert!(msr_index_list.contains(&IA32_TSC));
365*bb4ee6a4SAndroid Build Coastguard Worker     }
366*bb4ee6a4SAndroid Build Coastguard Worker }
367