xref: /aosp_15_r20/external/crosvm/hypervisor/src/haxm/vcpu.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 core::ffi::c_void;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::CpuidResult;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker use base::errno_result;
11*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl;
12*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_mut_ref;
13*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_ptr_sized;
14*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_ref;
15*bb4ee6a4SAndroid Build Coastguard Worker use base::warn;
16*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor;
17*bb4ee6a4SAndroid Build Coastguard Worker use base::Error;
18*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor;
19*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
20*bb4ee6a4SAndroid Build Coastguard Worker use base::SafeDescriptor;
21*bb4ee6a4SAndroid Build Coastguard Worker use data_model::vec_with_array_field;
22*bb4ee6a4SAndroid Build Coastguard Worker use libc::EINVAL;
23*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENOENT;
24*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENXIO;
25*bb4ee6a4SAndroid Build Coastguard Worker use libc::EOPNOTSUPP;
26*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
27*bb4ee6a4SAndroid Build Coastguard Worker 
28*bb4ee6a4SAndroid Build Coastguard Worker use super::*;
29*bb4ee6a4SAndroid Build Coastguard Worker use crate::CpuId;
30*bb4ee6a4SAndroid Build Coastguard Worker use crate::CpuIdEntry;
31*bb4ee6a4SAndroid Build Coastguard Worker use crate::DebugRegs;
32*bb4ee6a4SAndroid Build Coastguard Worker use crate::DescriptorTable;
33*bb4ee6a4SAndroid Build Coastguard Worker use crate::Fpu;
34*bb4ee6a4SAndroid Build Coastguard Worker use crate::FpuReg;
35*bb4ee6a4SAndroid Build Coastguard Worker use crate::IoOperation;
36*bb4ee6a4SAndroid Build Coastguard Worker use crate::IoParams;
37*bb4ee6a4SAndroid Build Coastguard Worker use crate::Regs;
38*bb4ee6a4SAndroid Build Coastguard Worker use crate::Segment;
39*bb4ee6a4SAndroid Build Coastguard Worker use crate::Sregs;
40*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vcpu;
41*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuExit;
42*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuShutdownError;
43*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuShutdownErrorKind;
44*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuX86_64;
45*bb4ee6a4SAndroid Build Coastguard Worker use crate::Xsave;
46*bb4ee6a4SAndroid Build Coastguard Worker 
47*bb4ee6a4SAndroid Build Coastguard Worker // HAXM exit reasons
48*bb4ee6a4SAndroid Build Coastguard Worker // IO port request
49*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_IO: u32 = 1;
50*bb4ee6a4SAndroid Build Coastguard Worker // MMIO instruction emulation, should not happen anymore, replaced with
51*bb4ee6a4SAndroid Build Coastguard Worker // HAX_EXIT_FAST_MMIO
52*bb4ee6a4SAndroid Build Coastguard Worker #[allow(dead_code)]
53*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_MMIO: u32 = 2;
54*bb4ee6a4SAndroid Build Coastguard Worker // Real mode emulation when unrestricted guest is disabled
55*bb4ee6a4SAndroid Build Coastguard Worker #[allow(dead_code)]
56*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_REALMODE: u32 = 3;
57*bb4ee6a4SAndroid Build Coastguard Worker // Interrupt window open, crosvm can inject an interrupt now.
58*bb4ee6a4SAndroid Build Coastguard Worker // Also used when vcpu thread receives a signal
59*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_INTERRUPT: u32 = 4;
60*bb4ee6a4SAndroid Build Coastguard Worker // Unknown vmexit, mostly trigger reboot
61*bb4ee6a4SAndroid Build Coastguard Worker #[allow(dead_code)]
62*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_UNKNOWN: u32 = 5;
63*bb4ee6a4SAndroid Build Coastguard Worker // HALT from guest
64*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_HLT: u32 = 6;
65*bb4ee6a4SAndroid Build Coastguard Worker // VCPU panic, like because of triple fault in guest
66*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_VCPU_PANIC: u32 = 7;
67*bb4ee6a4SAndroid Build Coastguard Worker // Paused by crosvm setting _exit_reason to HAX_EXIT_PAUSED before entry
68*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) const HAX_EXIT_PAUSED: u32 = 8;
69*bb4ee6a4SAndroid Build Coastguard Worker // MMIO instruction emulation through io_buffer
70*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_FAST_MMIO: u32 = 9;
71*bb4ee6a4SAndroid Build Coastguard Worker // Page fault that was not able to be handled by HAXM
72*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_PAGEFAULT: u32 = 10;
73*bb4ee6a4SAndroid Build Coastguard Worker // A debug exception caused a vmexit
74*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_DEBUG: u32 = 11;
75*bb4ee6a4SAndroid Build Coastguard Worker 
76*bb4ee6a4SAndroid Build Coastguard Worker // HAXM exit directions
77*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_DIRECTION_PIO_IN: u32 = 1;
78*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_DIRECTION_PIO_OUT: u32 = 0;
79*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_DIRECTION_MMIO_READ: u8 = 0;
80*bb4ee6a4SAndroid Build Coastguard Worker const HAX_EXIT_DIRECTION_MMIO_WRITE: u8 = 1;
81*bb4ee6a4SAndroid Build Coastguard Worker 
82*bb4ee6a4SAndroid Build Coastguard Worker pub struct HaxmVcpu {
83*bb4ee6a4SAndroid Build Coastguard Worker     pub(super) descriptor: SafeDescriptor,
84*bb4ee6a4SAndroid Build Coastguard Worker     pub(super) id: usize,
85*bb4ee6a4SAndroid Build Coastguard Worker     pub(super) tunnel: *mut hax_tunnel,
86*bb4ee6a4SAndroid Build Coastguard Worker     pub(super) io_buffer: *mut c_void,
87*bb4ee6a4SAndroid Build Coastguard Worker }
88*bb4ee6a4SAndroid Build Coastguard Worker 
89*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315998194): Add safety comment
90*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
91*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Send for HaxmVcpu {}
92*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315998194): Add safety comment
93*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
94*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Sync for HaxmVcpu {}
95*bb4ee6a4SAndroid Build Coastguard Worker 
96*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for HaxmVcpu {
as_raw_descriptor(&self) -> RawDescriptor97*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
98*bb4ee6a4SAndroid Build Coastguard Worker         self.descriptor.as_raw_descriptor()
99*bb4ee6a4SAndroid Build Coastguard Worker     }
100*bb4ee6a4SAndroid Build Coastguard Worker }
101*bb4ee6a4SAndroid Build Coastguard Worker 
102*bb4ee6a4SAndroid Build Coastguard Worker impl HaxmVcpu {
get_vcpu_state(&self) -> Result<VcpuState>103*bb4ee6a4SAndroid Build Coastguard Worker     fn get_vcpu_state(&self) -> Result<VcpuState> {
104*bb4ee6a4SAndroid Build Coastguard Worker         let mut state = vcpu_state_t::default();
105*bb4ee6a4SAndroid Build Coastguard Worker 
106*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe with return value checked.
107*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_GET_REGS, &mut state) };
108*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
109*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
110*bb4ee6a4SAndroid Build Coastguard Worker         }
111*bb4ee6a4SAndroid Build Coastguard Worker 
112*bb4ee6a4SAndroid Build Coastguard Worker         // Also read efer MSR
113*bb4ee6a4SAndroid Build Coastguard Worker         state.efer = self.get_msr(IA32_EFER)? as u32;
114*bb4ee6a4SAndroid Build Coastguard Worker 
115*bb4ee6a4SAndroid Build Coastguard Worker         Ok(VcpuState { state })
116*bb4ee6a4SAndroid Build Coastguard Worker     }
117*bb4ee6a4SAndroid Build Coastguard Worker 
set_vcpu_state(&self, state: &mut VcpuState) -> Result<()>118*bb4ee6a4SAndroid Build Coastguard Worker     fn set_vcpu_state(&self, state: &mut VcpuState) -> Result<()> {
119*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe with return value checked.
120*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_SET_REGS, &mut state.state) };
121*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
122*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
123*bb4ee6a4SAndroid Build Coastguard Worker         }
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker         // Also set efer MSR
126*bb4ee6a4SAndroid Build Coastguard Worker         self.set_msr(IA32_EFER, state.state.efer as u64)
127*bb4ee6a4SAndroid Build Coastguard Worker     }
128*bb4ee6a4SAndroid Build Coastguard Worker }
129*bb4ee6a4SAndroid Build Coastguard Worker 
130*bb4ee6a4SAndroid Build Coastguard Worker impl Vcpu for HaxmVcpu {
131*bb4ee6a4SAndroid Build Coastguard Worker     /// Makes a shallow clone of this `Vcpu`.
try_clone(&self) -> Result<Self>132*bb4ee6a4SAndroid Build Coastguard Worker     fn try_clone(&self) -> Result<Self> {
133*bb4ee6a4SAndroid Build Coastguard Worker         Ok(HaxmVcpu {
134*bb4ee6a4SAndroid Build Coastguard Worker             descriptor: self.descriptor.try_clone()?,
135*bb4ee6a4SAndroid Build Coastguard Worker             id: self.id,
136*bb4ee6a4SAndroid Build Coastguard Worker             tunnel: self.tunnel,
137*bb4ee6a4SAndroid Build Coastguard Worker             io_buffer: self.io_buffer,
138*bb4ee6a4SAndroid Build Coastguard Worker         })
139*bb4ee6a4SAndroid Build Coastguard Worker     }
140*bb4ee6a4SAndroid Build Coastguard Worker 
as_vcpu(&self) -> &dyn Vcpu141*bb4ee6a4SAndroid Build Coastguard Worker     fn as_vcpu(&self) -> &dyn Vcpu {
142*bb4ee6a4SAndroid Build Coastguard Worker         self
143*bb4ee6a4SAndroid Build Coastguard Worker     }
144*bb4ee6a4SAndroid Build Coastguard Worker 
145*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns the vcpu id.
id(&self) -> usize146*bb4ee6a4SAndroid Build Coastguard Worker     fn id(&self) -> usize {
147*bb4ee6a4SAndroid Build Coastguard Worker         self.id
148*bb4ee6a4SAndroid Build Coastguard Worker     }
149*bb4ee6a4SAndroid Build Coastguard Worker 
150*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the bit that requests an immediate exit.
set_immediate_exit(&self, exit: bool)151*bb4ee6a4SAndroid Build Coastguard Worker     fn set_immediate_exit(&self, exit: bool) {
152*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
153*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know the tunnel is a pointer to a hax_tunnel and we know its size.
154*bb4ee6a4SAndroid Build Coastguard Worker         // Crosvm's HAXM implementation does not use the _exit_reason, so it's fine if we
155*bb4ee6a4SAndroid Build Coastguard Worker         // overwrite it.
156*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
157*bb4ee6a4SAndroid Build Coastguard Worker             (*self.tunnel).exit_reason = if exit { HAX_EXIT_PAUSED } else { 0 };
158*bb4ee6a4SAndroid Build Coastguard Worker         }
159*bb4ee6a4SAndroid Build Coastguard Worker     }
160*bb4ee6a4SAndroid Build Coastguard Worker 
161*bb4ee6a4SAndroid Build Coastguard Worker     /// Signals to the hypervisor that this guest is being paused by userspace.
on_suspend(&self) -> Result<()>162*bb4ee6a4SAndroid Build Coastguard Worker     fn on_suspend(&self) -> Result<()> {
163*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
164*bb4ee6a4SAndroid Build Coastguard Worker     }
165*bb4ee6a4SAndroid Build Coastguard Worker 
166*bb4ee6a4SAndroid Build Coastguard Worker     /// Enables a hypervisor-specific extension on this Vcpu.  `cap` is a constant defined by the
167*bb4ee6a4SAndroid Build Coastguard Worker     /// hypervisor API.  `args` are the arguments for enabling the feature, if any.
enable_raw_capability(&self, _cap: u32, _args: &[u64; 4]) -> Result<()>168*bb4ee6a4SAndroid Build Coastguard Worker     unsafe fn enable_raw_capability(&self, _cap: u32, _args: &[u64; 4]) -> Result<()> {
169*bb4ee6a4SAndroid Build Coastguard Worker         // Haxm does not support enable_capability
170*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(libc::ENXIO))
171*bb4ee6a4SAndroid Build Coastguard Worker     }
172*bb4ee6a4SAndroid Build Coastguard Worker 
173*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should be called after `Vcpu::run` returns `VcpuExit::Mmio`.
174*bb4ee6a4SAndroid Build Coastguard Worker     ///
175*bb4ee6a4SAndroid Build Coastguard Worker     /// Once called, it will determine whether a mmio read or mmio write was the reason for the mmio
176*bb4ee6a4SAndroid Build Coastguard Worker     /// exit, call `handle_fn` with the respective IoOperation to perform the mmio read or
177*bb4ee6a4SAndroid Build Coastguard Worker     /// write, and set the return data in the vcpu so that the vcpu can resume running.
handle_mmio(&self, handle_fn: &mut dyn FnMut(IoParams) -> Result<()>) -> Result<()>178*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_mmio(&self, handle_fn: &mut dyn FnMut(IoParams) -> Result<()>) -> Result<()> {
179*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
180*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the hax_tunnel struct because the
181*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was.
182*bb4ee6a4SAndroid Build Coastguard Worker         // Verify that the handler is called for mmio context only.
183*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
184*bb4ee6a4SAndroid Build Coastguard Worker             assert!((*self.tunnel).exit_status == HAX_EXIT_FAST_MMIO);
185*bb4ee6a4SAndroid Build Coastguard Worker         }
186*bb4ee6a4SAndroid Build Coastguard Worker         let mmio = self.io_buffer as *mut hax_fastmmio;
187*bb4ee6a4SAndroid Build Coastguard Worker         let (address, size, direction) =
188*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
189*bb4ee6a4SAndroid Build Coastguard Worker             // Safe because the exit_reason (which comes from the kernel) told us which
190*bb4ee6a4SAndroid Build Coastguard Worker             // union field to use.
191*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ((*mmio).gpa, (*mmio).size as usize, (*mmio).direction) };
192*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
193*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the exit_reason (which comes from the kernel) told us which
194*bb4ee6a4SAndroid Build Coastguard Worker         // union field to use. We use `addr_of_mut!()` to get a potentially unaligned u64 pointer,
195*bb4ee6a4SAndroid Build Coastguard Worker         // but it is then cast via a u8 pointer to a u8 slice, which has no alignment requirements.
196*bb4ee6a4SAndroid Build Coastguard Worker         let data = unsafe {
197*bb4ee6a4SAndroid Build Coastguard Worker             assert!(size <= size_of::<u64>());
198*bb4ee6a4SAndroid Build Coastguard Worker             std::slice::from_raw_parts_mut(
199*bb4ee6a4SAndroid Build Coastguard Worker                 std::ptr::addr_of_mut!((*mmio).__bindgen_anon_1.value) as *mut u8,
200*bb4ee6a4SAndroid Build Coastguard Worker                 size,
201*bb4ee6a4SAndroid Build Coastguard Worker             )
202*bb4ee6a4SAndroid Build Coastguard Worker         };
203*bb4ee6a4SAndroid Build Coastguard Worker 
204*bb4ee6a4SAndroid Build Coastguard Worker         match direction {
205*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_DIRECTION_MMIO_READ => {
206*bb4ee6a4SAndroid Build Coastguard Worker                 handle_fn(IoParams {
207*bb4ee6a4SAndroid Build Coastguard Worker                     address,
208*bb4ee6a4SAndroid Build Coastguard Worker                     operation: IoOperation::Read(data),
209*bb4ee6a4SAndroid Build Coastguard Worker                 })
210*bb4ee6a4SAndroid Build Coastguard Worker                 // We have to unwrap/panic here because HAXM doesn't have a
211*bb4ee6a4SAndroid Build Coastguard Worker                 // facility to inject a GP fault here. Once HAXM can do that, we
212*bb4ee6a4SAndroid Build Coastguard Worker                 // should inject a GP fault & bubble the error.
213*bb4ee6a4SAndroid Build Coastguard Worker                 .unwrap();
214*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
215*bb4ee6a4SAndroid Build Coastguard Worker             }
216*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_DIRECTION_MMIO_WRITE => {
217*bb4ee6a4SAndroid Build Coastguard Worker                 handle_fn(IoParams {
218*bb4ee6a4SAndroid Build Coastguard Worker                     address,
219*bb4ee6a4SAndroid Build Coastguard Worker                     operation: IoOperation::Write(data),
220*bb4ee6a4SAndroid Build Coastguard Worker                 })
221*bb4ee6a4SAndroid Build Coastguard Worker                 // Similarly to the read direction, we MUST panic here.
222*bb4ee6a4SAndroid Build Coastguard Worker                 .unwrap();
223*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
224*bb4ee6a4SAndroid Build Coastguard Worker             }
225*bb4ee6a4SAndroid Build Coastguard Worker             _ => Err(Error::new(EINVAL)),
226*bb4ee6a4SAndroid Build Coastguard Worker         }
227*bb4ee6a4SAndroid Build Coastguard Worker     }
228*bb4ee6a4SAndroid Build Coastguard Worker 
229*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should be called after `Vcpu::run` returns `VcpuExit::Io`.
230*bb4ee6a4SAndroid Build Coastguard Worker     ///
231*bb4ee6a4SAndroid Build Coastguard Worker     /// Once called, it will determine whether an io in or io out was the reason for the io exit,
232*bb4ee6a4SAndroid Build Coastguard Worker     /// call `handle_fn` with the respective IoOperation to perform the io in or io out,
233*bb4ee6a4SAndroid Build Coastguard Worker     /// and set the return data in the vcpu so that the vcpu can resume running.
234*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
handle_io(&self, handle_fn: &mut dyn FnMut(IoParams)) -> Result<()>235*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_io(&self, handle_fn: &mut dyn FnMut(IoParams)) -> Result<()> {
236*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
237*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the hax_tunnel struct because the
238*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was.
239*bb4ee6a4SAndroid Build Coastguard Worker         // Verify that the handler is called for io context only.
240*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
241*bb4ee6a4SAndroid Build Coastguard Worker             assert!((*self.tunnel).exit_status == HAX_EXIT_IO);
242*bb4ee6a4SAndroid Build Coastguard Worker         }
243*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
244*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the exit_reason (which comes from the kernel) told us which
245*bb4ee6a4SAndroid Build Coastguard Worker         // union field to use.
246*bb4ee6a4SAndroid Build Coastguard Worker         let io = unsafe { (*self.tunnel).__bindgen_anon_1.io };
247*bb4ee6a4SAndroid Build Coastguard Worker         let address = io.port.into();
248*bb4ee6a4SAndroid Build Coastguard Worker         let size = io.size as usize;
249*bb4ee6a4SAndroid Build Coastguard Worker         let count = io.count as usize;
250*bb4ee6a4SAndroid Build Coastguard Worker         let data_len = count * size;
251*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
252*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the exit_reason (which comes from the kernel) told us that this is port io,
253*bb4ee6a4SAndroid Build Coastguard Worker         // where the iobuf can be treated as a *u8
254*bb4ee6a4SAndroid Build Coastguard Worker         let buffer: &mut [u8] =
255*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { std::slice::from_raw_parts_mut(self.io_buffer as *mut u8, data_len) };
256*bb4ee6a4SAndroid Build Coastguard Worker         let data_chunks = buffer.chunks_mut(size);
257*bb4ee6a4SAndroid Build Coastguard Worker 
258*bb4ee6a4SAndroid Build Coastguard Worker         match io.direction as u32 {
259*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_DIRECTION_PIO_IN => {
260*bb4ee6a4SAndroid Build Coastguard Worker                 for data in data_chunks {
261*bb4ee6a4SAndroid Build Coastguard Worker                     handle_fn(IoParams {
262*bb4ee6a4SAndroid Build Coastguard Worker                         address,
263*bb4ee6a4SAndroid Build Coastguard Worker                         operation: IoOperation::Read(data),
264*bb4ee6a4SAndroid Build Coastguard Worker                     });
265*bb4ee6a4SAndroid Build Coastguard Worker                 }
266*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
267*bb4ee6a4SAndroid Build Coastguard Worker             }
268*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_DIRECTION_PIO_OUT => {
269*bb4ee6a4SAndroid Build Coastguard Worker                 for data in data_chunks {
270*bb4ee6a4SAndroid Build Coastguard Worker                     handle_fn(IoParams {
271*bb4ee6a4SAndroid Build Coastguard Worker                         address,
272*bb4ee6a4SAndroid Build Coastguard Worker                         operation: IoOperation::Write(data),
273*bb4ee6a4SAndroid Build Coastguard Worker                     });
274*bb4ee6a4SAndroid Build Coastguard Worker                 }
275*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
276*bb4ee6a4SAndroid Build Coastguard Worker             }
277*bb4ee6a4SAndroid Build Coastguard Worker             _ => Err(Error::new(EINVAL)),
278*bb4ee6a4SAndroid Build Coastguard Worker         }
279*bb4ee6a4SAndroid Build Coastguard Worker     }
280*bb4ee6a4SAndroid Build Coastguard Worker 
281*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
282*bb4ee6a4SAndroid Build Coastguard Worker     // The pointer is page aligned so casting to a different type is well defined, hence the clippy
283*bb4ee6a4SAndroid Build Coastguard Worker     // allow attribute.
run(&mut self) -> Result<VcpuExit>284*bb4ee6a4SAndroid Build Coastguard Worker     fn run(&mut self) -> Result<VcpuExit> {
285*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
286*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
287*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl(self, HAX_VCPU_IOCTL_RUN) };
288*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
289*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
290*bb4ee6a4SAndroid Build Coastguard Worker         }
291*bb4ee6a4SAndroid Build Coastguard Worker 
292*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
293*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the hax_tunnel struct because the
294*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was.
295*bb4ee6a4SAndroid Build Coastguard Worker         let exit_status = unsafe { (*self.tunnel).exit_status };
296*bb4ee6a4SAndroid Build Coastguard Worker 
297*bb4ee6a4SAndroid Build Coastguard Worker         match exit_status {
298*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_IO => Ok(VcpuExit::Io),
299*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_INTERRUPT => Ok(VcpuExit::Intr),
300*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_HLT => Ok(VcpuExit::Hlt),
301*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_VCPU_PANIC => {
302*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
303*bb4ee6a4SAndroid Build Coastguard Worker                 // 1) we mapped enough memory to hold the hax_tunnel struct because the kernel told
304*bb4ee6a4SAndroid Build Coastguard Worker                 //    us how large it was. That memory is still alive here.
305*bb4ee6a4SAndroid Build Coastguard Worker                 let panic_reason = unsafe { (*self.tunnel).vcpu_panic_reason };
306*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(VcpuExit::Shutdown(Err(VcpuShutdownError::new(
307*bb4ee6a4SAndroid Build Coastguard Worker                     VcpuShutdownErrorKind::Other,
308*bb4ee6a4SAndroid Build Coastguard Worker                     panic_reason as u64,
309*bb4ee6a4SAndroid Build Coastguard Worker                 ))))
310*bb4ee6a4SAndroid Build Coastguard Worker             }
311*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_FAST_MMIO => Ok(VcpuExit::Mmio),
312*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_PAGEFAULT => Ok(VcpuExit::Exception),
313*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_DEBUG => Ok(VcpuExit::Debug),
314*bb4ee6a4SAndroid Build Coastguard Worker             HAX_EXIT_PAUSED => Ok(VcpuExit::Exception),
315*bb4ee6a4SAndroid Build Coastguard Worker             r => panic!("unknown exit reason: {}", r),
316*bb4ee6a4SAndroid Build Coastguard Worker         }
317*bb4ee6a4SAndroid Build Coastguard Worker     }
318*bb4ee6a4SAndroid Build Coastguard Worker }
319*bb4ee6a4SAndroid Build Coastguard Worker 
320*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuX86_64 for HaxmVcpu {
321*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets or clears the flag that requests the VCPU to exit when it becomes possible to inject
322*bb4ee6a4SAndroid Build Coastguard Worker     /// interrupts into the guest.
set_interrupt_window_requested(&self, requested: bool)323*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_window_requested(&self, requested: bool) {
324*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
325*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the hax_tunnel struct because the
326*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was.
327*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
328*bb4ee6a4SAndroid Build Coastguard Worker             (*self.tunnel).request_interrupt_window = i32::from(requested);
329*bb4ee6a4SAndroid Build Coastguard Worker         }
330*bb4ee6a4SAndroid Build Coastguard Worker     }
331*bb4ee6a4SAndroid Build Coastguard Worker 
332*bb4ee6a4SAndroid Build Coastguard Worker     /// Checks if we can inject an interrupt into the VCPU.
ready_for_interrupt(&self) -> bool333*bb4ee6a4SAndroid Build Coastguard Worker     fn ready_for_interrupt(&self) -> bool {
334*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
335*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the hax_tunnel struct because the
336*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was.
337*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { (*self.tunnel).ready_for_interrupt_injection != 0 }
338*bb4ee6a4SAndroid Build Coastguard Worker     }
339*bb4ee6a4SAndroid Build Coastguard Worker 
340*bb4ee6a4SAndroid Build Coastguard Worker     /// Injects interrupt vector `irq` into the VCPU.
interrupt(&self, irq: u8) -> Result<()>341*bb4ee6a4SAndroid Build Coastguard Worker     fn interrupt(&self, irq: u8) -> Result<()> {
342*bb4ee6a4SAndroid Build Coastguard Worker         let irq: u32 = irq.into();
343*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
344*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
345*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, HAX_VCPU_IOCTL_INTERRUPT, &irq) };
346*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
347*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
348*bb4ee6a4SAndroid Build Coastguard Worker         }
349*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
350*bb4ee6a4SAndroid Build Coastguard Worker     }
351*bb4ee6a4SAndroid Build Coastguard Worker 
352*bb4ee6a4SAndroid Build Coastguard Worker     /// Injects a non-maskable interrupt into the VCPU.
inject_nmi(&self) -> Result<()>353*bb4ee6a4SAndroid Build Coastguard Worker     fn inject_nmi(&self) -> Result<()> {
354*bb4ee6a4SAndroid Build Coastguard Worker         warn!("HAXM does not support injecting NMIs");
355*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
356*bb4ee6a4SAndroid Build Coastguard Worker     }
357*bb4ee6a4SAndroid Build Coastguard Worker 
358*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU general purpose registers.
get_regs(&self) -> Result<Regs>359*bb4ee6a4SAndroid Build Coastguard Worker     fn get_regs(&self) -> Result<Regs> {
360*bb4ee6a4SAndroid Build Coastguard Worker         Ok(self.get_vcpu_state()?.get_regs())
361*bb4ee6a4SAndroid Build Coastguard Worker     }
362*bb4ee6a4SAndroid Build Coastguard Worker 
363*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU general purpose registers.
set_regs(&self, regs: &Regs) -> Result<()>364*bb4ee6a4SAndroid Build Coastguard Worker     fn set_regs(&self, regs: &Regs) -> Result<()> {
365*bb4ee6a4SAndroid Build Coastguard Worker         let mut state = self.get_vcpu_state()?;
366*bb4ee6a4SAndroid Build Coastguard Worker         state.set_regs(regs);
367*bb4ee6a4SAndroid Build Coastguard Worker         self.set_vcpu_state(&mut state)?;
368*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
369*bb4ee6a4SAndroid Build Coastguard Worker     }
370*bb4ee6a4SAndroid Build Coastguard Worker 
371*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU special registers.
get_sregs(&self) -> Result<Sregs>372*bb4ee6a4SAndroid Build Coastguard Worker     fn get_sregs(&self) -> Result<Sregs> {
373*bb4ee6a4SAndroid Build Coastguard Worker         Ok(self.get_vcpu_state()?.get_sregs())
374*bb4ee6a4SAndroid Build Coastguard Worker     }
375*bb4ee6a4SAndroid Build Coastguard Worker 
376*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU special registers.
set_sregs(&self, sregs: &Sregs) -> Result<()>377*bb4ee6a4SAndroid Build Coastguard Worker     fn set_sregs(&self, sregs: &Sregs) -> Result<()> {
378*bb4ee6a4SAndroid Build Coastguard Worker         let mut state = self.get_vcpu_state()?;
379*bb4ee6a4SAndroid Build Coastguard Worker         state.set_sregs(sregs);
380*bb4ee6a4SAndroid Build Coastguard Worker         self.set_vcpu_state(&mut state)?;
381*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
382*bb4ee6a4SAndroid Build Coastguard Worker     }
383*bb4ee6a4SAndroid Build Coastguard Worker 
384*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU FPU registers.
get_fpu(&self) -> Result<Fpu>385*bb4ee6a4SAndroid Build Coastguard Worker     fn get_fpu(&self) -> Result<Fpu> {
386*bb4ee6a4SAndroid Build Coastguard Worker         let mut fpu = fx_layout::default();
387*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
388*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
389*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_IOCTL_GET_FPU, &mut fpu) };
390*bb4ee6a4SAndroid Build Coastguard Worker 
391*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
392*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
393*bb4ee6a4SAndroid Build Coastguard Worker         }
394*bb4ee6a4SAndroid Build Coastguard Worker 
395*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Fpu::from(&fpu))
396*bb4ee6a4SAndroid Build Coastguard Worker     }
397*bb4ee6a4SAndroid Build Coastguard Worker 
398*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU FPU registers.
set_fpu(&self, fpu: &Fpu) -> Result<()>399*bb4ee6a4SAndroid Build Coastguard Worker     fn set_fpu(&self, fpu: &Fpu) -> Result<()> {
400*bb4ee6a4SAndroid Build Coastguard Worker         let mut current_fpu = fx_layout::default();
401*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
402*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
403*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_IOCTL_GET_FPU, &mut current_fpu) };
404*bb4ee6a4SAndroid Build Coastguard Worker 
405*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
406*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
407*bb4ee6a4SAndroid Build Coastguard Worker         }
408*bb4ee6a4SAndroid Build Coastguard Worker 
409*bb4ee6a4SAndroid Build Coastguard Worker         let mut new_fpu = fx_layout::from(fpu);
410*bb4ee6a4SAndroid Build Coastguard Worker 
411*bb4ee6a4SAndroid Build Coastguard Worker         // the mxcsr mask is something that isn't part of the Fpu state, so we make the new
412*bb4ee6a4SAndroid Build Coastguard Worker         // fpu state's mxcsr_mask matches its current value
413*bb4ee6a4SAndroid Build Coastguard Worker         new_fpu.mxcsr_mask = current_fpu.mxcsr_mask;
414*bb4ee6a4SAndroid Build Coastguard Worker 
415*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
416*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
417*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, HAX_VCPU_IOCTL_SET_FPU, &new_fpu) };
418*bb4ee6a4SAndroid Build Coastguard Worker 
419*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
420*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
421*bb4ee6a4SAndroid Build Coastguard Worker         }
422*bb4ee6a4SAndroid Build Coastguard Worker 
423*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
424*bb4ee6a4SAndroid Build Coastguard Worker     }
425*bb4ee6a4SAndroid Build Coastguard Worker 
get_xsave(&self) -> Result<Xsave>426*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xsave(&self) -> Result<Xsave> {
427*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(EOPNOTSUPP))
428*bb4ee6a4SAndroid Build Coastguard Worker     }
429*bb4ee6a4SAndroid Build Coastguard Worker 
set_xsave(&self, _xsave: &Xsave) -> Result<()>430*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xsave(&self, _xsave: &Xsave) -> Result<()> {
431*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(EOPNOTSUPP))
432*bb4ee6a4SAndroid Build Coastguard Worker     }
433*bb4ee6a4SAndroid Build Coastguard Worker 
get_interrupt_state(&self) -> Result<serde_json::Value>434*bb4ee6a4SAndroid Build Coastguard Worker     fn get_interrupt_state(&self) -> Result<serde_json::Value> {
435*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(EOPNOTSUPP))
436*bb4ee6a4SAndroid Build Coastguard Worker     }
437*bb4ee6a4SAndroid Build Coastguard Worker 
set_interrupt_state(&self, _data: serde_json::Value) -> Result<()>438*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_state(&self, _data: serde_json::Value) -> Result<()> {
439*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(EOPNOTSUPP))
440*bb4ee6a4SAndroid Build Coastguard Worker     }
441*bb4ee6a4SAndroid Build Coastguard Worker 
442*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU debug registers.
get_debugregs(&self) -> Result<DebugRegs>443*bb4ee6a4SAndroid Build Coastguard Worker     fn get_debugregs(&self) -> Result<DebugRegs> {
444*bb4ee6a4SAndroid Build Coastguard Worker         Ok(self.get_vcpu_state()?.get_debugregs())
445*bb4ee6a4SAndroid Build Coastguard Worker     }
446*bb4ee6a4SAndroid Build Coastguard Worker 
447*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU debug registers.
set_debugregs(&self, debugregs: &DebugRegs) -> Result<()>448*bb4ee6a4SAndroid Build Coastguard Worker     fn set_debugregs(&self, debugregs: &DebugRegs) -> Result<()> {
449*bb4ee6a4SAndroid Build Coastguard Worker         let mut state = self.get_vcpu_state()?;
450*bb4ee6a4SAndroid Build Coastguard Worker         state.set_debugregs(debugregs);
451*bb4ee6a4SAndroid Build Coastguard Worker         self.set_vcpu_state(&mut state)?;
452*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
453*bb4ee6a4SAndroid Build Coastguard Worker     }
454*bb4ee6a4SAndroid Build Coastguard Worker 
455*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU extended control registers.
get_xcrs(&self) -> Result<BTreeMap<u32, u64>>456*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>> {
457*bb4ee6a4SAndroid Build Coastguard Worker         // Haxm does not support getting XCRs
458*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(libc::ENXIO))
459*bb4ee6a4SAndroid Build Coastguard Worker     }
460*bb4ee6a4SAndroid Build Coastguard Worker 
461*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets a VCPU extended control register.
set_xcr(&self, _xcr_index: u32, _value: u64) -> Result<()>462*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xcr(&self, _xcr_index: u32, _value: u64) -> Result<()> {
463*bb4ee6a4SAndroid Build Coastguard Worker         // Haxm does not support setting XCRs
464*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(libc::ENXIO))
465*bb4ee6a4SAndroid Build Coastguard Worker     }
466*bb4ee6a4SAndroid Build Coastguard Worker 
467*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the value of one model-specific register.
get_msr(&self, msr_index: u32) -> Result<u64>468*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr(&self, msr_index: u32) -> Result<u64> {
469*bb4ee6a4SAndroid Build Coastguard Worker         let mut msr_data = hax_msr_data {
470*bb4ee6a4SAndroid Build Coastguard Worker             nr_msr: 1,
471*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
472*bb4ee6a4SAndroid Build Coastguard Worker         };
473*bb4ee6a4SAndroid Build Coastguard Worker         msr_data.entries[0].entry = u64::from(msr_index);
474*bb4ee6a4SAndroid Build Coastguard Worker 
475*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
476*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
477*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_IOCTL_GET_MSRS, &mut msr_data) };
478*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
479*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
480*bb4ee6a4SAndroid Build Coastguard Worker         }
481*bb4ee6a4SAndroid Build Coastguard Worker 
482*bb4ee6a4SAndroid Build Coastguard Worker         Ok(msr_data.entries[0].value)
483*bb4ee6a4SAndroid Build Coastguard Worker     }
484*bb4ee6a4SAndroid Build Coastguard Worker 
get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>485*bb4ee6a4SAndroid Build Coastguard Worker     fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>> {
486*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(EOPNOTSUPP))
487*bb4ee6a4SAndroid Build Coastguard Worker     }
488*bb4ee6a4SAndroid Build Coastguard Worker 
489*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the value of one model-specific register.
set_msr(&self, msr_index: u32, value: u64) -> Result<()>490*bb4ee6a4SAndroid Build Coastguard Worker     fn set_msr(&self, msr_index: u32, value: u64) -> Result<()> {
491*bb4ee6a4SAndroid Build Coastguard Worker         let mut msr_data = hax_msr_data {
492*bb4ee6a4SAndroid Build Coastguard Worker             nr_msr: 1,
493*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
494*bb4ee6a4SAndroid Build Coastguard Worker         };
495*bb4ee6a4SAndroid Build Coastguard Worker         msr_data.entries[0].entry = u64::from(msr_index);
496*bb4ee6a4SAndroid Build Coastguard Worker         msr_data.entries[0].value = value;
497*bb4ee6a4SAndroid Build Coastguard Worker 
498*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
499*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
500*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, HAX_VCPU_IOCTL_SET_MSRS, &mut msr_data) };
501*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
502*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
503*bb4ee6a4SAndroid Build Coastguard Worker         }
504*bb4ee6a4SAndroid Build Coastguard Worker 
505*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
506*bb4ee6a4SAndroid Build Coastguard Worker     }
507*bb4ee6a4SAndroid Build Coastguard Worker 
508*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets up the data returned by the CPUID instruction.
set_cpuid(&self, cpuid: &CpuId) -> Result<()>509*bb4ee6a4SAndroid Build Coastguard Worker     fn set_cpuid(&self, cpuid: &CpuId) -> Result<()> {
510*bb4ee6a4SAndroid Build Coastguard Worker         let total = cpuid.cpu_id_entries.len();
511*bb4ee6a4SAndroid Build Coastguard Worker         let mut hax = vec_with_array_field::<hax_cpuid, hax_cpuid_entry>(total);
512*bb4ee6a4SAndroid Build Coastguard Worker         hax[0].total = total as u32;
513*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
514*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
515*bb4ee6a4SAndroid Build Coastguard Worker         let entries = unsafe { hax[0].entries.as_mut_slice(total) };
516*bb4ee6a4SAndroid Build Coastguard Worker         for (i, e) in cpuid.cpu_id_entries.iter().enumerate() {
517*bb4ee6a4SAndroid Build Coastguard Worker             entries[i] = hax_cpuid_entry::from(e);
518*bb4ee6a4SAndroid Build Coastguard Worker         }
519*bb4ee6a4SAndroid Build Coastguard Worker 
520*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
521*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
522*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe {
523*bb4ee6a4SAndroid Build Coastguard Worker             ioctl_with_ptr_sized(
524*bb4ee6a4SAndroid Build Coastguard Worker                 self,
525*bb4ee6a4SAndroid Build Coastguard Worker                 HAX_VCPU_IOCTL_SET_CPUID,
526*bb4ee6a4SAndroid Build Coastguard Worker                 hax.as_ptr(),
527*bb4ee6a4SAndroid Build Coastguard Worker                 size_of::<hax_cpuid>() + total * size_of::<hax_cpuid_entry>(),
528*bb4ee6a4SAndroid Build Coastguard Worker             )
529*bb4ee6a4SAndroid Build Coastguard Worker         };
530*bb4ee6a4SAndroid Build Coastguard Worker 
531*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
532*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
533*bb4ee6a4SAndroid Build Coastguard Worker         }
534*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
535*bb4ee6a4SAndroid Build Coastguard Worker     }
536*bb4ee6a4SAndroid Build Coastguard Worker 
537*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should be called after `Vcpu::run` returns `VcpuExit::Cpuid`, and `entry`
538*bb4ee6a4SAndroid Build Coastguard Worker     /// should represent the result of emulating the CPUID instruction. The `handle_cpuid` function
539*bb4ee6a4SAndroid Build Coastguard Worker     /// will then set the appropriate registers on the vcpu.
540*bb4ee6a4SAndroid Build Coastguard Worker     /// HAXM does not support the VcpuExit::Cpuid exit type.
handle_cpuid(&mut self, _entry: &CpuIdEntry) -> Result<()>541*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_cpuid(&mut self, _entry: &CpuIdEntry) -> Result<()> {
542*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENXIO))
543*bb4ee6a4SAndroid Build Coastguard Worker     }
544*bb4ee6a4SAndroid Build Coastguard Worker 
set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()>545*bb4ee6a4SAndroid Build Coastguard Worker     fn set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()> {
546*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/173807302): Implement this
547*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOENT))
548*bb4ee6a4SAndroid Build Coastguard Worker     }
549*bb4ee6a4SAndroid Build Coastguard Worker 
restore_timekeeping(&self, _host_tsc_reference_moment: u64, tsc_offset: u64) -> Result<()>550*bb4ee6a4SAndroid Build Coastguard Worker     fn restore_timekeeping(&self, _host_tsc_reference_moment: u64, tsc_offset: u64) -> Result<()> {
551*bb4ee6a4SAndroid Build Coastguard Worker         // HAXM sets TSC_OFFSET based on what we set TSC to; however, it does
552*bb4ee6a4SAndroid Build Coastguard Worker         // not yet handle syncing. This means it computes
553*bb4ee6a4SAndroid Build Coastguard Worker         // TSC_OFFSET = new_tsc - rdtsc(), so if we want to target the same
554*bb4ee6a4SAndroid Build Coastguard Worker         // offset value, we need new_tsc = rdtsc() + target_offset. This is what
555*bb4ee6a4SAndroid Build Coastguard Worker         // Self::set_tsc_offset does.
556*bb4ee6a4SAndroid Build Coastguard Worker         //
557*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/311793539): haxm doesn't yet support syncing TSCs across VCPUs
558*bb4ee6a4SAndroid Build Coastguard Worker         // if the TSC value is non-zero. Once we have that support, we can
559*bb4ee6a4SAndroid Build Coastguard Worker         // switch to calling Self::set_tsc_value here with the common host
560*bb4ee6a4SAndroid Build Coastguard Worker         // reference moment. (Alternatively, we may just expose a way to set the
561*bb4ee6a4SAndroid Build Coastguard Worker         // offset directly.)
562*bb4ee6a4SAndroid Build Coastguard Worker         self.set_tsc_offset(tsc_offset)
563*bb4ee6a4SAndroid Build Coastguard Worker     }
564*bb4ee6a4SAndroid Build Coastguard Worker }
565*bb4ee6a4SAndroid Build Coastguard Worker 
566*bb4ee6a4SAndroid Build Coastguard Worker struct VcpuState {
567*bb4ee6a4SAndroid Build Coastguard Worker     state: vcpu_state_t,
568*bb4ee6a4SAndroid Build Coastguard Worker }
569*bb4ee6a4SAndroid Build Coastguard Worker 
570*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuState {
get_regs(&self) -> Regs571*bb4ee6a4SAndroid Build Coastguard Worker     fn get_regs(&self) -> Regs {
572*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
573*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
574*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
575*bb4ee6a4SAndroid Build Coastguard Worker             Regs {
576*bb4ee6a4SAndroid Build Coastguard Worker                 rax: self
577*bb4ee6a4SAndroid Build Coastguard Worker                     .state
578*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
579*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
580*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
581*bb4ee6a4SAndroid Build Coastguard Worker                     .rax,
582*bb4ee6a4SAndroid Build Coastguard Worker                 rbx: self
583*bb4ee6a4SAndroid Build Coastguard Worker                     .state
584*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
585*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
586*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_4
587*bb4ee6a4SAndroid Build Coastguard Worker                     .rbx,
588*bb4ee6a4SAndroid Build Coastguard Worker                 rcx: self
589*bb4ee6a4SAndroid Build Coastguard Worker                     .state
590*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
591*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
592*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_2
593*bb4ee6a4SAndroid Build Coastguard Worker                     .rcx,
594*bb4ee6a4SAndroid Build Coastguard Worker                 rdx: self
595*bb4ee6a4SAndroid Build Coastguard Worker                     .state
596*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
597*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
598*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_3
599*bb4ee6a4SAndroid Build Coastguard Worker                     .rdx,
600*bb4ee6a4SAndroid Build Coastguard Worker                 rsi: self
601*bb4ee6a4SAndroid Build Coastguard Worker                     .state
602*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
603*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
604*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_7
605*bb4ee6a4SAndroid Build Coastguard Worker                     .rsi,
606*bb4ee6a4SAndroid Build Coastguard Worker                 rdi: self
607*bb4ee6a4SAndroid Build Coastguard Worker                     .state
608*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
609*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
610*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_8
611*bb4ee6a4SAndroid Build Coastguard Worker                     .rdi,
612*bb4ee6a4SAndroid Build Coastguard Worker                 rsp: self
613*bb4ee6a4SAndroid Build Coastguard Worker                     .state
614*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
615*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
616*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_5
617*bb4ee6a4SAndroid Build Coastguard Worker                     .rsp,
618*bb4ee6a4SAndroid Build Coastguard Worker                 rbp: self
619*bb4ee6a4SAndroid Build Coastguard Worker                     .state
620*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
621*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_1
622*bb4ee6a4SAndroid Build Coastguard Worker                     .__bindgen_anon_6
623*bb4ee6a4SAndroid Build Coastguard Worker                     .rbp,
624*bb4ee6a4SAndroid Build Coastguard Worker                 r8: self.state.__bindgen_anon_1.__bindgen_anon_1.r8,
625*bb4ee6a4SAndroid Build Coastguard Worker                 r9: self.state.__bindgen_anon_1.__bindgen_anon_1.r9,
626*bb4ee6a4SAndroid Build Coastguard Worker                 r10: self.state.__bindgen_anon_1.__bindgen_anon_1.r10,
627*bb4ee6a4SAndroid Build Coastguard Worker                 r11: self.state.__bindgen_anon_1.__bindgen_anon_1.r11,
628*bb4ee6a4SAndroid Build Coastguard Worker                 r12: self.state.__bindgen_anon_1.__bindgen_anon_1.r12,
629*bb4ee6a4SAndroid Build Coastguard Worker                 r13: self.state.__bindgen_anon_1.__bindgen_anon_1.r13,
630*bb4ee6a4SAndroid Build Coastguard Worker                 r14: self.state.__bindgen_anon_1.__bindgen_anon_1.r14,
631*bb4ee6a4SAndroid Build Coastguard Worker                 r15: self.state.__bindgen_anon_1.__bindgen_anon_1.r15,
632*bb4ee6a4SAndroid Build Coastguard Worker                 rip: self.state.__bindgen_anon_2.rip,
633*bb4ee6a4SAndroid Build Coastguard Worker                 rflags: self.state.__bindgen_anon_3.rflags,
634*bb4ee6a4SAndroid Build Coastguard Worker             }
635*bb4ee6a4SAndroid Build Coastguard Worker         }
636*bb4ee6a4SAndroid Build Coastguard Worker     }
637*bb4ee6a4SAndroid Build Coastguard Worker 
set_regs(&mut self, regs: &Regs)638*bb4ee6a4SAndroid Build Coastguard Worker     fn set_regs(&mut self, regs: &Regs) {
639*bb4ee6a4SAndroid Build Coastguard Worker         self.state
640*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
641*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
642*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
643*bb4ee6a4SAndroid Build Coastguard Worker             .rax = regs.rax;
644*bb4ee6a4SAndroid Build Coastguard Worker         self.state
645*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
646*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
647*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_4
648*bb4ee6a4SAndroid Build Coastguard Worker             .rbx = regs.rbx;
649*bb4ee6a4SAndroid Build Coastguard Worker         self.state
650*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
651*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
652*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_2
653*bb4ee6a4SAndroid Build Coastguard Worker             .rcx = regs.rcx;
654*bb4ee6a4SAndroid Build Coastguard Worker         self.state
655*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
656*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
657*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_3
658*bb4ee6a4SAndroid Build Coastguard Worker             .rdx = regs.rdx;
659*bb4ee6a4SAndroid Build Coastguard Worker         self.state
660*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
661*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
662*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_7
663*bb4ee6a4SAndroid Build Coastguard Worker             .rsi = regs.rsi;
664*bb4ee6a4SAndroid Build Coastguard Worker         self.state
665*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
666*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
667*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_8
668*bb4ee6a4SAndroid Build Coastguard Worker             .rdi = regs.rdi;
669*bb4ee6a4SAndroid Build Coastguard Worker         self.state
670*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
671*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
672*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_5
673*bb4ee6a4SAndroid Build Coastguard Worker             .rsp = regs.rsp;
674*bb4ee6a4SAndroid Build Coastguard Worker         self.state
675*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
676*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_1
677*bb4ee6a4SAndroid Build Coastguard Worker             .__bindgen_anon_6
678*bb4ee6a4SAndroid Build Coastguard Worker             .rbp = regs.rbp;
679*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r8 = regs.r8;
680*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r9 = regs.r9;
681*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r10 = regs.r10;
682*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r11 = regs.r11;
683*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r12 = regs.r12;
684*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r13 = regs.r13;
685*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r14 = regs.r14;
686*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_1.__bindgen_anon_1.r15 = regs.r15;
687*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_2.rip = regs.rip;
688*bb4ee6a4SAndroid Build Coastguard Worker         self.state.__bindgen_anon_3.rflags = regs.rflags;
689*bb4ee6a4SAndroid Build Coastguard Worker     }
690*bb4ee6a4SAndroid Build Coastguard Worker 
get_sregs(&self) -> Sregs691*bb4ee6a4SAndroid Build Coastguard Worker     fn get_sregs(&self) -> Sregs {
692*bb4ee6a4SAndroid Build Coastguard Worker         Sregs {
693*bb4ee6a4SAndroid Build Coastguard Worker             cs: Segment::from(&self.state.cs),
694*bb4ee6a4SAndroid Build Coastguard Worker             ds: Segment::from(&self.state.ds),
695*bb4ee6a4SAndroid Build Coastguard Worker             es: Segment::from(&self.state.es),
696*bb4ee6a4SAndroid Build Coastguard Worker             fs: Segment::from(&self.state.fs),
697*bb4ee6a4SAndroid Build Coastguard Worker             gs: Segment::from(&self.state.gs),
698*bb4ee6a4SAndroid Build Coastguard Worker             ss: Segment::from(&self.state.ss),
699*bb4ee6a4SAndroid Build Coastguard Worker             tr: Segment::from(&self.state.tr),
700*bb4ee6a4SAndroid Build Coastguard Worker             ldt: Segment::from(&self.state.ldt),
701*bb4ee6a4SAndroid Build Coastguard Worker             gdt: DescriptorTable::from(&self.state.gdt),
702*bb4ee6a4SAndroid Build Coastguard Worker             idt: DescriptorTable::from(&self.state.idt),
703*bb4ee6a4SAndroid Build Coastguard Worker             cr0: self.state.cr0,
704*bb4ee6a4SAndroid Build Coastguard Worker             cr2: self.state.cr2,
705*bb4ee6a4SAndroid Build Coastguard Worker             cr3: self.state.cr3,
706*bb4ee6a4SAndroid Build Coastguard Worker             cr4: self.state.cr4,
707*bb4ee6a4SAndroid Build Coastguard Worker             // HAXM does not support setting cr8
708*bb4ee6a4SAndroid Build Coastguard Worker             cr8: 0,
709*bb4ee6a4SAndroid Build Coastguard Worker             efer: self.state.efer as u64,
710*bb4ee6a4SAndroid Build Coastguard Worker         }
711*bb4ee6a4SAndroid Build Coastguard Worker     }
712*bb4ee6a4SAndroid Build Coastguard Worker 
set_sregs(&mut self, sregs: &Sregs)713*bb4ee6a4SAndroid Build Coastguard Worker     fn set_sregs(&mut self, sregs: &Sregs) {
714*bb4ee6a4SAndroid Build Coastguard Worker         self.state.cs = segment_desc_t::from(&sregs.cs);
715*bb4ee6a4SAndroid Build Coastguard Worker         self.state.ds = segment_desc_t::from(&sregs.ds);
716*bb4ee6a4SAndroid Build Coastguard Worker         self.state.es = segment_desc_t::from(&sregs.es);
717*bb4ee6a4SAndroid Build Coastguard Worker         self.state.fs = segment_desc_t::from(&sregs.fs);
718*bb4ee6a4SAndroid Build Coastguard Worker         self.state.gs = segment_desc_t::from(&sregs.gs);
719*bb4ee6a4SAndroid Build Coastguard Worker         self.state.ss = segment_desc_t::from(&sregs.ss);
720*bb4ee6a4SAndroid Build Coastguard Worker         self.state.tr = segment_desc_t::from(&sregs.tr);
721*bb4ee6a4SAndroid Build Coastguard Worker         self.state.ldt = segment_desc_t::from(&sregs.ldt);
722*bb4ee6a4SAndroid Build Coastguard Worker         self.state.gdt = segment_desc_t::from(&sregs.gdt);
723*bb4ee6a4SAndroid Build Coastguard Worker         self.state.idt = segment_desc_t::from(&sregs.idt);
724*bb4ee6a4SAndroid Build Coastguard Worker         self.state.cr0 = sregs.cr0;
725*bb4ee6a4SAndroid Build Coastguard Worker         self.state.cr2 = sregs.cr2;
726*bb4ee6a4SAndroid Build Coastguard Worker         self.state.cr3 = sregs.cr3;
727*bb4ee6a4SAndroid Build Coastguard Worker         self.state.cr4 = sregs.cr4;
728*bb4ee6a4SAndroid Build Coastguard Worker         self.state.efer = sregs.efer as u32;
729*bb4ee6a4SAndroid Build Coastguard Worker     }
730*bb4ee6a4SAndroid Build Coastguard Worker 
get_debugregs(&self) -> DebugRegs731*bb4ee6a4SAndroid Build Coastguard Worker     fn get_debugregs(&self) -> DebugRegs {
732*bb4ee6a4SAndroid Build Coastguard Worker         DebugRegs {
733*bb4ee6a4SAndroid Build Coastguard Worker             db: [
734*bb4ee6a4SAndroid Build Coastguard Worker                 self.state.dr0,
735*bb4ee6a4SAndroid Build Coastguard Worker                 self.state.dr1,
736*bb4ee6a4SAndroid Build Coastguard Worker                 self.state.dr2,
737*bb4ee6a4SAndroid Build Coastguard Worker                 self.state.dr3,
738*bb4ee6a4SAndroid Build Coastguard Worker             ],
739*bb4ee6a4SAndroid Build Coastguard Worker             dr6: self.state.dr6,
740*bb4ee6a4SAndroid Build Coastguard Worker             dr7: self.state.dr7,
741*bb4ee6a4SAndroid Build Coastguard Worker         }
742*bb4ee6a4SAndroid Build Coastguard Worker     }
743*bb4ee6a4SAndroid Build Coastguard Worker 
set_debugregs(&mut self, debugregs: &DebugRegs)744*bb4ee6a4SAndroid Build Coastguard Worker     fn set_debugregs(&mut self, debugregs: &DebugRegs) {
745*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr0 = debugregs.db[0];
746*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr1 = debugregs.db[1];
747*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr2 = debugregs.db[2];
748*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr3 = debugregs.db[3];
749*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr6 = debugregs.dr6;
750*bb4ee6a4SAndroid Build Coastguard Worker         self.state.dr7 = debugregs.dr7;
751*bb4ee6a4SAndroid Build Coastguard Worker     }
752*bb4ee6a4SAndroid Build Coastguard Worker }
753*bb4ee6a4SAndroid Build Coastguard Worker 
754*bb4ee6a4SAndroid Build Coastguard Worker // HAXM's segment descriptor format matches exactly with the VMCS structure. The format
755*bb4ee6a4SAndroid Build Coastguard Worker // of the AR bits is described in the Intel System Programming Guide Part 3, chapter 24.4.1,
756*bb4ee6a4SAndroid Build Coastguard Worker // table 24-2. The main confusing thing is that the type_ field in haxm is 4 bits, meaning
757*bb4ee6a4SAndroid Build Coastguard Worker // the 3 least significant bits represent the normal type field, and the most significant
758*bb4ee6a4SAndroid Build Coastguard Worker // bit represents the "descriptor type" field.
759*bb4ee6a4SAndroid Build Coastguard Worker 
760*bb4ee6a4SAndroid Build Coastguard Worker impl From<&segment_desc_t> for Segment {
from(item: &segment_desc_t) -> Self761*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &segment_desc_t) -> Self {
762*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
763*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
764*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
765*bb4ee6a4SAndroid Build Coastguard Worker             Segment {
766*bb4ee6a4SAndroid Build Coastguard Worker                 base: item.base,
767*bb4ee6a4SAndroid Build Coastguard Worker                 limit_bytes: item.limit,
768*bb4ee6a4SAndroid Build Coastguard Worker                 selector: item.selector,
769*bb4ee6a4SAndroid Build Coastguard Worker                 type_: item.__bindgen_anon_1.__bindgen_anon_1.type_() as u8,
770*bb4ee6a4SAndroid Build Coastguard Worker                 present: item.__bindgen_anon_1.__bindgen_anon_1.present() as u8,
771*bb4ee6a4SAndroid Build Coastguard Worker                 dpl: item.__bindgen_anon_1.__bindgen_anon_1.dpl() as u8,
772*bb4ee6a4SAndroid Build Coastguard Worker                 db: item.__bindgen_anon_1.__bindgen_anon_1.operand_size() as u8,
773*bb4ee6a4SAndroid Build Coastguard Worker                 s: item.__bindgen_anon_1.__bindgen_anon_1.desc() as u8,
774*bb4ee6a4SAndroid Build Coastguard Worker                 l: item.__bindgen_anon_1.__bindgen_anon_1.long_mode() as u8,
775*bb4ee6a4SAndroid Build Coastguard Worker                 g: item.__bindgen_anon_1.__bindgen_anon_1.granularity() as u8,
776*bb4ee6a4SAndroid Build Coastguard Worker                 avl: item.__bindgen_anon_1.__bindgen_anon_1.available() as u8,
777*bb4ee6a4SAndroid Build Coastguard Worker             }
778*bb4ee6a4SAndroid Build Coastguard Worker         }
779*bb4ee6a4SAndroid Build Coastguard Worker     }
780*bb4ee6a4SAndroid Build Coastguard Worker }
781*bb4ee6a4SAndroid Build Coastguard Worker 
782*bb4ee6a4SAndroid Build Coastguard Worker impl From<&Segment> for segment_desc_t {
from(item: &Segment) -> Self783*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &Segment) -> Self {
784*bb4ee6a4SAndroid Build Coastguard Worker         let mut segment = segment_desc_t {
785*bb4ee6a4SAndroid Build Coastguard Worker             base: item.base,
786*bb4ee6a4SAndroid Build Coastguard Worker             limit: item.limit_bytes,
787*bb4ee6a4SAndroid Build Coastguard Worker             selector: item.selector,
788*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
789*bb4ee6a4SAndroid Build Coastguard Worker         };
790*bb4ee6a4SAndroid Build Coastguard Worker 
791*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
792*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
793*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
794*bb4ee6a4SAndroid Build Coastguard Worker             segment
795*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
796*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
797*bb4ee6a4SAndroid Build Coastguard Worker                 .set_type(item.type_ as u32);
798*bb4ee6a4SAndroid Build Coastguard Worker             segment
799*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
800*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
801*bb4ee6a4SAndroid Build Coastguard Worker                 .set_desc(item.s as u32);
802*bb4ee6a4SAndroid Build Coastguard Worker             segment
803*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
804*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
805*bb4ee6a4SAndroid Build Coastguard Worker                 .set_present(item.present as u32);
806*bb4ee6a4SAndroid Build Coastguard Worker             segment
807*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
808*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
809*bb4ee6a4SAndroid Build Coastguard Worker                 .set_dpl(item.dpl as u32);
810*bb4ee6a4SAndroid Build Coastguard Worker             segment
811*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
812*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
813*bb4ee6a4SAndroid Build Coastguard Worker                 .set_operand_size(item.db as u32);
814*bb4ee6a4SAndroid Build Coastguard Worker             segment
815*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
816*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
817*bb4ee6a4SAndroid Build Coastguard Worker                 .set_long_mode(item.l as u32);
818*bb4ee6a4SAndroid Build Coastguard Worker             segment
819*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
820*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
821*bb4ee6a4SAndroid Build Coastguard Worker                 .set_granularity(item.g as u32);
822*bb4ee6a4SAndroid Build Coastguard Worker             segment
823*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
824*bb4ee6a4SAndroid Build Coastguard Worker                 .__bindgen_anon_1
825*bb4ee6a4SAndroid Build Coastguard Worker                 .set_available(item.avl as u32);
826*bb4ee6a4SAndroid Build Coastguard Worker         }
827*bb4ee6a4SAndroid Build Coastguard Worker 
828*bb4ee6a4SAndroid Build Coastguard Worker         segment
829*bb4ee6a4SAndroid Build Coastguard Worker     }
830*bb4ee6a4SAndroid Build Coastguard Worker }
831*bb4ee6a4SAndroid Build Coastguard Worker 
832*bb4ee6a4SAndroid Build Coastguard Worker impl From<&segment_desc_t> for DescriptorTable {
from(item: &segment_desc_t) -> Self833*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &segment_desc_t) -> Self {
834*bb4ee6a4SAndroid Build Coastguard Worker         DescriptorTable {
835*bb4ee6a4SAndroid Build Coastguard Worker             base: item.base,
836*bb4ee6a4SAndroid Build Coastguard Worker             limit: item.limit as u16,
837*bb4ee6a4SAndroid Build Coastguard Worker         }
838*bb4ee6a4SAndroid Build Coastguard Worker     }
839*bb4ee6a4SAndroid Build Coastguard Worker }
840*bb4ee6a4SAndroid Build Coastguard Worker 
841*bb4ee6a4SAndroid Build Coastguard Worker impl From<&DescriptorTable> for segment_desc_t {
from(item: &DescriptorTable) -> Self842*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &DescriptorTable) -> Self {
843*bb4ee6a4SAndroid Build Coastguard Worker         segment_desc_t {
844*bb4ee6a4SAndroid Build Coastguard Worker             base: item.base,
845*bb4ee6a4SAndroid Build Coastguard Worker             limit: item.limit as u32,
846*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
847*bb4ee6a4SAndroid Build Coastguard Worker         }
848*bb4ee6a4SAndroid Build Coastguard Worker     }
849*bb4ee6a4SAndroid Build Coastguard Worker }
850*bb4ee6a4SAndroid Build Coastguard Worker 
851*bb4ee6a4SAndroid Build Coastguard Worker impl From<&fx_layout> for Fpu {
from(item: &fx_layout) -> Self852*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &fx_layout) -> Self {
853*bb4ee6a4SAndroid Build Coastguard Worker         let mut fpu = Fpu {
854*bb4ee6a4SAndroid Build Coastguard Worker             fpr: FpuReg::from_16byte_arrays(&item.st_mm),
855*bb4ee6a4SAndroid Build Coastguard Worker             fcw: item.fcw,
856*bb4ee6a4SAndroid Build Coastguard Worker             fsw: item.fsw,
857*bb4ee6a4SAndroid Build Coastguard Worker             ftwx: item.ftw,
858*bb4ee6a4SAndroid Build Coastguard Worker             last_opcode: item.fop,
859*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY: trivially safe
860*bb4ee6a4SAndroid Build Coastguard Worker             last_ip: unsafe { item.__bindgen_anon_1.fpu_ip },
861*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY: trivially safe
862*bb4ee6a4SAndroid Build Coastguard Worker             last_dp: unsafe { item.__bindgen_anon_2.fpu_dp },
863*bb4ee6a4SAndroid Build Coastguard Worker             xmm: [[0; 16]; 16],
864*bb4ee6a4SAndroid Build Coastguard Worker             mxcsr: item.mxcsr,
865*bb4ee6a4SAndroid Build Coastguard Worker         };
866*bb4ee6a4SAndroid Build Coastguard Worker 
867*bb4ee6a4SAndroid Build Coastguard Worker         fpu.xmm[..8].copy_from_slice(&item.mmx_1[..]);
868*bb4ee6a4SAndroid Build Coastguard Worker         fpu.xmm[8..].copy_from_slice(&item.mmx_2[..]);
869*bb4ee6a4SAndroid Build Coastguard Worker 
870*bb4ee6a4SAndroid Build Coastguard Worker         fpu
871*bb4ee6a4SAndroid Build Coastguard Worker     }
872*bb4ee6a4SAndroid Build Coastguard Worker }
873*bb4ee6a4SAndroid Build Coastguard Worker 
874*bb4ee6a4SAndroid Build Coastguard Worker impl From<&Fpu> for fx_layout {
from(item: &Fpu) -> Self875*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &Fpu) -> Self {
876*bb4ee6a4SAndroid Build Coastguard Worker         let mut fpu = fx_layout {
877*bb4ee6a4SAndroid Build Coastguard Worker             fcw: item.fcw,
878*bb4ee6a4SAndroid Build Coastguard Worker             fsw: item.fsw,
879*bb4ee6a4SAndroid Build Coastguard Worker             ftw: item.ftwx,
880*bb4ee6a4SAndroid Build Coastguard Worker             res1: 0,
881*bb4ee6a4SAndroid Build Coastguard Worker             fop: item.last_opcode,
882*bb4ee6a4SAndroid Build Coastguard Worker             __bindgen_anon_1: fx_layout__bindgen_ty_1 {
883*bb4ee6a4SAndroid Build Coastguard Worker                 fpu_ip: item.last_ip,
884*bb4ee6a4SAndroid Build Coastguard Worker             },
885*bb4ee6a4SAndroid Build Coastguard Worker             __bindgen_anon_2: fx_layout__bindgen_ty_2 {
886*bb4ee6a4SAndroid Build Coastguard Worker                 fpu_dp: item.last_dp,
887*bb4ee6a4SAndroid Build Coastguard Worker             },
888*bb4ee6a4SAndroid Build Coastguard Worker             mxcsr: item.mxcsr,
889*bb4ee6a4SAndroid Build Coastguard Worker             mxcsr_mask: 0,
890*bb4ee6a4SAndroid Build Coastguard Worker             st_mm: FpuReg::to_16byte_arrays(&item.fpr),
891*bb4ee6a4SAndroid Build Coastguard Worker             mmx_1: [[0; 16]; 8],
892*bb4ee6a4SAndroid Build Coastguard Worker             mmx_2: [[0; 16]; 8],
893*bb4ee6a4SAndroid Build Coastguard Worker             pad: [0; 96],
894*bb4ee6a4SAndroid Build Coastguard Worker         };
895*bb4ee6a4SAndroid Build Coastguard Worker 
896*bb4ee6a4SAndroid Build Coastguard Worker         fpu.mmx_1.copy_from_slice(&item.xmm[..8]);
897*bb4ee6a4SAndroid Build Coastguard Worker         fpu.mmx_2.copy_from_slice(&item.xmm[8..]);
898*bb4ee6a4SAndroid Build Coastguard Worker 
899*bb4ee6a4SAndroid Build Coastguard Worker         fpu
900*bb4ee6a4SAndroid Build Coastguard Worker     }
901*bb4ee6a4SAndroid Build Coastguard Worker }
902*bb4ee6a4SAndroid Build Coastguard Worker 
903*bb4ee6a4SAndroid Build Coastguard Worker impl From<&hax_cpuid_entry> for CpuIdEntry {
from(item: &hax_cpuid_entry) -> Self904*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &hax_cpuid_entry) -> Self {
905*bb4ee6a4SAndroid Build Coastguard Worker         CpuIdEntry {
906*bb4ee6a4SAndroid Build Coastguard Worker             function: item.function,
907*bb4ee6a4SAndroid Build Coastguard Worker             index: item.index,
908*bb4ee6a4SAndroid Build Coastguard Worker             flags: item.flags,
909*bb4ee6a4SAndroid Build Coastguard Worker             cpuid: CpuidResult {
910*bb4ee6a4SAndroid Build Coastguard Worker                 eax: item.eax,
911*bb4ee6a4SAndroid Build Coastguard Worker                 ebx: item.ebx,
912*bb4ee6a4SAndroid Build Coastguard Worker                 ecx: item.ecx,
913*bb4ee6a4SAndroid Build Coastguard Worker                 edx: item.edx,
914*bb4ee6a4SAndroid Build Coastguard Worker             },
915*bb4ee6a4SAndroid Build Coastguard Worker         }
916*bb4ee6a4SAndroid Build Coastguard Worker     }
917*bb4ee6a4SAndroid Build Coastguard Worker }
918*bb4ee6a4SAndroid Build Coastguard Worker 
919*bb4ee6a4SAndroid Build Coastguard Worker impl From<&CpuIdEntry> for hax_cpuid_entry {
from(item: &CpuIdEntry) -> Self920*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: &CpuIdEntry) -> Self {
921*bb4ee6a4SAndroid Build Coastguard Worker         hax_cpuid_entry {
922*bb4ee6a4SAndroid Build Coastguard Worker             function: item.function,
923*bb4ee6a4SAndroid Build Coastguard Worker             index: item.index,
924*bb4ee6a4SAndroid Build Coastguard Worker             flags: item.flags,
925*bb4ee6a4SAndroid Build Coastguard Worker             eax: item.cpuid.eax,
926*bb4ee6a4SAndroid Build Coastguard Worker             ebx: item.cpuid.ebx,
927*bb4ee6a4SAndroid Build Coastguard Worker             ecx: item.cpuid.ecx,
928*bb4ee6a4SAndroid Build Coastguard Worker             edx: item.cpuid.edx,
929*bb4ee6a4SAndroid Build Coastguard Worker             pad: Default::default(),
930*bb4ee6a4SAndroid Build Coastguard Worker         }
931*bb4ee6a4SAndroid Build Coastguard Worker     }
932*bb4ee6a4SAndroid Build Coastguard Worker }
933*bb4ee6a4SAndroid Build Coastguard Worker 
934*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b:241252288): Enable tests disabled with dummy feature flag - enable_haxm_tests.
935*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
936*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "enable_haxm_tests")]
937*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
938*bb4ee6a4SAndroid Build Coastguard Worker     use vm_memory::GuestAddress;
939*bb4ee6a4SAndroid Build Coastguard Worker     use vm_memory::GuestMemory;
940*bb4ee6a4SAndroid Build Coastguard Worker 
941*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
942*bb4ee6a4SAndroid Build Coastguard Worker     use crate::VmX86_64;
943*bb4ee6a4SAndroid Build Coastguard Worker 
944*bb4ee6a4SAndroid Build Coastguard Worker     // EFER Bits
945*bb4ee6a4SAndroid Build Coastguard Worker     const EFER_SCE: u64 = 0x00000001;
946*bb4ee6a4SAndroid Build Coastguard Worker     const EFER_LME: u64 = 0x00000100;
947*bb4ee6a4SAndroid Build Coastguard Worker     const EFER_LMA: u64 = 0x00000400;
948*bb4ee6a4SAndroid Build Coastguard Worker     const EFER_SVME: u64 = 1 << 12;
949*bb4ee6a4SAndroid Build Coastguard Worker 
950*bb4ee6a4SAndroid Build Coastguard Worker     // CR0 bits
951*bb4ee6a4SAndroid Build Coastguard Worker     const CR0_PG: u64 = 1 << 31;
952*bb4ee6a4SAndroid Build Coastguard Worker 
953*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
get_regs()954*bb4ee6a4SAndroid Build Coastguard Worker     fn get_regs() {
955*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
956*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
957*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
958*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
959*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
960*bb4ee6a4SAndroid Build Coastguard Worker 
961*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.get_regs().expect("failed to get regs");
962*bb4ee6a4SAndroid Build Coastguard Worker     }
963*bb4ee6a4SAndroid Build Coastguard Worker 
964*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
get_fpu()965*bb4ee6a4SAndroid Build Coastguard Worker     fn get_fpu() {
966*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
967*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
968*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
969*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
970*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
971*bb4ee6a4SAndroid Build Coastguard Worker 
972*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.get_fpu().expect("failed to get fpu");
973*bb4ee6a4SAndroid Build Coastguard Worker     }
974*bb4ee6a4SAndroid Build Coastguard Worker 
975*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
set_msr()976*bb4ee6a4SAndroid Build Coastguard Worker     fn set_msr() {
977*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
978*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
979*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
980*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
981*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
982*bb4ee6a4SAndroid Build Coastguard Worker 
983*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.set_msr(38, 0x300).expect("failed to set MSR");
984*bb4ee6a4SAndroid Build Coastguard Worker     }
985*bb4ee6a4SAndroid Build Coastguard Worker 
986*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
get_msr()987*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr() {
988*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
989*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
990*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
991*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
992*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
993*bb4ee6a4SAndroid Build Coastguard Worker 
994*bb4ee6a4SAndroid Build Coastguard Worker         let _value = vcpu.get_msr(38).expect("failed to get MSR");
995*bb4ee6a4SAndroid Build Coastguard Worker     }
996*bb4ee6a4SAndroid Build Coastguard Worker 
997*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
set_cpuid()998*bb4ee6a4SAndroid Build Coastguard Worker     fn set_cpuid() {
999*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
1000*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
1001*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
1002*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
1003*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
1004*bb4ee6a4SAndroid Build Coastguard Worker 
1005*bb4ee6a4SAndroid Build Coastguard Worker         let mut cpuid = haxm
1006*bb4ee6a4SAndroid Build Coastguard Worker             .get_supported_cpuid()
1007*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to get supported cpuids");
1008*bb4ee6a4SAndroid Build Coastguard Worker         for entry in &mut cpuid.cpu_id_entries {
1009*bb4ee6a4SAndroid Build Coastguard Worker             if entry.function == 1 {
1010*bb4ee6a4SAndroid Build Coastguard Worker                 // Disable XSAVE and OSXSAVE
1011*bb4ee6a4SAndroid Build Coastguard Worker                 entry.cpuid.ecx &= !(1 << 26);
1012*bb4ee6a4SAndroid Build Coastguard Worker                 entry.cpuid.ecx &= !(1 << 27);
1013*bb4ee6a4SAndroid Build Coastguard Worker             }
1014*bb4ee6a4SAndroid Build Coastguard Worker         }
1015*bb4ee6a4SAndroid Build Coastguard Worker 
1016*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.set_cpuid(&cpuid).expect("failed to set cpuid");
1017*bb4ee6a4SAndroid Build Coastguard Worker     }
1018*bb4ee6a4SAndroid Build Coastguard Worker 
1019*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
set_efer()1020*bb4ee6a4SAndroid Build Coastguard Worker     fn set_efer() {
1021*bb4ee6a4SAndroid Build Coastguard Worker         // HAXM efer setting requires some extra code, so we have this test specifically
1022*bb4ee6a4SAndroid Build Coastguard Worker         // checking that it's working.
1023*bb4ee6a4SAndroid Build Coastguard Worker         let haxm = Haxm::new().expect("failed to instantiate HAXM");
1024*bb4ee6a4SAndroid Build Coastguard Worker         let mem =
1025*bb4ee6a4SAndroid Build Coastguard Worker             GuestMemory::new(&[(GuestAddress(0), 0x1000)]).expect("failed to create guest memory");
1026*bb4ee6a4SAndroid Build Coastguard Worker         let vm = HaxmVm::new(&haxm, mem).expect("failed to create vm");
1027*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = vm.create_vcpu(0).expect("failed to create vcpu");
1028*bb4ee6a4SAndroid Build Coastguard Worker 
1029*bb4ee6a4SAndroid Build Coastguard Worker         let mut sregs = vcpu.get_sregs().expect("failed to get sregs");
1030*bb4ee6a4SAndroid Build Coastguard Worker         // Initial value should be 0
1031*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(sregs.efer & !EFER_SVME, 0);
1032*bb4ee6a4SAndroid Build Coastguard Worker 
1033*bb4ee6a4SAndroid Build Coastguard Worker         // Enable and activate long mode
1034*bb4ee6a4SAndroid Build Coastguard Worker         sregs.efer = EFER_LMA | EFER_LME;
1035*bb4ee6a4SAndroid Build Coastguard Worker         // Need to enable paging or LMA will be turned off
1036*bb4ee6a4SAndroid Build Coastguard Worker         sregs.cr0 |= CR0_PG;
1037*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.set_sregs(&sregs).expect("failed to set sregs");
1038*bb4ee6a4SAndroid Build Coastguard Worker 
1039*bb4ee6a4SAndroid Build Coastguard Worker         // Verify that setting stuck
1040*bb4ee6a4SAndroid Build Coastguard Worker         let sregs = vcpu.get_sregs().expect("failed to get sregs");
1041*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(sregs.efer & !EFER_SVME, EFER_LMA | EFER_LME);
1042*bb4ee6a4SAndroid Build Coastguard Worker 
1043*bb4ee6a4SAndroid Build Coastguard Worker         // IA32_EFER register value should match
1044*bb4ee6a4SAndroid Build Coastguard Worker         let efer = vcpu.get_msr(IA32_EFER).expect("failed to get msr");
1045*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(efer & !EFER_SVME, EFER_LMA | EFER_LME);
1046*bb4ee6a4SAndroid Build Coastguard Worker 
1047*bb4ee6a4SAndroid Build Coastguard Worker         // Enable SCE via set_msrs
1048*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.set_msr(IA32_EFER, efer | EFER_SCE)
1049*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to set msr");
1050*bb4ee6a4SAndroid Build Coastguard Worker 
1051*bb4ee6a4SAndroid Build Coastguard Worker         // Verify that setting stuck
1052*bb4ee6a4SAndroid Build Coastguard Worker         let sregs = vcpu.get_sregs().expect("failed to get sregs");
1053*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(sregs.efer & !EFER_SVME, EFER_SCE | EFER_LME | EFER_LMA);
1054*bb4ee6a4SAndroid Build Coastguard Worker         let new_efer = vcpu.get_msr(IA32_EFER).expect("failed to get msrs");
1055*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(new_efer & !EFER_SVME, EFER_SCE | EFER_LME | EFER_LMA);
1056*bb4ee6a4SAndroid Build Coastguard Worker     }
1057*bb4ee6a4SAndroid Build Coastguard Worker }
1058