xref: /aosp_15_r20/external/crosvm/hypervisor/src/lib.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! 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