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 //! A crate for abstracting the underlying kernel hypervisor used in crosvm. 6*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 7*bb4ee6a4SAndroid Build Coastguard Worker pub mod aarch64; 8*bb4ee6a4SAndroid Build Coastguard Worker pub mod caps; 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all( 11*bb4ee6a4SAndroid Build Coastguard Worker unix, 12*bb4ee6a4SAndroid Build Coastguard Worker any(target_arch = "arm", target_arch = "aarch64"), 13*bb4ee6a4SAndroid Build Coastguard Worker feature = "gunyah" 14*bb4ee6a4SAndroid Build Coastguard Worker ))] 15*bb4ee6a4SAndroid Build Coastguard Worker pub mod gunyah; 16*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all(windows, feature = "haxm"))] 17*bb4ee6a4SAndroid Build Coastguard Worker pub mod haxm; 18*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 19*bb4ee6a4SAndroid Build Coastguard Worker pub mod kvm; 20*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "riscv64")] 21*bb4ee6a4SAndroid Build Coastguard Worker pub mod riscv64; 22*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all(windows, feature = "whpx"))] 23*bb4ee6a4SAndroid Build Coastguard Worker pub mod whpx; 24*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")] 25*bb4ee6a4SAndroid Build Coastguard Worker pub mod x86_64; 26*bb4ee6a4SAndroid Build Coastguard Worker 27*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 28*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all(unix, feature = "geniezone"))] 29*bb4ee6a4SAndroid Build Coastguard Worker pub mod geniezone; 30*bb4ee6a4SAndroid Build Coastguard Worker 31*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor; 32*bb4ee6a4SAndroid Build Coastguard Worker use base::Event; 33*bb4ee6a4SAndroid Build Coastguard Worker use base::MappedRegion; 34*bb4ee6a4SAndroid Build Coastguard Worker use base::Protection; 35*bb4ee6a4SAndroid Build Coastguard Worker use base::Result; 36*bb4ee6a4SAndroid Build Coastguard Worker use base::SafeDescriptor; 37*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 38*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 39*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress; 40*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestMemory; 41*bb4ee6a4SAndroid Build Coastguard Worker 42*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 43*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::aarch64::*; 44*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::caps::*; 45*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "riscv64")] 46*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::riscv64::*; 47*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")] 48*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::x86_64::*; 49*bb4ee6a4SAndroid Build Coastguard Worker 50*bb4ee6a4SAndroid Build Coastguard Worker /// An index in the list of guest-mapped memory regions. 51*bb4ee6a4SAndroid Build Coastguard Worker pub type MemSlot = u32; 52*bb4ee6a4SAndroid Build Coastguard Worker 53*bb4ee6a4SAndroid Build Coastguard Worker /// Range of GPA space. Starting from `guest_address` up to `size`. 54*bb4ee6a4SAndroid Build Coastguard Worker pub struct MemRegion { 55*bb4ee6a4SAndroid Build Coastguard Worker pub guest_address: GuestAddress, 56*bb4ee6a4SAndroid Build Coastguard Worker pub size: u64, 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker 59*bb4ee6a4SAndroid Build Coastguard Worker /// Signal to the hypervisor on kernels that support the KVM_CAP_USER_CONFIGURE_NONCOHERENT_DMA (or 60*bb4ee6a4SAndroid Build Coastguard Worker /// equivalent) that during user memory region (memslot) configuration, a guest page's memtype 61*bb4ee6a4SAndroid Build Coastguard Worker /// should be considered in SLAT effective memtype determination rather than implicitly respecting 62*bb4ee6a4SAndroid Build Coastguard Worker /// only the host page's memtype. 63*bb4ee6a4SAndroid Build Coastguard Worker /// 64*bb4ee6a4SAndroid Build Coastguard Worker /// This explicit control is needed for Virtio devices (e.g. gpu) that configure memslots for host 65*bb4ee6a4SAndroid Build Coastguard Worker /// WB page mappings with guest WC page mappings. See b/316337317, b/360295883 for more detail. 66*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] 67*bb4ee6a4SAndroid Build Coastguard Worker pub enum MemCacheType { 68*bb4ee6a4SAndroid Build Coastguard Worker /// Don't provide any explicit instruction to the hypervisor on how it should determine a 69*bb4ee6a4SAndroid Build Coastguard Worker /// memslot's effective memtype. 70*bb4ee6a4SAndroid Build Coastguard Worker /// 71*bb4ee6a4SAndroid Build Coastguard Worker /// On KVM-VMX (Intel), this means that the memslot is flagged with VMX_EPT_IPAT_BIT such that 72*bb4ee6a4SAndroid Build Coastguard Worker /// only the host memtype is respected. 73*bb4ee6a4SAndroid Build Coastguard Worker CacheCoherent, 74*bb4ee6a4SAndroid Build Coastguard Worker /// explicitly instruct the hypervisor to respect the guest page's memtype when determining the 75*bb4ee6a4SAndroid Build Coastguard Worker /// memslot's effective memtype. 76*bb4ee6a4SAndroid Build Coastguard Worker /// 77*bb4ee6a4SAndroid Build Coastguard Worker /// On KVM-VMX (Intel), this means the memslot is NOT flagged with VMX_EPT_IPAT_BIT, and the 78*bb4ee6a4SAndroid Build Coastguard Worker /// effective memtype will generally decay to the weaker amongst the host/guest memtypes and 79*bb4ee6a4SAndroid Build Coastguard Worker /// the MTRR for the physical address. 80*bb4ee6a4SAndroid Build Coastguard Worker CacheNonCoherent, 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker 83*bb4ee6a4SAndroid Build Coastguard Worker /// This is intended for use with virtio-balloon, where a guest driver determines unused ranges and 84*bb4ee6a4SAndroid Build Coastguard Worker /// requests they be freed. Use without the guest's knowledge is sure to break something. 85*bb4ee6a4SAndroid Build Coastguard Worker pub enum BalloonEvent { 86*bb4ee6a4SAndroid Build Coastguard Worker /// Balloon event when the region is acquired from the guest. The guest cannot access this 87*bb4ee6a4SAndroid Build Coastguard Worker /// region any more. The guest memory can be reclaimed by the host OS. As per virtio-balloon 88*bb4ee6a4SAndroid Build Coastguard Worker /// spec, the given address and size are intended to be page-aligned. 89*bb4ee6a4SAndroid Build Coastguard Worker Inflate(MemRegion), 90*bb4ee6a4SAndroid Build Coastguard Worker /// Balloon event when the region is returned to the guest. VMM should reallocate memory and 91*bb4ee6a4SAndroid Build Coastguard Worker /// register it with the hypervisor for accesses by the guest. 92*bb4ee6a4SAndroid Build Coastguard Worker Deflate(MemRegion), 93*bb4ee6a4SAndroid Build Coastguard Worker /// Balloon event when the requested memory size is achieved. This can be achieved through 94*bb4ee6a4SAndroid Build Coastguard Worker /// either inflation or deflation. The `u64` will be the current size of the balloon in bytes. 95*bb4ee6a4SAndroid Build Coastguard Worker BalloonTargetReached(u64), 96*bb4ee6a4SAndroid Build Coastguard Worker } 97*bb4ee6a4SAndroid Build Coastguard Worker 98*bb4ee6a4SAndroid Build Coastguard Worker /// A trait for checking hypervisor capabilities. 99*bb4ee6a4SAndroid Build Coastguard Worker pub trait Hypervisor: Send { 100*bb4ee6a4SAndroid Build Coastguard Worker /// Makes a shallow clone of this `Hypervisor`. try_clone(&self) -> Result<Self> where Self: Sized101*bb4ee6a4SAndroid Build Coastguard Worker fn try_clone(&self) -> Result<Self> 102*bb4ee6a4SAndroid Build Coastguard Worker where 103*bb4ee6a4SAndroid Build Coastguard Worker Self: Sized; 104*bb4ee6a4SAndroid Build Coastguard Worker 105*bb4ee6a4SAndroid Build Coastguard Worker /// Checks if a particular `HypervisorCap` is available. check_capability(&self, cap: HypervisorCap) -> bool106*bb4ee6a4SAndroid Build Coastguard Worker fn check_capability(&self, cap: HypervisorCap) -> bool; 107*bb4ee6a4SAndroid Build Coastguard Worker } 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper for using a VM and getting/setting its state. 110*bb4ee6a4SAndroid Build Coastguard Worker pub trait Vm: Send { 111*bb4ee6a4SAndroid Build Coastguard Worker /// Makes a shallow clone of this `Vm`. try_clone(&self) -> Result<Self> where Self: Sized112*bb4ee6a4SAndroid Build Coastguard Worker fn try_clone(&self) -> Result<Self> 113*bb4ee6a4SAndroid Build Coastguard Worker where 114*bb4ee6a4SAndroid Build Coastguard Worker Self: Sized; 115*bb4ee6a4SAndroid Build Coastguard Worker 116*bb4ee6a4SAndroid Build Coastguard Worker /// Checks if a particular `VmCap` is available. 117*bb4ee6a4SAndroid Build Coastguard Worker /// 118*bb4ee6a4SAndroid Build Coastguard Worker /// This is distinct from the `Hypervisor` version of this method because some extensions depend 119*bb4ee6a4SAndroid Build Coastguard Worker /// on the particular `Vm` instance. This method is encouraged because it more accurately 120*bb4ee6a4SAndroid Build Coastguard Worker /// reflects the usable capabilities. check_capability(&self, c: VmCap) -> bool121*bb4ee6a4SAndroid Build Coastguard Worker fn check_capability(&self, c: VmCap) -> bool; 122*bb4ee6a4SAndroid Build Coastguard Worker 123*bb4ee6a4SAndroid Build Coastguard Worker /// Enable the VM capabilities. enable_capability(&self, _capability: VmCap, _flags: u32) -> Result<bool>124*bb4ee6a4SAndroid Build Coastguard Worker fn enable_capability(&self, _capability: VmCap, _flags: u32) -> Result<bool> { 125*bb4ee6a4SAndroid Build Coastguard Worker Err(std::io::Error::from(std::io::ErrorKind::Unsupported).into()) 126*bb4ee6a4SAndroid Build Coastguard Worker } 127*bb4ee6a4SAndroid Build Coastguard Worker 128*bb4ee6a4SAndroid Build Coastguard Worker /// Get the guest physical address size in bits. get_guest_phys_addr_bits(&self) -> u8129*bb4ee6a4SAndroid Build Coastguard Worker fn get_guest_phys_addr_bits(&self) -> u8; 130*bb4ee6a4SAndroid Build Coastguard Worker 131*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the guest-mapped memory for the Vm. get_memory(&self) -> &GuestMemory132*bb4ee6a4SAndroid Build Coastguard Worker fn get_memory(&self) -> &GuestMemory; 133*bb4ee6a4SAndroid Build Coastguard Worker 134*bb4ee6a4SAndroid Build Coastguard Worker /// Inserts the given `MappedRegion` into the VM's address space at `guest_addr`. 135*bb4ee6a4SAndroid Build Coastguard Worker /// 136*bb4ee6a4SAndroid Build Coastguard Worker /// The slot that was assigned the memory mapping is returned on success. The slot can be given 137*bb4ee6a4SAndroid Build Coastguard Worker /// to `Vm::remove_memory_region` to remove the memory from the VM's address space and take back 138*bb4ee6a4SAndroid Build Coastguard Worker /// ownership of `mem_region`. 139*bb4ee6a4SAndroid Build Coastguard Worker /// 140*bb4ee6a4SAndroid Build Coastguard Worker /// Note that memory inserted into the VM's address space must not overlap with any other memory 141*bb4ee6a4SAndroid Build Coastguard Worker /// slot's region. 142*bb4ee6a4SAndroid Build Coastguard Worker /// 143*bb4ee6a4SAndroid Build Coastguard Worker /// If `read_only` is true, the guest will be able to read the memory as normal, but attempts to 144*bb4ee6a4SAndroid Build Coastguard Worker /// write will trigger a mmio VM exit, leaving the memory untouched. 145*bb4ee6a4SAndroid Build Coastguard Worker /// 146*bb4ee6a4SAndroid Build Coastguard Worker /// If `log_dirty_pages` is true, the slot number can be used to retrieve the pages written to 147*bb4ee6a4SAndroid Build Coastguard Worker /// by the guest with `get_dirty_log`. 148*bb4ee6a4SAndroid Build Coastguard Worker /// 149*bb4ee6a4SAndroid Build Coastguard Worker /// `cache` can be used to set guest mem cache attribute if supported. Default is cache coherent 150*bb4ee6a4SAndroid Build Coastguard Worker /// memory. Noncoherent memory means this memory might not be coherent from all access points, 151*bb4ee6a4SAndroid Build Coastguard Worker /// e.g this could be the case when host GPU doesn't set the memory to be coherent with CPU 152*bb4ee6a4SAndroid Build Coastguard Worker /// access. Setting this attribute would allow hypervisor to adjust guest mem control to ensure 153*bb4ee6a4SAndroid Build Coastguard Worker /// synchronized guest access in noncoherent DMA case. add_memory_region( &mut self, guest_addr: GuestAddress, mem_region: Box<dyn MappedRegion>, read_only: bool, log_dirty_pages: bool, cache: MemCacheType, ) -> Result<MemSlot>154*bb4ee6a4SAndroid Build Coastguard Worker fn add_memory_region( 155*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 156*bb4ee6a4SAndroid Build Coastguard Worker guest_addr: GuestAddress, 157*bb4ee6a4SAndroid Build Coastguard Worker mem_region: Box<dyn MappedRegion>, 158*bb4ee6a4SAndroid Build Coastguard Worker read_only: bool, 159*bb4ee6a4SAndroid Build Coastguard Worker log_dirty_pages: bool, 160*bb4ee6a4SAndroid Build Coastguard Worker cache: MemCacheType, 161*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<MemSlot>; 162*bb4ee6a4SAndroid Build Coastguard Worker 163*bb4ee6a4SAndroid Build Coastguard Worker /// Does a synchronous msync of the memory mapped at `slot`, syncing `size` bytes starting at 164*bb4ee6a4SAndroid Build Coastguard Worker /// `offset` from the start of the region. `offset` must be page aligned. msync_memory_region(&mut self, slot: MemSlot, offset: usize, size: usize) -> Result<()>165*bb4ee6a4SAndroid Build Coastguard Worker fn msync_memory_region(&mut self, slot: MemSlot, offset: usize, size: usize) -> Result<()>; 166*bb4ee6a4SAndroid Build Coastguard Worker 167*bb4ee6a4SAndroid Build Coastguard Worker /// Gives a MADV_PAGEOUT advice to the memory region mapped at `slot`, with the address range 168*bb4ee6a4SAndroid Build Coastguard Worker /// starting at `offset` from the start of the region, and with size `size`. `offset` 169*bb4ee6a4SAndroid Build Coastguard Worker /// must be page aligned. 170*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] madvise_pageout_memory_region( &mut self, slot: MemSlot, offset: usize, size: usize, ) -> Result<()>171*bb4ee6a4SAndroid Build Coastguard Worker fn madvise_pageout_memory_region( 172*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 173*bb4ee6a4SAndroid Build Coastguard Worker slot: MemSlot, 174*bb4ee6a4SAndroid Build Coastguard Worker offset: usize, 175*bb4ee6a4SAndroid Build Coastguard Worker size: usize, 176*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 177*bb4ee6a4SAndroid Build Coastguard Worker 178*bb4ee6a4SAndroid Build Coastguard Worker /// Gives a MADV_REMOVE advice to the memory region mapped at `slot`, with the address range 179*bb4ee6a4SAndroid Build Coastguard Worker /// starting at `offset` from the start of the region, and with size `size`. `offset` 180*bb4ee6a4SAndroid Build Coastguard Worker /// must be page aligned. 181*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] madvise_remove_memory_region( &mut self, slot: MemSlot, offset: usize, size: usize, ) -> Result<()>182*bb4ee6a4SAndroid Build Coastguard Worker fn madvise_remove_memory_region( 183*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 184*bb4ee6a4SAndroid Build Coastguard Worker slot: MemSlot, 185*bb4ee6a4SAndroid Build Coastguard Worker offset: usize, 186*bb4ee6a4SAndroid Build Coastguard Worker size: usize, 187*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 188*bb4ee6a4SAndroid Build Coastguard Worker 189*bb4ee6a4SAndroid Build Coastguard Worker /// Removes and drops the `UserMemoryRegion` that was previously added at the given slot. remove_memory_region(&mut self, slot: MemSlot) -> Result<Box<dyn MappedRegion>>190*bb4ee6a4SAndroid Build Coastguard Worker fn remove_memory_region(&mut self, slot: MemSlot) -> Result<Box<dyn MappedRegion>>; 191*bb4ee6a4SAndroid Build Coastguard Worker 192*bb4ee6a4SAndroid Build Coastguard Worker /// Creates an emulated device. create_device(&self, kind: DeviceKind) -> Result<SafeDescriptor>193*bb4ee6a4SAndroid Build Coastguard Worker fn create_device(&self, kind: DeviceKind) -> Result<SafeDescriptor>; 194*bb4ee6a4SAndroid Build Coastguard Worker 195*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the bitmap of dirty pages since the last call to `get_dirty_log` for the memory at 196*bb4ee6a4SAndroid Build Coastguard Worker /// `slot`. Only works on VMs that support `VmCap::DirtyLog`. 197*bb4ee6a4SAndroid Build Coastguard Worker /// 198*bb4ee6a4SAndroid Build Coastguard Worker /// The size of `dirty_log` must be at least as many bits as there are pages in the memory 199*bb4ee6a4SAndroid Build Coastguard Worker /// region `slot` represents. For example, if the size of `slot` is 16 pages, `dirty_log` must 200*bb4ee6a4SAndroid Build Coastguard Worker /// be 2 bytes or greater. get_dirty_log(&self, slot: MemSlot, dirty_log: &mut [u8]) -> Result<()>201*bb4ee6a4SAndroid Build Coastguard Worker fn get_dirty_log(&self, slot: MemSlot, dirty_log: &mut [u8]) -> Result<()>; 202*bb4ee6a4SAndroid Build Coastguard Worker 203*bb4ee6a4SAndroid Build Coastguard Worker /// Registers an event to be signaled whenever a certain address is written to. 204*bb4ee6a4SAndroid Build Coastguard Worker /// 205*bb4ee6a4SAndroid Build Coastguard Worker /// The `datamatch` parameter can be used to limit signaling `evt` to only the cases where the 206*bb4ee6a4SAndroid Build Coastguard Worker /// value being written is equal to `datamatch`. Note that the size of `datamatch` is important 207*bb4ee6a4SAndroid Build Coastguard Worker /// and must match the expected size of the guest's write. 208*bb4ee6a4SAndroid Build Coastguard Worker /// 209*bb4ee6a4SAndroid Build Coastguard Worker /// In all cases where `evt` is signaled, the ordinary vmexit to userspace that would be 210*bb4ee6a4SAndroid Build Coastguard Worker /// triggered is prevented. register_ioevent( &mut self, evt: &Event, addr: IoEventAddress, datamatch: Datamatch, ) -> Result<()>211*bb4ee6a4SAndroid Build Coastguard Worker fn register_ioevent( 212*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 213*bb4ee6a4SAndroid Build Coastguard Worker evt: &Event, 214*bb4ee6a4SAndroid Build Coastguard Worker addr: IoEventAddress, 215*bb4ee6a4SAndroid Build Coastguard Worker datamatch: Datamatch, 216*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 217*bb4ee6a4SAndroid Build Coastguard Worker 218*bb4ee6a4SAndroid Build Coastguard Worker /// Unregisters an event previously registered with `register_ioevent`. 219*bb4ee6a4SAndroid Build Coastguard Worker /// 220*bb4ee6a4SAndroid Build Coastguard Worker /// The `evt`, `addr`, and `datamatch` set must be the same as the ones passed into 221*bb4ee6a4SAndroid Build Coastguard Worker /// `register_ioevent`. unregister_ioevent( &mut self, evt: &Event, addr: IoEventAddress, datamatch: Datamatch, ) -> Result<()>222*bb4ee6a4SAndroid Build Coastguard Worker fn unregister_ioevent( 223*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 224*bb4ee6a4SAndroid Build Coastguard Worker evt: &Event, 225*bb4ee6a4SAndroid Build Coastguard Worker addr: IoEventAddress, 226*bb4ee6a4SAndroid Build Coastguard Worker datamatch: Datamatch, 227*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 228*bb4ee6a4SAndroid Build Coastguard Worker 229*bb4ee6a4SAndroid Build Coastguard Worker /// Trigger any matching registered io events based on an MMIO or PIO write at `addr`. The 230*bb4ee6a4SAndroid Build Coastguard Worker /// `data` slice represents the contents and length of the write, which is used to compare with 231*bb4ee6a4SAndroid Build Coastguard Worker /// the registered io events' Datamatch values. If the hypervisor does in-kernel IO event 232*bb4ee6a4SAndroid Build Coastguard Worker /// delivery, this is a no-op. handle_io_events(&self, addr: IoEventAddress, data: &[u8]) -> Result<()>233*bb4ee6a4SAndroid Build Coastguard Worker fn handle_io_events(&self, addr: IoEventAddress, data: &[u8]) -> Result<()>; 234*bb4ee6a4SAndroid Build Coastguard Worker 235*bb4ee6a4SAndroid Build Coastguard Worker /// Retrieves the current timestamp of the paravirtual clock as seen by the current guest. 236*bb4ee6a4SAndroid Build Coastguard Worker /// Only works on VMs that support `VmCap::PvClock`. get_pvclock(&self) -> Result<ClockState>237*bb4ee6a4SAndroid Build Coastguard Worker fn get_pvclock(&self) -> Result<ClockState>; 238*bb4ee6a4SAndroid Build Coastguard Worker 239*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the current timestamp of the paravirtual clock as seen by the current guest. 240*bb4ee6a4SAndroid Build Coastguard Worker /// Only works on VMs that support `VmCap::PvClock`. set_pvclock(&self, state: &ClockState) -> Result<()>241*bb4ee6a4SAndroid Build Coastguard Worker fn set_pvclock(&self, state: &ClockState) -> Result<()>; 242*bb4ee6a4SAndroid Build Coastguard Worker 243*bb4ee6a4SAndroid Build Coastguard Worker /// Maps `size` bytes starting at `fs_offset` bytes from within the given `fd` 244*bb4ee6a4SAndroid Build Coastguard Worker /// at `offset` bytes from the start of the arena with `prot` protections. 245*bb4ee6a4SAndroid Build Coastguard Worker /// `offset` must be page aligned. 246*bb4ee6a4SAndroid Build Coastguard Worker /// 247*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments 248*bb4ee6a4SAndroid Build Coastguard Worker /// * `offset` - Page aligned offset into the arena in bytes. 249*bb4ee6a4SAndroid Build Coastguard Worker /// * `size` - Size of memory region in bytes. 250*bb4ee6a4SAndroid Build Coastguard Worker /// * `fd` - File descriptor to mmap from. 251*bb4ee6a4SAndroid Build Coastguard Worker /// * `fd_offset` - Offset in bytes from the beginning of `fd` to start the mmap. 252*bb4ee6a4SAndroid Build Coastguard Worker /// * `prot` - Protection (e.g. readable/writable) of the memory region. add_fd_mapping( &mut self, slot: u32, offset: usize, size: usize, fd: &dyn AsRawDescriptor, fd_offset: u64, prot: Protection, ) -> Result<()>253*bb4ee6a4SAndroid Build Coastguard Worker fn add_fd_mapping( 254*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 255*bb4ee6a4SAndroid Build Coastguard Worker slot: u32, 256*bb4ee6a4SAndroid Build Coastguard Worker offset: usize, 257*bb4ee6a4SAndroid Build Coastguard Worker size: usize, 258*bb4ee6a4SAndroid Build Coastguard Worker fd: &dyn AsRawDescriptor, 259*bb4ee6a4SAndroid Build Coastguard Worker fd_offset: u64, 260*bb4ee6a4SAndroid Build Coastguard Worker prot: Protection, 261*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 262*bb4ee6a4SAndroid Build Coastguard Worker 263*bb4ee6a4SAndroid Build Coastguard Worker /// Remove `size`-byte mapping starting at `offset`. remove_mapping(&mut self, slot: u32, offset: usize, size: usize) -> Result<()>264*bb4ee6a4SAndroid Build Coastguard Worker fn remove_mapping(&mut self, slot: u32, offset: usize, size: usize) -> Result<()>; 265*bb4ee6a4SAndroid Build Coastguard Worker 266*bb4ee6a4SAndroid Build Coastguard Worker /// Events from virtio-balloon that affect the state for guest memory and host memory. handle_balloon_event(&mut self, event: BalloonEvent) -> Result<()>267*bb4ee6a4SAndroid Build Coastguard Worker fn handle_balloon_event(&mut self, event: BalloonEvent) -> Result<()>; 268*bb4ee6a4SAndroid Build Coastguard Worker } 269*bb4ee6a4SAndroid Build Coastguard Worker 270*bb4ee6a4SAndroid Build Coastguard Worker /// Operation for Io and Mmio 271*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug)] 272*bb4ee6a4SAndroid Build Coastguard Worker pub enum IoOperation<'a> { 273*bb4ee6a4SAndroid Build Coastguard Worker /// Data to be read from a device on the bus. 274*bb4ee6a4SAndroid Build Coastguard Worker /// 275*bb4ee6a4SAndroid Build Coastguard Worker /// The `handle_fn` should fill the entire slice with the read data. 276*bb4ee6a4SAndroid Build Coastguard Worker Read(&'a mut [u8]), 277*bb4ee6a4SAndroid Build Coastguard Worker 278*bb4ee6a4SAndroid Build Coastguard Worker /// Data to be written to a device on the bus. 279*bb4ee6a4SAndroid Build Coastguard Worker Write(&'a [u8]), 280*bb4ee6a4SAndroid Build Coastguard Worker } 281*bb4ee6a4SAndroid Build Coastguard Worker 282*bb4ee6a4SAndroid Build Coastguard Worker /// Parameters describing an MMIO or PIO from the guest. 283*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug)] 284*bb4ee6a4SAndroid Build Coastguard Worker pub struct IoParams<'a> { 285*bb4ee6a4SAndroid Build Coastguard Worker pub address: u64, 286*bb4ee6a4SAndroid Build Coastguard Worker pub operation: IoOperation<'a>, 287*bb4ee6a4SAndroid Build Coastguard Worker } 288*bb4ee6a4SAndroid Build Coastguard Worker 289*bb4ee6a4SAndroid Build Coastguard Worker /// Handle to a virtual CPU that may be used to request a VM exit from within a signal handler. 290*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 291*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuSignalHandle { 292*bb4ee6a4SAndroid Build Coastguard Worker inner: Box<dyn VcpuSignalHandleInner>, 293*bb4ee6a4SAndroid Build Coastguard Worker } 294*bb4ee6a4SAndroid Build Coastguard Worker 295*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 296*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuSignalHandle { 297*bb4ee6a4SAndroid Build Coastguard Worker /// Request an immediate exit for this VCPU. 298*bb4ee6a4SAndroid Build Coastguard Worker /// 299*bb4ee6a4SAndroid Build Coastguard Worker /// This function is safe to call from a signal handler. signal_immediate_exit(&self)300*bb4ee6a4SAndroid Build Coastguard Worker pub fn signal_immediate_exit(&self) { 301*bb4ee6a4SAndroid Build Coastguard Worker self.inner.signal_immediate_exit() 302*bb4ee6a4SAndroid Build Coastguard Worker } 303*bb4ee6a4SAndroid Build Coastguard Worker } 304*bb4ee6a4SAndroid Build Coastguard Worker 305*bb4ee6a4SAndroid Build Coastguard Worker /// Signal-safe mechanism for requesting an immediate VCPU exit. 306*bb4ee6a4SAndroid Build Coastguard Worker /// 307*bb4ee6a4SAndroid Build Coastguard Worker /// Each hypervisor backend must implement this for its VCPU type. 308*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 309*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) trait VcpuSignalHandleInner { 310*bb4ee6a4SAndroid Build Coastguard Worker /// Signal the associated VCPU to exit if it is currently running. 311*bb4ee6a4SAndroid Build Coastguard Worker /// 312*bb4ee6a4SAndroid Build Coastguard Worker /// # Safety 313*bb4ee6a4SAndroid Build Coastguard Worker /// 314*bb4ee6a4SAndroid Build Coastguard Worker /// The implementation of this function must be async signal safe. 315*bb4ee6a4SAndroid Build Coastguard Worker /// <https://man7.org/linux/man-pages/man7/signal-safety.7.html> signal_immediate_exit(&self)316*bb4ee6a4SAndroid Build Coastguard Worker fn signal_immediate_exit(&self); 317*bb4ee6a4SAndroid Build Coastguard Worker } 318*bb4ee6a4SAndroid Build Coastguard Worker 319*bb4ee6a4SAndroid Build Coastguard Worker /// A virtual CPU holding a virtualized hardware thread's state, such as registers and interrupt 320*bb4ee6a4SAndroid Build Coastguard Worker /// state, which may be used to execute virtual machines. 321*bb4ee6a4SAndroid Build Coastguard Worker pub trait Vcpu: downcast_rs::DowncastSync { 322*bb4ee6a4SAndroid Build Coastguard Worker /// Makes a shallow clone of this `Vcpu`. try_clone(&self) -> Result<Self> where Self: Sized323*bb4ee6a4SAndroid Build Coastguard Worker fn try_clone(&self) -> Result<Self> 324*bb4ee6a4SAndroid Build Coastguard Worker where 325*bb4ee6a4SAndroid Build Coastguard Worker Self: Sized; 326*bb4ee6a4SAndroid Build Coastguard Worker 327*bb4ee6a4SAndroid Build Coastguard Worker /// Casts this architecture specific trait object to the base trait object `Vcpu`. as_vcpu(&self) -> &dyn Vcpu328*bb4ee6a4SAndroid Build Coastguard Worker fn as_vcpu(&self) -> &dyn Vcpu; 329*bb4ee6a4SAndroid Build Coastguard Worker 330*bb4ee6a4SAndroid Build Coastguard Worker /// Runs the VCPU until it exits, returning the reason for the exit. run(&mut self) -> Result<VcpuExit>331*bb4ee6a4SAndroid Build Coastguard Worker fn run(&mut self) -> Result<VcpuExit>; 332*bb4ee6a4SAndroid Build Coastguard Worker 333*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the vcpu id. id(&self) -> usize334*bb4ee6a4SAndroid Build Coastguard Worker fn id(&self) -> usize; 335*bb4ee6a4SAndroid Build Coastguard Worker 336*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the bit that requests an immediate exit. set_immediate_exit(&self, exit: bool)337*bb4ee6a4SAndroid Build Coastguard Worker fn set_immediate_exit(&self, exit: bool); 338*bb4ee6a4SAndroid Build Coastguard Worker 339*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a handle that can be used to cause this VCPU to exit from `run()` from a signal 340*bb4ee6a4SAndroid Build Coastguard Worker /// handler. 341*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] signal_handle(&self) -> VcpuSignalHandle342*bb4ee6a4SAndroid Build Coastguard Worker fn signal_handle(&self) -> VcpuSignalHandle; 343*bb4ee6a4SAndroid Build Coastguard Worker 344*bb4ee6a4SAndroid Build Coastguard Worker /// Handles an incoming MMIO request from the guest. 345*bb4ee6a4SAndroid Build Coastguard Worker /// 346*bb4ee6a4SAndroid Build Coastguard Worker /// This function should be called after `Vcpu::run` returns `VcpuExit::Mmio`, and in the same 347*bb4ee6a4SAndroid Build Coastguard Worker /// thread as run(). 348*bb4ee6a4SAndroid Build Coastguard Worker /// 349*bb4ee6a4SAndroid Build Coastguard Worker /// Once called, it will determine whether a MMIO read or MMIO write was the reason for the MMIO 350*bb4ee6a4SAndroid Build Coastguard Worker /// exit, call `handle_fn` with the respective IoParams to perform the MMIO read or write, and 351*bb4ee6a4SAndroid Build Coastguard Worker /// 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<()>352*bb4ee6a4SAndroid Build Coastguard Worker fn handle_mmio(&self, handle_fn: &mut dyn FnMut(IoParams) -> Result<()>) -> Result<()>; 353*bb4ee6a4SAndroid Build Coastguard Worker 354*bb4ee6a4SAndroid Build Coastguard Worker /// Handles an incoming PIO from the guest. 355*bb4ee6a4SAndroid Build Coastguard Worker /// 356*bb4ee6a4SAndroid Build Coastguard Worker /// This function should be called after `Vcpu::run` returns `VcpuExit::Io`, and in the same 357*bb4ee6a4SAndroid Build Coastguard Worker /// thread as run(). 358*bb4ee6a4SAndroid Build Coastguard Worker /// 359*bb4ee6a4SAndroid Build Coastguard Worker /// Once called, it will determine whether an input or output was the reason for the Io exit, 360*bb4ee6a4SAndroid Build Coastguard Worker /// call `handle_fn` with the respective IoParams to perform the input/output operation, and set 361*bb4ee6a4SAndroid Build Coastguard Worker /// the return data in the vcpu so that the vcpu can resume running. handle_io(&self, handle_fn: &mut dyn FnMut(IoParams)) -> Result<()>362*bb4ee6a4SAndroid Build Coastguard Worker fn handle_io(&self, handle_fn: &mut dyn FnMut(IoParams)) -> Result<()>; 363*bb4ee6a4SAndroid Build Coastguard Worker 364*bb4ee6a4SAndroid Build Coastguard Worker /// Signals to the hypervisor that this Vcpu is being paused by userspace. on_suspend(&self) -> Result<()>365*bb4ee6a4SAndroid Build Coastguard Worker fn on_suspend(&self) -> Result<()>; 366*bb4ee6a4SAndroid Build Coastguard Worker 367*bb4ee6a4SAndroid Build Coastguard Worker /// Enables a hypervisor-specific extension on this Vcpu. `cap` is a constant defined by the 368*bb4ee6a4SAndroid Build Coastguard Worker /// hypervisor API (e.g., kvm.h). `args` are the arguments for enabling the feature, if any. 369*bb4ee6a4SAndroid Build Coastguard Worker /// 370*bb4ee6a4SAndroid Build Coastguard Worker /// # Safety 371*bb4ee6a4SAndroid Build Coastguard Worker /// This function is marked as unsafe because `args` may be interpreted as pointers for some 372*bb4ee6a4SAndroid Build Coastguard Worker /// capabilities. The caller must ensure that any pointers passed in the `args` array are 373*bb4ee6a4SAndroid Build Coastguard Worker /// allocated as the kernel expects, and that mutable pointers are owned. enable_raw_capability(&self, cap: u32, args: &[u64; 4]) -> Result<()>374*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn enable_raw_capability(&self, cap: u32, args: &[u64; 4]) -> Result<()>; 375*bb4ee6a4SAndroid Build Coastguard Worker } 376*bb4ee6a4SAndroid Build Coastguard Worker 377*bb4ee6a4SAndroid Build Coastguard Worker downcast_rs::impl_downcast!(sync Vcpu); 378*bb4ee6a4SAndroid Build Coastguard Worker 379*bb4ee6a4SAndroid Build Coastguard Worker /// An address either in programmable I/O space or in memory mapped I/O space. 380*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, std::hash::Hash)] 381*bb4ee6a4SAndroid Build Coastguard Worker pub enum IoEventAddress { 382*bb4ee6a4SAndroid Build Coastguard Worker Pio(u64), 383*bb4ee6a4SAndroid Build Coastguard Worker Mmio(u64), 384*bb4ee6a4SAndroid Build Coastguard Worker } 385*bb4ee6a4SAndroid Build Coastguard Worker 386*bb4ee6a4SAndroid Build Coastguard Worker /// Used in `Vm::register_ioevent` to indicate a size and optionally value to match. 387*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] 388*bb4ee6a4SAndroid Build Coastguard Worker pub enum Datamatch { 389*bb4ee6a4SAndroid Build Coastguard Worker AnyLength, 390*bb4ee6a4SAndroid Build Coastguard Worker U8(Option<u8>), 391*bb4ee6a4SAndroid Build Coastguard Worker U16(Option<u16>), 392*bb4ee6a4SAndroid Build Coastguard Worker U32(Option<u32>), 393*bb4ee6a4SAndroid Build Coastguard Worker U64(Option<u64>), 394*bb4ee6a4SAndroid Build Coastguard Worker } 395*bb4ee6a4SAndroid Build Coastguard Worker 396*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug)] 397*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuShutdownErrorKind { 398*bb4ee6a4SAndroid Build Coastguard Worker DoubleFault, 399*bb4ee6a4SAndroid Build Coastguard Worker TripleFault, 400*bb4ee6a4SAndroid Build Coastguard Worker Other, 401*bb4ee6a4SAndroid Build Coastguard Worker } 402*bb4ee6a4SAndroid Build Coastguard Worker 403*bb4ee6a4SAndroid Build Coastguard Worker /// A Vcpu shutdown may signify an error, such as a double or triple fault, 404*bb4ee6a4SAndroid Build Coastguard Worker /// or hypervisor specific reasons. This error covers all such cases. 405*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug)] 406*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuShutdownError { 407*bb4ee6a4SAndroid Build Coastguard Worker kind: VcpuShutdownErrorKind, 408*bb4ee6a4SAndroid Build Coastguard Worker raw_error_code: u64, 409*bb4ee6a4SAndroid Build Coastguard Worker } 410*bb4ee6a4SAndroid Build Coastguard Worker 411*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuShutdownError { new(kind: VcpuShutdownErrorKind, raw_error_code: u64) -> VcpuShutdownError412*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(kind: VcpuShutdownErrorKind, raw_error_code: u64) -> VcpuShutdownError { 413*bb4ee6a4SAndroid Build Coastguard Worker Self { 414*bb4ee6a4SAndroid Build Coastguard Worker kind, 415*bb4ee6a4SAndroid Build Coastguard Worker raw_error_code, 416*bb4ee6a4SAndroid Build Coastguard Worker } 417*bb4ee6a4SAndroid Build Coastguard Worker } kind(&self) -> VcpuShutdownErrorKind418*bb4ee6a4SAndroid Build Coastguard Worker pub fn kind(&self) -> VcpuShutdownErrorKind { 419*bb4ee6a4SAndroid Build Coastguard Worker self.kind 420*bb4ee6a4SAndroid Build Coastguard Worker } get_raw_error_code(&self) -> u64421*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_raw_error_code(&self) -> u64 { 422*bb4ee6a4SAndroid Build Coastguard Worker self.raw_error_code 423*bb4ee6a4SAndroid Build Coastguard Worker } 424*bb4ee6a4SAndroid Build Coastguard Worker } 425*bb4ee6a4SAndroid Build Coastguard Worker 426*bb4ee6a4SAndroid Build Coastguard Worker // Note that when adding entries to the VcpuExit enum you may want to add corresponding entries in 427*bb4ee6a4SAndroid Build Coastguard Worker // crosvm::stats::exit_to_index and crosvm::stats::exit_index_to_str if you don't want the new 428*bb4ee6a4SAndroid Build Coastguard Worker // exit type to be categorized as "Unknown". 429*bb4ee6a4SAndroid Build Coastguard Worker 430*bb4ee6a4SAndroid Build Coastguard Worker /// A reason why a VCPU exited. One of these returns every time `Vcpu::run` is called. 431*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy)] 432*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuExit { 433*bb4ee6a4SAndroid Build Coastguard Worker /// An io instruction needs to be emulated. 434*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu handle_io should be called to handle the io operation 435*bb4ee6a4SAndroid Build Coastguard Worker Io, 436*bb4ee6a4SAndroid Build Coastguard Worker /// A mmio instruction needs to be emulated. 437*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu handle_mmio should be called to handle the mmio operation 438*bb4ee6a4SAndroid Build Coastguard Worker Mmio, 439*bb4ee6a4SAndroid Build Coastguard Worker IoapicEoi { 440*bb4ee6a4SAndroid Build Coastguard Worker vector: u8, 441*bb4ee6a4SAndroid Build Coastguard Worker }, 442*bb4ee6a4SAndroid Build Coastguard Worker Exception, 443*bb4ee6a4SAndroid Build Coastguard Worker Hypercall, 444*bb4ee6a4SAndroid Build Coastguard Worker Debug, 445*bb4ee6a4SAndroid Build Coastguard Worker Hlt, 446*bb4ee6a4SAndroid Build Coastguard Worker IrqWindowOpen, 447*bb4ee6a4SAndroid Build Coastguard Worker Shutdown(std::result::Result<(), VcpuShutdownError>), 448*bb4ee6a4SAndroid Build Coastguard Worker FailEntry { 449*bb4ee6a4SAndroid Build Coastguard Worker hardware_entry_failure_reason: u64, 450*bb4ee6a4SAndroid Build Coastguard Worker }, 451*bb4ee6a4SAndroid Build Coastguard Worker Intr, 452*bb4ee6a4SAndroid Build Coastguard Worker SetTpr, 453*bb4ee6a4SAndroid Build Coastguard Worker TprAccess, 454*bb4ee6a4SAndroid Build Coastguard Worker InternalError, 455*bb4ee6a4SAndroid Build Coastguard Worker SystemEventShutdown, 456*bb4ee6a4SAndroid Build Coastguard Worker SystemEventReset, 457*bb4ee6a4SAndroid Build Coastguard Worker SystemEventCrash, 458*bb4ee6a4SAndroid Build Coastguard Worker /// An invalid vcpu register was set while running. 459*bb4ee6a4SAndroid Build Coastguard Worker InvalidVpRegister, 460*bb4ee6a4SAndroid Build Coastguard Worker /// incorrect setup for vcpu requiring an unsupported feature 461*bb4ee6a4SAndroid Build Coastguard Worker UnsupportedFeature, 462*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu run was user cancelled 463*bb4ee6a4SAndroid Build Coastguard Worker Canceled, 464*bb4ee6a4SAndroid Build Coastguard Worker /// an unrecoverable exception was encountered (different from Exception) 465*bb4ee6a4SAndroid Build Coastguard Worker UnrecoverableException, 466*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stopped due to an msr access. 467*bb4ee6a4SAndroid Build Coastguard Worker MsrAccess, 468*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stopped due to a cpuid request. 469*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")] 470*bb4ee6a4SAndroid Build Coastguard Worker Cpuid { 471*bb4ee6a4SAndroid Build Coastguard Worker entry: CpuIdEntry, 472*bb4ee6a4SAndroid Build Coastguard Worker }, 473*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stopped due to calling rdtsc 474*bb4ee6a4SAndroid Build Coastguard Worker RdTsc, 475*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stopped for an apic smi trap 476*bb4ee6a4SAndroid Build Coastguard Worker ApicSmiTrap, 477*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stopped due to an apic trap 478*bb4ee6a4SAndroid Build Coastguard Worker ApicInitSipiTrap, 479*bb4ee6a4SAndroid Build Coastguard Worker /// vcpu stoppted due to bus lock 480*bb4ee6a4SAndroid Build Coastguard Worker BusLock, 481*bb4ee6a4SAndroid Build Coastguard Worker /// Riscv supervisor call. 482*bb4ee6a4SAndroid Build Coastguard Worker Sbi { 483*bb4ee6a4SAndroid Build Coastguard Worker extension_id: u64, 484*bb4ee6a4SAndroid Build Coastguard Worker function_id: u64, 485*bb4ee6a4SAndroid Build Coastguard Worker args: [u64; 6], 486*bb4ee6a4SAndroid Build Coastguard Worker }, 487*bb4ee6a4SAndroid Build Coastguard Worker /// Emulate CSR access from guest. 488*bb4ee6a4SAndroid Build Coastguard Worker RiscvCsr { 489*bb4ee6a4SAndroid Build Coastguard Worker csr_num: u64, 490*bb4ee6a4SAndroid Build Coastguard Worker new_value: u64, 491*bb4ee6a4SAndroid Build Coastguard Worker write_mask: u64, 492*bb4ee6a4SAndroid Build Coastguard Worker ret_value: u64, 493*bb4ee6a4SAndroid Build Coastguard Worker }, 494*bb4ee6a4SAndroid Build Coastguard Worker } 495*bb4ee6a4SAndroid Build Coastguard Worker 496*bb4ee6a4SAndroid Build Coastguard Worker /// A device type to create with `Vm.create_device`. 497*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)] 498*bb4ee6a4SAndroid Build Coastguard Worker pub enum DeviceKind { 499*bb4ee6a4SAndroid Build Coastguard Worker /// VFIO device for direct access to devices from userspace 500*bb4ee6a4SAndroid Build Coastguard Worker Vfio, 501*bb4ee6a4SAndroid Build Coastguard Worker /// ARM virtual general interrupt controller v2 502*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 503*bb4ee6a4SAndroid Build Coastguard Worker ArmVgicV2, 504*bb4ee6a4SAndroid Build Coastguard Worker /// ARM virtual general interrupt controller v3 505*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 506*bb4ee6a4SAndroid Build Coastguard Worker ArmVgicV3, 507*bb4ee6a4SAndroid Build Coastguard Worker /// RiscV AIA in-kernel emulation 508*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "riscv64")] 509*bb4ee6a4SAndroid Build Coastguard Worker RiscvAia, 510*bb4ee6a4SAndroid Build Coastguard Worker } 511*bb4ee6a4SAndroid Build Coastguard Worker 512*bb4ee6a4SAndroid Build Coastguard Worker /// The source chip of an `IrqSource` 513*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 514*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] 515*bb4ee6a4SAndroid Build Coastguard Worker pub enum IrqSourceChip { 516*bb4ee6a4SAndroid Build Coastguard Worker PicPrimary, 517*bb4ee6a4SAndroid Build Coastguard Worker PicSecondary, 518*bb4ee6a4SAndroid Build Coastguard Worker Ioapic, 519*bb4ee6a4SAndroid Build Coastguard Worker Gic, 520*bb4ee6a4SAndroid Build Coastguard Worker Aia, 521*bb4ee6a4SAndroid Build Coastguard Worker } 522*bb4ee6a4SAndroid Build Coastguard Worker 523*bb4ee6a4SAndroid Build Coastguard Worker /// A source of IRQs in an `IrqRoute`. 524*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 525*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] 526*bb4ee6a4SAndroid Build Coastguard Worker pub enum IrqSource { 527*bb4ee6a4SAndroid Build Coastguard Worker Irqchip { chip: IrqSourceChip, pin: u32 }, 528*bb4ee6a4SAndroid Build Coastguard Worker Msi { address: u64, data: u32 }, 529*bb4ee6a4SAndroid Build Coastguard Worker } 530*bb4ee6a4SAndroid Build Coastguard Worker 531*bb4ee6a4SAndroid Build Coastguard Worker /// A single route for an IRQ. 532*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 533*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] 534*bb4ee6a4SAndroid Build Coastguard Worker pub struct IrqRoute { 535*bb4ee6a4SAndroid Build Coastguard Worker pub gsi: u32, 536*bb4ee6a4SAndroid Build Coastguard Worker pub source: IrqSource, 537*bb4ee6a4SAndroid Build Coastguard Worker } 538*bb4ee6a4SAndroid Build Coastguard Worker 539*bb4ee6a4SAndroid Build Coastguard Worker /// The state of the paravirtual clock. 540*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] 541*bb4ee6a4SAndroid Build Coastguard Worker pub struct ClockState { 542*bb4ee6a4SAndroid Build Coastguard Worker /// Current pv clock timestamp, as seen by the guest 543*bb4ee6a4SAndroid Build Coastguard Worker pub clock: u64, 544*bb4ee6a4SAndroid Build Coastguard Worker } 545*bb4ee6a4SAndroid Build Coastguard Worker 546*bb4ee6a4SAndroid Build Coastguard Worker /// The MPState represents the state of a processor. 547*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 548*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] 549*bb4ee6a4SAndroid Build Coastguard Worker pub enum MPState { 550*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu is currently running (x86/x86_64,arm/arm64) 551*bb4ee6a4SAndroid Build Coastguard Worker Runnable, 552*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu is an application processor (AP) which has not yet received an INIT signal 553*bb4ee6a4SAndroid Build Coastguard Worker /// (x86/x86_64) 554*bb4ee6a4SAndroid Build Coastguard Worker Uninitialized, 555*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu has received an INIT signal, and is now ready for a SIPI (x86/x86_64) 556*bb4ee6a4SAndroid Build Coastguard Worker InitReceived, 557*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu has executed a HLT instruction and is waiting for an interrupt (x86/x86_64) 558*bb4ee6a4SAndroid Build Coastguard Worker Halted, 559*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu has just received a SIPI (vector accessible via KVM_GET_VCPU_EVENTS) (x86/x86_64) 560*bb4ee6a4SAndroid Build Coastguard Worker SipiReceived, 561*bb4ee6a4SAndroid Build Coastguard Worker /// the vcpu is stopped (arm/arm64) 562*bb4ee6a4SAndroid Build Coastguard Worker Stopped, 563*bb4ee6a4SAndroid Build Coastguard Worker } 564*bb4ee6a4SAndroid Build Coastguard Worker 565*bb4ee6a4SAndroid Build Coastguard Worker /// Whether the VM should be run in protected mode or not. 566*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] 567*bb4ee6a4SAndroid Build Coastguard Worker pub enum ProtectionType { 568*bb4ee6a4SAndroid Build Coastguard Worker /// The VM should be run in the unprotected mode, where the host has access to its memory. 569*bb4ee6a4SAndroid Build Coastguard Worker Unprotected, 570*bb4ee6a4SAndroid Build Coastguard Worker /// The VM should be run in protected mode, so the host cannot access its memory directly. It 571*bb4ee6a4SAndroid Build Coastguard Worker /// should be booted via the protected VM firmware, so that it can access its secrets. 572*bb4ee6a4SAndroid Build Coastguard Worker Protected, 573*bb4ee6a4SAndroid Build Coastguard Worker /// The VM should be run in protected mode, so the host cannot access its memory directly. It 574*bb4ee6a4SAndroid Build Coastguard Worker /// should be booted via a custom VM firmware, useful for debugging and testing. 575*bb4ee6a4SAndroid Build Coastguard Worker ProtectedWithCustomFirmware, 576*bb4ee6a4SAndroid Build Coastguard Worker /// The VM should be run in protected mode, but booted directly without pVM firmware. The host 577*bb4ee6a4SAndroid Build Coastguard Worker /// will still be unable to access the VM memory, but it won't be given any secrets. 578*bb4ee6a4SAndroid Build Coastguard Worker ProtectedWithoutFirmware, 579*bb4ee6a4SAndroid Build Coastguard Worker /// The VM should be run in unprotected mode, but with the same memory layout as protected 580*bb4ee6a4SAndroid Build Coastguard Worker /// mode, protected VM firmware loaded, and simulating protected mode as much as possible. 581*bb4ee6a4SAndroid Build Coastguard Worker /// This is useful for debugging the protected VM firmware and other protected mode issues. 582*bb4ee6a4SAndroid Build Coastguard Worker UnprotectedWithFirmware, 583*bb4ee6a4SAndroid Build Coastguard Worker } 584*bb4ee6a4SAndroid Build Coastguard Worker 585*bb4ee6a4SAndroid Build Coastguard Worker impl ProtectionType { 586*bb4ee6a4SAndroid Build Coastguard Worker /// Returns whether the hypervisor will prevent us from accessing the VM's memory. isolates_memory(&self) -> bool587*bb4ee6a4SAndroid Build Coastguard Worker pub fn isolates_memory(&self) -> bool { 588*bb4ee6a4SAndroid Build Coastguard Worker matches!( 589*bb4ee6a4SAndroid Build Coastguard Worker self, 590*bb4ee6a4SAndroid Build Coastguard Worker Self::Protected | Self::ProtectedWithCustomFirmware | Self::ProtectedWithoutFirmware 591*bb4ee6a4SAndroid Build Coastguard Worker ) 592*bb4ee6a4SAndroid Build Coastguard Worker } 593*bb4ee6a4SAndroid Build Coastguard Worker 594*bb4ee6a4SAndroid Build Coastguard Worker /// Returns whether the VMM needs to load the pVM firmware. needs_firmware_loaded(&self) -> bool595*bb4ee6a4SAndroid Build Coastguard Worker pub fn needs_firmware_loaded(&self) -> bool { 596*bb4ee6a4SAndroid Build Coastguard Worker matches!( 597*bb4ee6a4SAndroid Build Coastguard Worker self, 598*bb4ee6a4SAndroid Build Coastguard Worker Self::UnprotectedWithFirmware | Self::ProtectedWithCustomFirmware 599*bb4ee6a4SAndroid Build Coastguard Worker ) 600*bb4ee6a4SAndroid Build Coastguard Worker } 601*bb4ee6a4SAndroid Build Coastguard Worker 602*bb4ee6a4SAndroid Build Coastguard Worker /// Returns whether the VM runs a pVM firmware. runs_firmware(&self) -> bool603*bb4ee6a4SAndroid Build Coastguard Worker pub fn runs_firmware(&self) -> bool { 604*bb4ee6a4SAndroid Build Coastguard Worker self.needs_firmware_loaded() || matches!(self, Self::Protected) 605*bb4ee6a4SAndroid Build Coastguard Worker } 606*bb4ee6a4SAndroid Build Coastguard Worker } 607*bb4ee6a4SAndroid Build Coastguard Worker 608*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy)] 609*bb4ee6a4SAndroid Build Coastguard Worker pub struct Config { 610*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "aarch64")] 611*bb4ee6a4SAndroid Build Coastguard Worker /// enable the Memory Tagging Extension in the guest 612*bb4ee6a4SAndroid Build Coastguard Worker pub mte: bool, 613*bb4ee6a4SAndroid Build Coastguard Worker pub protection_type: ProtectionType, 614*bb4ee6a4SAndroid Build Coastguard Worker } 615*bb4ee6a4SAndroid Build Coastguard Worker 616*bb4ee6a4SAndroid Build Coastguard Worker impl Default for Config { default() -> Config617*bb4ee6a4SAndroid Build Coastguard Worker fn default() -> Config { 618*bb4ee6a4SAndroid Build Coastguard Worker Config { 619*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "aarch64")] 620*bb4ee6a4SAndroid Build Coastguard Worker mte: false, 621*bb4ee6a4SAndroid Build Coastguard Worker protection_type: ProtectionType::Unprotected, 622*bb4ee6a4SAndroid Build Coastguard Worker } 623*bb4ee6a4SAndroid Build Coastguard Worker } 624*bb4ee6a4SAndroid Build Coastguard Worker } 625