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