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