xref: /aosp_15_r20/external/crosvm/kvm/src/lib.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 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 safe wrapper around the kernel's KVM interface.
6*bb4ee6a4SAndroid Build Coastguard Worker //!
7*bb4ee6a4SAndroid Build Coastguard Worker //! New code should use the `hypervisor` crate instead.
8*bb4ee6a4SAndroid Build Coastguard Worker 
9*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(any(target_os = "android", target_os = "linux"))]
10*bb4ee6a4SAndroid Build Coastguard Worker 
11*bb4ee6a4SAndroid Build Coastguard Worker mod cap;
12*bb4ee6a4SAndroid Build Coastguard Worker 
13*bb4ee6a4SAndroid Build Coastguard Worker use std::cell::RefCell;
14*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::min;
15*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::Ordering;
16*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
17*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BinaryHeap;
18*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CString;
19*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File;
20*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of;
21*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::Deref;
22*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::DerefMut;
23*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::*;
24*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::prelude::OsStrExt;
25*bb4ee6a4SAndroid Build Coastguard Worker use std::path::Path;
26*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr::copy_nonoverlapping;
27*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
28*bb4ee6a4SAndroid Build Coastguard Worker 
29*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
30*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl;
31*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
32*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_mut_ptr;
33*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
34*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_mut_ref;
35*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
36*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_ptr;
37*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
38*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_ref;
39*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
40*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_val;
41*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
42*bb4ee6a4SAndroid Build Coastguard Worker use base::pagesize;
43*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
44*bb4ee6a4SAndroid Build Coastguard Worker use base::signal;
45*bb4ee6a4SAndroid Build Coastguard Worker use base::sys::BlockedSignal;
46*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
47*bb4ee6a4SAndroid Build Coastguard Worker use base::unblock_signal;
48*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
49*bb4ee6a4SAndroid Build Coastguard Worker use base::warn;
50*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor;
51*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
52*bb4ee6a4SAndroid Build Coastguard Worker use base::Error;
53*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
54*bb4ee6a4SAndroid Build Coastguard Worker use base::Event;
55*bb4ee6a4SAndroid Build Coastguard Worker use base::FromRawDescriptor;
56*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
57*bb4ee6a4SAndroid Build Coastguard Worker use base::IoctlNr;
58*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
59*bb4ee6a4SAndroid Build Coastguard Worker use base::MappedRegion;
60*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
61*bb4ee6a4SAndroid Build Coastguard Worker use base::MemoryMapping;
62*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
63*bb4ee6a4SAndroid Build Coastguard Worker use base::MemoryMappingBuilder;
64*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
65*bb4ee6a4SAndroid Build Coastguard Worker use base::MmapError;
66*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor;
67*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
68*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
69*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_imports)]
70*bb4ee6a4SAndroid Build Coastguard Worker use base::SIGRTMIN;
71*bb4ee6a4SAndroid Build Coastguard Worker use data_model::vec_with_array_field;
72*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")]
73*bb4ee6a4SAndroid Build Coastguard Worker use data_model::FlexibleArrayWrapper;
74*bb4ee6a4SAndroid Build Coastguard Worker use kvm_sys::*;
75*bb4ee6a4SAndroid Build Coastguard Worker use libc::open64;
76*bb4ee6a4SAndroid Build Coastguard Worker use libc::sigset_t;
77*bb4ee6a4SAndroid Build Coastguard Worker use libc::EBUSY;
78*bb4ee6a4SAndroid Build Coastguard Worker use libc::EINVAL;
79*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENOENT;
80*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENOSPC;
81*bb4ee6a4SAndroid Build Coastguard Worker use libc::EOVERFLOW;
82*bb4ee6a4SAndroid Build Coastguard Worker use libc::O_CLOEXEC;
83*bb4ee6a4SAndroid Build Coastguard Worker use libc::O_RDWR;
84*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
85*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
86*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestMemory;
87*bb4ee6a4SAndroid Build Coastguard Worker 
88*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::cap::*;
89*bb4ee6a4SAndroid Build Coastguard Worker 
errno_result<T>() -> Result<T>90*bb4ee6a4SAndroid Build Coastguard Worker fn errno_result<T>() -> Result<T> {
91*bb4ee6a4SAndroid Build Coastguard Worker     Err(Error::last())
92*bb4ee6a4SAndroid Build Coastguard Worker }
93*bb4ee6a4SAndroid Build Coastguard Worker 
set_user_memory_region<F: AsRawDescriptor>( fd: &F, slot: u32, read_only: bool, log_dirty_pages: bool, guest_addr: u64, memory_size: u64, userspace_addr: *mut u8, ) -> Result<()>94*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn set_user_memory_region<F: AsRawDescriptor>(
95*bb4ee6a4SAndroid Build Coastguard Worker     fd: &F,
96*bb4ee6a4SAndroid Build Coastguard Worker     slot: u32,
97*bb4ee6a4SAndroid Build Coastguard Worker     read_only: bool,
98*bb4ee6a4SAndroid Build Coastguard Worker     log_dirty_pages: bool,
99*bb4ee6a4SAndroid Build Coastguard Worker     guest_addr: u64,
100*bb4ee6a4SAndroid Build Coastguard Worker     memory_size: u64,
101*bb4ee6a4SAndroid Build Coastguard Worker     userspace_addr: *mut u8,
102*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
103*bb4ee6a4SAndroid Build Coastguard Worker     let mut flags = if read_only { KVM_MEM_READONLY } else { 0 };
104*bb4ee6a4SAndroid Build Coastguard Worker     if log_dirty_pages {
105*bb4ee6a4SAndroid Build Coastguard Worker         flags |= KVM_MEM_LOG_DIRTY_PAGES;
106*bb4ee6a4SAndroid Build Coastguard Worker     }
107*bb4ee6a4SAndroid Build Coastguard Worker     let region = kvm_userspace_memory_region {
108*bb4ee6a4SAndroid Build Coastguard Worker         slot,
109*bb4ee6a4SAndroid Build Coastguard Worker         flags,
110*bb4ee6a4SAndroid Build Coastguard Worker         guest_phys_addr: guest_addr,
111*bb4ee6a4SAndroid Build Coastguard Worker         memory_size,
112*bb4ee6a4SAndroid Build Coastguard Worker         userspace_addr: userspace_addr as u64,
113*bb4ee6a4SAndroid Build Coastguard Worker     };
114*bb4ee6a4SAndroid Build Coastguard Worker 
115*bb4ee6a4SAndroid Build Coastguard Worker     let ret = ioctl_with_ref(fd, KVM_SET_USER_MEMORY_REGION, &region);
116*bb4ee6a4SAndroid Build Coastguard Worker     if ret == 0 {
117*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
118*bb4ee6a4SAndroid Build Coastguard Worker     } else {
119*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
120*bb4ee6a4SAndroid Build Coastguard Worker     }
121*bb4ee6a4SAndroid Build Coastguard Worker }
122*bb4ee6a4SAndroid Build Coastguard Worker 
123*bb4ee6a4SAndroid Build Coastguard Worker /// Helper function to determine the size in bytes of a dirty log bitmap for the given memory region
124*bb4ee6a4SAndroid Build Coastguard Worker /// size.
125*bb4ee6a4SAndroid Build Coastguard Worker ///
126*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
127*bb4ee6a4SAndroid Build Coastguard Worker ///
128*bb4ee6a4SAndroid Build Coastguard Worker /// * `size` - Number of bytes in the memory region being queried.
dirty_log_bitmap_size(size: usize) -> usize129*bb4ee6a4SAndroid Build Coastguard Worker pub fn dirty_log_bitmap_size(size: usize) -> usize {
130*bb4ee6a4SAndroid Build Coastguard Worker     let page_size = pagesize();
131*bb4ee6a4SAndroid Build Coastguard Worker     (((size + page_size - 1) / page_size) + 7) / 8
132*bb4ee6a4SAndroid Build Coastguard Worker }
133*bb4ee6a4SAndroid Build Coastguard Worker 
134*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around opening and using `/dev/kvm`.
135*bb4ee6a4SAndroid Build Coastguard Worker ///
136*bb4ee6a4SAndroid Build Coastguard Worker /// Useful for querying extensions and basic values from the KVM backend. A `Kvm` is required to
137*bb4ee6a4SAndroid Build Coastguard Worker /// create a `Vm` object.
138*bb4ee6a4SAndroid Build Coastguard Worker pub struct Kvm {
139*bb4ee6a4SAndroid Build Coastguard Worker     kvm: File,
140*bb4ee6a4SAndroid Build Coastguard Worker }
141*bb4ee6a4SAndroid Build Coastguard Worker 
142*bb4ee6a4SAndroid Build Coastguard Worker impl Kvm {
143*bb4ee6a4SAndroid Build Coastguard Worker     /// Opens `/dev/kvm` and returns a Kvm object on success.
new() -> Result<Kvm>144*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new() -> Result<Kvm> {
145*bb4ee6a4SAndroid Build Coastguard Worker         Kvm::new_with_path(Path::new("/dev/kvm"))
146*bb4ee6a4SAndroid Build Coastguard Worker     }
147*bb4ee6a4SAndroid Build Coastguard Worker 
148*bb4ee6a4SAndroid Build Coastguard Worker     /// Opens a KVM device at `device_path` and returns a Kvm object on success.
new_with_path(device_path: &Path) -> Result<Kvm>149*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new_with_path(device_path: &Path) -> Result<Kvm> {
150*bb4ee6a4SAndroid Build Coastguard Worker         let c_path = CString::new(device_path.as_os_str().as_bytes()).unwrap();
151*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
152*bb4ee6a4SAndroid Build Coastguard Worker         // Open calls are safe because we give a nul-terminated string and verify the result.
153*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { open64(c_path.as_ptr(), O_RDWR | O_CLOEXEC) };
154*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
155*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
156*bb4ee6a4SAndroid Build Coastguard Worker         }
157*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Kvm {
158*bb4ee6a4SAndroid Build Coastguard Worker             kvm: {
159*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
160*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because we verify that ret is valid and we own the fd.
161*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe { File::from_raw_descriptor(ret) }
162*bb4ee6a4SAndroid Build Coastguard Worker             },
163*bb4ee6a4SAndroid Build Coastguard Worker         })
164*bb4ee6a4SAndroid Build Coastguard Worker     }
165*bb4ee6a4SAndroid Build Coastguard Worker 
check_extension_int(&self, c: Cap) -> i32166*bb4ee6a4SAndroid Build Coastguard Worker     fn check_extension_int(&self, c: Cap) -> i32 {
167*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
168*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a KVM fd and that the extension is one of the ones
169*bb4ee6a4SAndroid Build Coastguard Worker         // defined by kernel.
170*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION, c as c_ulong) }
171*bb4ee6a4SAndroid Build Coastguard Worker     }
172*bb4ee6a4SAndroid Build Coastguard Worker 
173*bb4ee6a4SAndroid Build Coastguard Worker     /// Checks if a particular `Cap` is available.
check_extension(&self, c: Cap) -> bool174*bb4ee6a4SAndroid Build Coastguard Worker     pub fn check_extension(&self, c: Cap) -> bool {
175*bb4ee6a4SAndroid Build Coastguard Worker         self.check_extension_int(c) == 1
176*bb4ee6a4SAndroid Build Coastguard Worker     }
177*bb4ee6a4SAndroid Build Coastguard Worker 
178*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the size of the mmap required to use vcpu's `kvm_run` structure.
get_vcpu_mmap_size(&self) -> Result<usize>179*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_vcpu_mmap_size(&self) -> Result<usize> {
180*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
181*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a KVM fd and we verify the return result.
182*bb4ee6a4SAndroid Build Coastguard Worker         let res = unsafe { ioctl(self, KVM_GET_VCPU_MMAP_SIZE) };
183*bb4ee6a4SAndroid Build Coastguard Worker         if res > 0 {
184*bb4ee6a4SAndroid Build Coastguard Worker             Ok(res as usize)
185*bb4ee6a4SAndroid Build Coastguard Worker         } else {
186*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
187*bb4ee6a4SAndroid Build Coastguard Worker         }
188*bb4ee6a4SAndroid Build Coastguard Worker     }
189*bb4ee6a4SAndroid Build Coastguard Worker 
190*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_cpuid(&self, kind: IoctlNr) -> Result<CpuId>191*bb4ee6a4SAndroid Build Coastguard Worker     fn get_cpuid(&self, kind: IoctlNr) -> Result<CpuId> {
192*bb4ee6a4SAndroid Build Coastguard Worker         const MAX_KVM_CPUID_ENTRIES: usize = 256;
193*bb4ee6a4SAndroid Build Coastguard Worker         let mut cpuid = CpuId::new(MAX_KVM_CPUID_ENTRIES);
194*bb4ee6a4SAndroid Build Coastguard Worker 
195*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
196*bb4ee6a4SAndroid Build Coastguard Worker         // ioctl is unsafe. The kernel is trusted not to write beyond the bounds of the memory
197*bb4ee6a4SAndroid Build Coastguard Worker         // allocated for the struct. The limit is read from nent, which is set to the allocated
198*bb4ee6a4SAndroid Build Coastguard Worker         // size(MAX_KVM_CPUID_ENTRIES) above.
199*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ptr(self, kind, cpuid.as_mut_ptr()) };
200*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
201*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
202*bb4ee6a4SAndroid Build Coastguard Worker         }
203*bb4ee6a4SAndroid Build Coastguard Worker 
204*bb4ee6a4SAndroid Build Coastguard Worker         Ok(cpuid)
205*bb4ee6a4SAndroid Build Coastguard Worker     }
206*bb4ee6a4SAndroid Build Coastguard Worker 
207*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get the system supported CPUID values
208*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_supported_cpuid(&self) -> Result<CpuId>209*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_supported_cpuid(&self) -> Result<CpuId> {
210*bb4ee6a4SAndroid Build Coastguard Worker         self.get_cpuid(KVM_GET_SUPPORTED_CPUID)
211*bb4ee6a4SAndroid Build Coastguard Worker     }
212*bb4ee6a4SAndroid Build Coastguard Worker 
213*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get the system emulated CPUID values
214*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_emulated_cpuid(&self) -> Result<CpuId>215*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_emulated_cpuid(&self) -> Result<CpuId> {
216*bb4ee6a4SAndroid Build Coastguard Worker         self.get_cpuid(KVM_GET_EMULATED_CPUID)
217*bb4ee6a4SAndroid Build Coastguard Worker     }
218*bb4ee6a4SAndroid Build Coastguard Worker 
219*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get list of supported MSRS
220*bb4ee6a4SAndroid Build Coastguard Worker     ///
221*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_GET_MSR_INDEX_LIST.
222*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_msr_index_list(&self) -> Result<Vec<u32>>223*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_msr_index_list(&self) -> Result<Vec<u32>> {
224*bb4ee6a4SAndroid Build Coastguard Worker         const MAX_KVM_MSR_ENTRIES: usize = 256;
225*bb4ee6a4SAndroid Build Coastguard Worker 
226*bb4ee6a4SAndroid Build Coastguard Worker         let mut msr_list = vec_with_array_field::<kvm_msr_list, u32>(MAX_KVM_MSR_ENTRIES);
227*bb4ee6a4SAndroid Build Coastguard Worker         msr_list[0].nmsrs = MAX_KVM_MSR_ENTRIES as u32;
228*bb4ee6a4SAndroid Build Coastguard Worker 
229*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
230*bb4ee6a4SAndroid Build Coastguard Worker         // ioctl is unsafe. The kernel is trusted not to write beyond the bounds of the memory
231*bb4ee6a4SAndroid Build Coastguard Worker         // allocated for the struct. The limit is read from nmsrs, which is set to the allocated
232*bb4ee6a4SAndroid Build Coastguard Worker         // size (MAX_KVM_MSR_ENTRIES) above.
233*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_MSR_INDEX_LIST, &mut msr_list[0]) };
234*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
235*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
236*bb4ee6a4SAndroid Build Coastguard Worker         }
237*bb4ee6a4SAndroid Build Coastguard Worker 
238*bb4ee6a4SAndroid Build Coastguard Worker         let mut nmsrs = msr_list[0].nmsrs;
239*bb4ee6a4SAndroid Build Coastguard Worker 
240*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
241*bb4ee6a4SAndroid Build Coastguard Worker         // Mapping the unsized array to a slice is unsafe because the length isn't known.  Using
242*bb4ee6a4SAndroid Build Coastguard Worker         // the length we originally allocated with eliminates the possibility of overflow.
243*bb4ee6a4SAndroid Build Coastguard Worker         let indices: &[u32] = unsafe {
244*bb4ee6a4SAndroid Build Coastguard Worker             if nmsrs > MAX_KVM_MSR_ENTRIES as u32 {
245*bb4ee6a4SAndroid Build Coastguard Worker                 nmsrs = MAX_KVM_MSR_ENTRIES as u32;
246*bb4ee6a4SAndroid Build Coastguard Worker             }
247*bb4ee6a4SAndroid Build Coastguard Worker             msr_list[0].indices.as_slice(nmsrs as usize)
248*bb4ee6a4SAndroid Build Coastguard Worker         };
249*bb4ee6a4SAndroid Build Coastguard Worker 
250*bb4ee6a4SAndroid Build Coastguard Worker         Ok(indices.to_vec())
251*bb4ee6a4SAndroid Build Coastguard Worker     }
252*bb4ee6a4SAndroid Build Coastguard Worker 
253*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
254*bb4ee6a4SAndroid Build Coastguard Worker     // The x86 and riscv machine type is always 0
get_vm_type(&self) -> c_ulong255*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_vm_type(&self) -> c_ulong {
256*bb4ee6a4SAndroid Build Coastguard Worker         0
257*bb4ee6a4SAndroid Build Coastguard Worker     }
258*bb4ee6a4SAndroid Build Coastguard Worker 
259*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
260*bb4ee6a4SAndroid Build Coastguard Worker     // Compute the machine type, which should be the IPA range for the VM
261*bb4ee6a4SAndroid Build Coastguard Worker     // Ideally, this would take a description of the memory map and return
262*bb4ee6a4SAndroid Build Coastguard Worker     // the closest machine type for this VM. Here, we just return the maximum
263*bb4ee6a4SAndroid Build Coastguard Worker     // the kernel support.
264*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::useless_conversion)]
get_vm_type(&self) -> c_ulong265*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_vm_type(&self) -> c_ulong {
266*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
267*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know self is a real kvm fd
268*bb4ee6a4SAndroid Build Coastguard Worker         match unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE.into()) } {
269*bb4ee6a4SAndroid Build Coastguard Worker             // Not supported? Use 0 as the machine type, which implies 40bit IPA
270*bb4ee6a4SAndroid Build Coastguard Worker             ret if ret < 0 => 0,
271*bb4ee6a4SAndroid Build Coastguard Worker             // Use the lower 8 bits representing the IPA space as the machine type
272*bb4ee6a4SAndroid Build Coastguard Worker             ipa => (ipa & 0xff) as c_ulong,
273*bb4ee6a4SAndroid Build Coastguard Worker         }
274*bb4ee6a4SAndroid Build Coastguard Worker     }
275*bb4ee6a4SAndroid Build Coastguard Worker }
276*bb4ee6a4SAndroid Build Coastguard Worker 
277*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Kvm {
as_raw_descriptor(&self) -> RawDescriptor278*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
279*bb4ee6a4SAndroid Build Coastguard Worker         self.kvm.as_raw_descriptor()
280*bb4ee6a4SAndroid Build Coastguard Worker     }
281*bb4ee6a4SAndroid Build Coastguard Worker }
282*bb4ee6a4SAndroid Build Coastguard Worker 
283*bb4ee6a4SAndroid Build Coastguard Worker /// An address either in programmable I/O space or in memory mapped I/O space.
284*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug)]
285*bb4ee6a4SAndroid Build Coastguard Worker pub enum IoeventAddress {
286*bb4ee6a4SAndroid Build Coastguard Worker     Pio(u64),
287*bb4ee6a4SAndroid Build Coastguard Worker     Mmio(u64),
288*bb4ee6a4SAndroid Build Coastguard Worker }
289*bb4ee6a4SAndroid Build Coastguard Worker 
290*bb4ee6a4SAndroid Build Coastguard Worker /// Used in `Vm::register_ioevent` to indicate a size and optionally value to match.
291*bb4ee6a4SAndroid Build Coastguard Worker pub enum Datamatch {
292*bb4ee6a4SAndroid Build Coastguard Worker     AnyLength,
293*bb4ee6a4SAndroid Build Coastguard Worker     U8(Option<u8>),
294*bb4ee6a4SAndroid Build Coastguard Worker     U16(Option<u16>),
295*bb4ee6a4SAndroid Build Coastguard Worker     U32(Option<u32>),
296*bb4ee6a4SAndroid Build Coastguard Worker     U64(Option<u64>),
297*bb4ee6a4SAndroid Build Coastguard Worker }
298*bb4ee6a4SAndroid Build Coastguard Worker 
299*bb4ee6a4SAndroid Build Coastguard Worker /// A source of IRQs in an `IrqRoute`.
300*bb4ee6a4SAndroid Build Coastguard Worker pub enum IrqSource {
301*bb4ee6a4SAndroid Build Coastguard Worker     Irqchip { chip: u32, pin: u32 },
302*bb4ee6a4SAndroid Build Coastguard Worker     Msi { address: u64, data: u32 },
303*bb4ee6a4SAndroid Build Coastguard Worker }
304*bb4ee6a4SAndroid Build Coastguard Worker 
305*bb4ee6a4SAndroid Build Coastguard Worker /// A single route for an IRQ.
306*bb4ee6a4SAndroid Build Coastguard Worker pub struct IrqRoute {
307*bb4ee6a4SAndroid Build Coastguard Worker     pub gsi: u32,
308*bb4ee6a4SAndroid Build Coastguard Worker     pub source: IrqSource,
309*bb4ee6a4SAndroid Build Coastguard Worker }
310*bb4ee6a4SAndroid Build Coastguard Worker 
311*bb4ee6a4SAndroid Build Coastguard Worker /// Interrupt controller IDs
312*bb4ee6a4SAndroid Build Coastguard Worker pub enum PicId {
313*bb4ee6a4SAndroid Build Coastguard Worker     Primary = 0,
314*bb4ee6a4SAndroid Build Coastguard Worker     Secondary = 1,
315*bb4ee6a4SAndroid Build Coastguard Worker }
316*bb4ee6a4SAndroid Build Coastguard Worker 
317*bb4ee6a4SAndroid Build Coastguard Worker /// Number of pins on the IOAPIC.
318*bb4ee6a4SAndroid Build Coastguard Worker pub const NUM_IOAPIC_PINS: usize = 24;
319*bb4ee6a4SAndroid Build Coastguard Worker 
320*bb4ee6a4SAndroid Build Coastguard Worker // Used to invert the order when stored in a max-heap.
321*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Eq, PartialEq)]
322*bb4ee6a4SAndroid Build Coastguard Worker struct MemSlot(u32);
323*bb4ee6a4SAndroid Build Coastguard Worker 
324*bb4ee6a4SAndroid Build Coastguard Worker impl Ord for MemSlot {
cmp(&self, other: &MemSlot) -> Ordering325*bb4ee6a4SAndroid Build Coastguard Worker     fn cmp(&self, other: &MemSlot) -> Ordering {
326*bb4ee6a4SAndroid Build Coastguard Worker         // Notice the order is inverted so the lowest magnitude slot has the highest priority in a
327*bb4ee6a4SAndroid Build Coastguard Worker         // max-heap.
328*bb4ee6a4SAndroid Build Coastguard Worker         other.0.cmp(&self.0)
329*bb4ee6a4SAndroid Build Coastguard Worker     }
330*bb4ee6a4SAndroid Build Coastguard Worker }
331*bb4ee6a4SAndroid Build Coastguard Worker 
332*bb4ee6a4SAndroid Build Coastguard Worker impl PartialOrd for MemSlot {
partial_cmp(&self, other: &MemSlot) -> Option<Ordering>333*bb4ee6a4SAndroid Build Coastguard Worker     fn partial_cmp(&self, other: &MemSlot) -> Option<Ordering> {
334*bb4ee6a4SAndroid Build Coastguard Worker         Some(self.cmp(other))
335*bb4ee6a4SAndroid Build Coastguard Worker     }
336*bb4ee6a4SAndroid Build Coastguard Worker }
337*bb4ee6a4SAndroid Build Coastguard Worker 
338*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around creating and using a VM.
339*bb4ee6a4SAndroid Build Coastguard Worker pub struct Vm {
340*bb4ee6a4SAndroid Build Coastguard Worker     vm: File,
341*bb4ee6a4SAndroid Build Coastguard Worker     guest_mem: GuestMemory,
342*bb4ee6a4SAndroid Build Coastguard Worker     mem_regions: Arc<Mutex<BTreeMap<u32, Box<dyn MappedRegion>>>>,
343*bb4ee6a4SAndroid Build Coastguard Worker     mem_slot_gaps: Arc<Mutex<BinaryHeap<MemSlot>>>,
344*bb4ee6a4SAndroid Build Coastguard Worker }
345*bb4ee6a4SAndroid Build Coastguard Worker 
346*bb4ee6a4SAndroid Build Coastguard Worker impl Vm {
347*bb4ee6a4SAndroid Build Coastguard Worker     /// Constructs a new `Vm` using the given `Kvm` instance.
new(kvm: &Kvm, guest_mem: GuestMemory) -> Result<Vm>348*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(kvm: &Kvm, guest_mem: GuestMemory) -> Result<Vm> {
349*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
350*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know kvm is a real kvm fd as this module is the only one that can make
351*bb4ee6a4SAndroid Build Coastguard Worker         // Kvm objects.
352*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_val(kvm, KVM_CREATE_VM, kvm.get_vm_type()) };
353*bb4ee6a4SAndroid Build Coastguard Worker         if ret >= 0 {
354*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
355*bb4ee6a4SAndroid Build Coastguard Worker             // Safe because we verify the value of ret and we are the owners of the fd.
356*bb4ee6a4SAndroid Build Coastguard Worker             let vm_file = unsafe { File::from_raw_descriptor(ret) };
357*bb4ee6a4SAndroid Build Coastguard Worker             for region in guest_mem.regions() {
358*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
359*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because the guest regions are guaranteed not to overlap.
360*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe {
361*bb4ee6a4SAndroid Build Coastguard Worker                     set_user_memory_region(
362*bb4ee6a4SAndroid Build Coastguard Worker                         &vm_file,
363*bb4ee6a4SAndroid Build Coastguard Worker                         region.index as u32,
364*bb4ee6a4SAndroid Build Coastguard Worker                         false,
365*bb4ee6a4SAndroid Build Coastguard Worker                         false,
366*bb4ee6a4SAndroid Build Coastguard Worker                         region.guest_addr.offset(),
367*bb4ee6a4SAndroid Build Coastguard Worker                         region.size as u64,
368*bb4ee6a4SAndroid Build Coastguard Worker                         region.host_addr as *mut u8,
369*bb4ee6a4SAndroid Build Coastguard Worker                     )
370*bb4ee6a4SAndroid Build Coastguard Worker                 }?;
371*bb4ee6a4SAndroid Build Coastguard Worker             }
372*bb4ee6a4SAndroid Build Coastguard Worker 
373*bb4ee6a4SAndroid Build Coastguard Worker             Ok(Vm {
374*bb4ee6a4SAndroid Build Coastguard Worker                 vm: vm_file,
375*bb4ee6a4SAndroid Build Coastguard Worker                 guest_mem,
376*bb4ee6a4SAndroid Build Coastguard Worker                 mem_regions: Arc::new(Mutex::new(BTreeMap::new())),
377*bb4ee6a4SAndroid Build Coastguard Worker                 mem_slot_gaps: Arc::new(Mutex::new(BinaryHeap::new())),
378*bb4ee6a4SAndroid Build Coastguard Worker             })
379*bb4ee6a4SAndroid Build Coastguard Worker         } else {
380*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
381*bb4ee6a4SAndroid Build Coastguard Worker         }
382*bb4ee6a4SAndroid Build Coastguard Worker     }
383*bb4ee6a4SAndroid Build Coastguard Worker 
384*bb4ee6a4SAndroid Build Coastguard Worker     /// Checks if a particular `Cap` is available.
385*bb4ee6a4SAndroid Build Coastguard Worker     ///
386*bb4ee6a4SAndroid Build Coastguard Worker     /// This is distinct from the `Kvm` version of this method because the some extensions depend on
387*bb4ee6a4SAndroid Build Coastguard Worker     /// the particular `Vm` existence. This method is encouraged by the kernel because it more
388*bb4ee6a4SAndroid Build Coastguard Worker     /// accurately reflects the usable capabilities.
check_extension(&self, c: Cap) -> bool389*bb4ee6a4SAndroid Build Coastguard Worker     pub fn check_extension(&self, c: Cap) -> bool {
390*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
391*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a KVM fd and that the extension is one of the ones
392*bb4ee6a4SAndroid Build Coastguard Worker         // defined by kernel.
393*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION, c as c_ulong) == 1 }
394*bb4ee6a4SAndroid Build Coastguard Worker     }
395*bb4ee6a4SAndroid Build Coastguard Worker 
396*bb4ee6a4SAndroid Build Coastguard Worker     /// Inserts the given `mem` into the VM's address space at `guest_addr`.
397*bb4ee6a4SAndroid Build Coastguard Worker     ///
398*bb4ee6a4SAndroid Build Coastguard Worker     /// The slot that was assigned the kvm memory mapping is returned on success. The slot can be
399*bb4ee6a4SAndroid Build Coastguard Worker     /// given to `Vm::remove_memory_region` to remove the memory from the VM's address space and
400*bb4ee6a4SAndroid Build Coastguard Worker     /// take back ownership of `mem`.
401*bb4ee6a4SAndroid Build Coastguard Worker     ///
402*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that memory inserted into the VM's address space must not overlap with any other memory
403*bb4ee6a4SAndroid Build Coastguard Worker     /// slot's region.
404*bb4ee6a4SAndroid Build Coastguard Worker     ///
405*bb4ee6a4SAndroid Build Coastguard Worker     /// If `read_only` is true, the guest will be able to read the memory as normal, but attempts to
406*bb4ee6a4SAndroid Build Coastguard Worker     /// write will trigger a mmio VM exit, leaving the memory untouched.
407*bb4ee6a4SAndroid Build Coastguard Worker     ///
408*bb4ee6a4SAndroid Build Coastguard Worker     /// If `log_dirty_pages` is true, the slot number can be used to retrieve the pages written to
409*bb4ee6a4SAndroid Build Coastguard Worker     /// by the guest with `get_dirty_log`.
add_memory_region( &mut self, guest_addr: GuestAddress, mem: Box<dyn MappedRegion>, read_only: bool, log_dirty_pages: bool, ) -> Result<u32>410*bb4ee6a4SAndroid Build Coastguard Worker     pub fn add_memory_region(
411*bb4ee6a4SAndroid Build Coastguard Worker         &mut self,
412*bb4ee6a4SAndroid Build Coastguard Worker         guest_addr: GuestAddress,
413*bb4ee6a4SAndroid Build Coastguard Worker         mem: Box<dyn MappedRegion>,
414*bb4ee6a4SAndroid Build Coastguard Worker         read_only: bool,
415*bb4ee6a4SAndroid Build Coastguard Worker         log_dirty_pages: bool,
416*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<u32> {
417*bb4ee6a4SAndroid Build Coastguard Worker         let size = mem.size() as u64;
418*bb4ee6a4SAndroid Build Coastguard Worker         let end_addr = guest_addr
419*bb4ee6a4SAndroid Build Coastguard Worker             .checked_add(size)
420*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or_else(|| Error::new(EOVERFLOW))?;
421*bb4ee6a4SAndroid Build Coastguard Worker         if self.guest_mem.range_overlap(guest_addr, end_addr) {
422*bb4ee6a4SAndroid Build Coastguard Worker             return Err(Error::new(ENOSPC));
423*bb4ee6a4SAndroid Build Coastguard Worker         }
424*bb4ee6a4SAndroid Build Coastguard Worker         let mut regions = self.mem_regions.lock();
425*bb4ee6a4SAndroid Build Coastguard Worker         let mut gaps = self.mem_slot_gaps.lock();
426*bb4ee6a4SAndroid Build Coastguard Worker         let slot = match gaps.pop() {
427*bb4ee6a4SAndroid Build Coastguard Worker             Some(gap) => gap.0,
428*bb4ee6a4SAndroid Build Coastguard Worker             None => (regions.len() + self.guest_mem.num_regions() as usize) as u32,
429*bb4ee6a4SAndroid Build Coastguard Worker         };
430*bb4ee6a4SAndroid Build Coastguard Worker 
431*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
432*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we check that the given guest address is valid and has no overlaps. We also
433*bb4ee6a4SAndroid Build Coastguard Worker         // know that the pointer and size are correct because the MemoryMapping interface ensures
434*bb4ee6a4SAndroid Build Coastguard Worker         // this. We take ownership of the memory mapping so that it won't be unmapped until the slot
435*bb4ee6a4SAndroid Build Coastguard Worker         // is removed.
436*bb4ee6a4SAndroid Build Coastguard Worker         let res = unsafe {
437*bb4ee6a4SAndroid Build Coastguard Worker             set_user_memory_region(
438*bb4ee6a4SAndroid Build Coastguard Worker                 &self.vm,
439*bb4ee6a4SAndroid Build Coastguard Worker                 slot,
440*bb4ee6a4SAndroid Build Coastguard Worker                 read_only,
441*bb4ee6a4SAndroid Build Coastguard Worker                 log_dirty_pages,
442*bb4ee6a4SAndroid Build Coastguard Worker                 guest_addr.offset(),
443*bb4ee6a4SAndroid Build Coastguard Worker                 size,
444*bb4ee6a4SAndroid Build Coastguard Worker                 mem.as_ptr(),
445*bb4ee6a4SAndroid Build Coastguard Worker             )
446*bb4ee6a4SAndroid Build Coastguard Worker         };
447*bb4ee6a4SAndroid Build Coastguard Worker 
448*bb4ee6a4SAndroid Build Coastguard Worker         if let Err(e) = res {
449*bb4ee6a4SAndroid Build Coastguard Worker             gaps.push(MemSlot(slot));
450*bb4ee6a4SAndroid Build Coastguard Worker             return Err(e);
451*bb4ee6a4SAndroid Build Coastguard Worker         }
452*bb4ee6a4SAndroid Build Coastguard Worker         regions.insert(slot, mem);
453*bb4ee6a4SAndroid Build Coastguard Worker         Ok(slot)
454*bb4ee6a4SAndroid Build Coastguard Worker     }
455*bb4ee6a4SAndroid Build Coastguard Worker 
456*bb4ee6a4SAndroid Build Coastguard Worker     /// Removes memory that was previously added at the given slot.
457*bb4ee6a4SAndroid Build Coastguard Worker     ///
458*bb4ee6a4SAndroid Build Coastguard Worker     /// Ownership of the host memory mapping associated with the given slot is returned on success.
remove_memory_region(&mut self, slot: u32) -> Result<Box<dyn MappedRegion>>459*bb4ee6a4SAndroid Build Coastguard Worker     pub fn remove_memory_region(&mut self, slot: u32) -> Result<Box<dyn MappedRegion>> {
460*bb4ee6a4SAndroid Build Coastguard Worker         let mut regions = self.mem_regions.lock();
461*bb4ee6a4SAndroid Build Coastguard Worker         if !regions.contains_key(&slot) {
462*bb4ee6a4SAndroid Build Coastguard Worker             return Err(Error::new(ENOENT));
463*bb4ee6a4SAndroid Build Coastguard Worker         }
464*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
465*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the slot is checked against the list of memory slots.
466*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
467*bb4ee6a4SAndroid Build Coastguard Worker             set_user_memory_region(&self.vm, slot, false, false, 0, 0, std::ptr::null_mut())?;
468*bb4ee6a4SAndroid Build Coastguard Worker         }
469*bb4ee6a4SAndroid Build Coastguard Worker         self.mem_slot_gaps.lock().push(MemSlot(slot));
470*bb4ee6a4SAndroid Build Coastguard Worker         // This remove will always succeed because of the contains_key check above.
471*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regions.remove(&slot).unwrap())
472*bb4ee6a4SAndroid Build Coastguard Worker     }
473*bb4ee6a4SAndroid Build Coastguard Worker 
474*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the bitmap of dirty pages since the last call to `get_dirty_log` for the memory at
475*bb4ee6a4SAndroid Build Coastguard Worker     /// `slot`.
476*bb4ee6a4SAndroid Build Coastguard Worker     ///
477*bb4ee6a4SAndroid Build Coastguard Worker     /// The size of `dirty_log` must be at least as many bits as there are pages in the memory
478*bb4ee6a4SAndroid Build Coastguard Worker     /// region `slot` represents. For example, if the size of `slot` is 16 pages, `dirty_log` must
479*bb4ee6a4SAndroid Build Coastguard Worker     /// be 2 bytes or greater.
get_dirty_log(&self, slot: u32, dirty_log: &mut [u8]) -> Result<()>480*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_dirty_log(&self, slot: u32, dirty_log: &mut [u8]) -> Result<()> {
481*bb4ee6a4SAndroid Build Coastguard Worker         match self.mem_regions.lock().get(&slot) {
482*bb4ee6a4SAndroid Build Coastguard Worker             Some(mem) => {
483*bb4ee6a4SAndroid Build Coastguard Worker                 // Ensures that there are as many bytes in dirty_log as there are pages in the mmap.
484*bb4ee6a4SAndroid Build Coastguard Worker                 if dirty_log_bitmap_size(mem.size()) > dirty_log.len() {
485*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
486*bb4ee6a4SAndroid Build Coastguard Worker                 }
487*bb4ee6a4SAndroid Build Coastguard Worker                 let mut dirty_log_kvm = kvm_dirty_log {
488*bb4ee6a4SAndroid Build Coastguard Worker                     slot,
489*bb4ee6a4SAndroid Build Coastguard Worker                     ..Default::default()
490*bb4ee6a4SAndroid Build Coastguard Worker                 };
491*bb4ee6a4SAndroid Build Coastguard Worker                 dirty_log_kvm.__bindgen_anon_1.dirty_bitmap = dirty_log.as_ptr() as *mut c_void;
492*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
493*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because the `dirty_bitmap` pointer assigned above is guaranteed to be valid
494*bb4ee6a4SAndroid Build Coastguard Worker                 // (because it's from a slice) and we checked that it will be large enough to hold
495*bb4ee6a4SAndroid Build Coastguard Worker                 // the entire log.
496*bb4ee6a4SAndroid Build Coastguard Worker                 let ret = unsafe { ioctl_with_ref(self, KVM_GET_DIRTY_LOG, &dirty_log_kvm) };
497*bb4ee6a4SAndroid Build Coastguard Worker                 if ret == 0 {
498*bb4ee6a4SAndroid Build Coastguard Worker                     Ok(())
499*bb4ee6a4SAndroid Build Coastguard Worker                 } else {
500*bb4ee6a4SAndroid Build Coastguard Worker                     errno_result()
501*bb4ee6a4SAndroid Build Coastguard Worker                 }
502*bb4ee6a4SAndroid Build Coastguard Worker             }
503*bb4ee6a4SAndroid Build Coastguard Worker             _ => Err(Error::new(ENOENT)),
504*bb4ee6a4SAndroid Build Coastguard Worker         }
505*bb4ee6a4SAndroid Build Coastguard Worker     }
506*bb4ee6a4SAndroid Build Coastguard Worker 
507*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets a reference to the guest memory owned by this VM.
508*bb4ee6a4SAndroid Build Coastguard Worker     ///
509*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that `GuestMemory` does not include any mmio memory that may have been added after
510*bb4ee6a4SAndroid Build Coastguard Worker     /// this VM was constructed.
get_memory(&self) -> &GuestMemory511*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_memory(&self) -> &GuestMemory {
512*bb4ee6a4SAndroid Build Coastguard Worker         &self.guest_mem
513*bb4ee6a4SAndroid Build Coastguard Worker     }
514*bb4ee6a4SAndroid Build Coastguard Worker 
515*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the address of a one-page region in the VM's address space.
516*bb4ee6a4SAndroid Build Coastguard Worker     ///
517*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation on the KVM_SET_IDENTITY_MAP_ADDR ioctl.
518*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_identity_map_addr(&self, addr: GuestAddress) -> Result<()>519*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_identity_map_addr(&self, addr: GuestAddress) -> Result<()> {
520*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
521*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd and we verify the return result.
522*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_IDENTITY_MAP_ADDR, &addr.offset()) };
523*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
524*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
525*bb4ee6a4SAndroid Build Coastguard Worker         } else {
526*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
527*bb4ee6a4SAndroid Build Coastguard Worker         }
528*bb4ee6a4SAndroid Build Coastguard Worker     }
529*bb4ee6a4SAndroid Build Coastguard Worker 
530*bb4ee6a4SAndroid Build Coastguard Worker     /// Retrieves the current timestamp of kvmclock as seen by the current guest.
531*bb4ee6a4SAndroid Build Coastguard Worker     ///
532*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation on the KVM_GET_CLOCK ioctl.
533*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_clock(&self) -> Result<kvm_clock_data>534*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_clock(&self) -> Result<kvm_clock_data> {
535*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
536*bb4ee6a4SAndroid Build Coastguard Worker         let mut clock_data = unsafe { std::mem::zeroed() };
537*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
538*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only write
539*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
540*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_CLOCK, &mut clock_data) };
541*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
542*bb4ee6a4SAndroid Build Coastguard Worker             Ok(clock_data)
543*bb4ee6a4SAndroid Build Coastguard Worker         } else {
544*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
545*bb4ee6a4SAndroid Build Coastguard Worker         }
546*bb4ee6a4SAndroid Build Coastguard Worker     }
547*bb4ee6a4SAndroid Build Coastguard Worker 
548*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the current timestamp of kvmclock to the specified value.
549*bb4ee6a4SAndroid Build Coastguard Worker     ///
550*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation on the KVM_SET_CLOCK ioctl.
551*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_clock(&self, clock_data: &kvm_clock_data) -> Result<()>552*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_clock(&self, clock_data: &kvm_clock_data) -> Result<()> {
553*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
554*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read
555*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
556*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_CLOCK, clock_data) };
557*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
558*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
559*bb4ee6a4SAndroid Build Coastguard Worker         } else {
560*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
561*bb4ee6a4SAndroid Build Coastguard Worker         }
562*bb4ee6a4SAndroid Build Coastguard Worker     }
563*bb4ee6a4SAndroid Build Coastguard Worker 
564*bb4ee6a4SAndroid Build Coastguard Worker     /// Crates an in kernel interrupt controller.
565*bb4ee6a4SAndroid Build Coastguard Worker     ///
566*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation on the KVM_CREATE_IRQCHIP ioctl.
567*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
create_irq_chip(&self) -> Result<()>568*bb4ee6a4SAndroid Build Coastguard Worker     pub fn create_irq_chip(&self) -> Result<()> {
569*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
570*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd and we verify the return result.
571*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl(self, KVM_CREATE_IRQCHIP) };
572*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
573*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
574*bb4ee6a4SAndroid Build Coastguard Worker         } else {
575*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
576*bb4ee6a4SAndroid Build Coastguard Worker         }
577*bb4ee6a4SAndroid Build Coastguard Worker     }
578*bb4ee6a4SAndroid Build Coastguard Worker 
579*bb4ee6a4SAndroid Build Coastguard Worker     /// Retrieves the state of given interrupt controller by issuing KVM_GET_IRQCHIP ioctl.
580*bb4ee6a4SAndroid Build Coastguard Worker     ///
581*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
582*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_pic_state(&self, id: PicId) -> Result<kvm_pic_state>583*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_pic_state(&self, id: PicId) -> Result<kvm_pic_state> {
584*bb4ee6a4SAndroid Build Coastguard Worker         let mut irqchip_state = kvm_irqchip {
585*bb4ee6a4SAndroid Build Coastguard Worker             chip_id: id as u32,
586*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
587*bb4ee6a4SAndroid Build Coastguard Worker         };
588*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
589*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know our file is a VM fd, we know the kernel will only write
590*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
591*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_IRQCHIP, &mut irqchip_state) };
592*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
593*bb4ee6a4SAndroid Build Coastguard Worker             Ok(
594*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
595*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe as we know that we are retrieving data related to the
596*bb4ee6a4SAndroid Build Coastguard Worker                 // PIC (primary or secondary) and not IOAPIC.
597*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe { irqchip_state.chip.pic },
598*bb4ee6a4SAndroid Build Coastguard Worker             )
599*bb4ee6a4SAndroid Build Coastguard Worker         } else {
600*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
601*bb4ee6a4SAndroid Build Coastguard Worker         }
602*bb4ee6a4SAndroid Build Coastguard Worker     }
603*bb4ee6a4SAndroid Build Coastguard Worker 
604*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the state of given interrupt controller by issuing KVM_SET_IRQCHIP ioctl.
605*bb4ee6a4SAndroid Build Coastguard Worker     ///
606*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
607*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_pic_state(&self, id: PicId, state: &kvm_pic_state) -> Result<()>608*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_pic_state(&self, id: PicId, state: &kvm_pic_state) -> Result<()> {
609*bb4ee6a4SAndroid Build Coastguard Worker         let mut irqchip_state = kvm_irqchip {
610*bb4ee6a4SAndroid Build Coastguard Worker             chip_id: id as u32,
611*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
612*bb4ee6a4SAndroid Build Coastguard Worker         };
613*bb4ee6a4SAndroid Build Coastguard Worker         irqchip_state.chip.pic = *state;
614*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
615*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read
616*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
617*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_IRQCHIP, &irqchip_state) };
618*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
619*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
620*bb4ee6a4SAndroid Build Coastguard Worker         } else {
621*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
622*bb4ee6a4SAndroid Build Coastguard Worker         }
623*bb4ee6a4SAndroid Build Coastguard Worker     }
624*bb4ee6a4SAndroid Build Coastguard Worker 
625*bb4ee6a4SAndroid Build Coastguard Worker     /// Retrieves the state of IOAPIC by issuing KVM_GET_IRQCHIP ioctl.
626*bb4ee6a4SAndroid Build Coastguard Worker     ///
627*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
628*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_ioapic_state(&self) -> Result<kvm_ioapic_state>629*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_ioapic_state(&self) -> Result<kvm_ioapic_state> {
630*bb4ee6a4SAndroid Build Coastguard Worker         let mut irqchip_state = kvm_irqchip {
631*bb4ee6a4SAndroid Build Coastguard Worker             chip_id: 2,
632*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
633*bb4ee6a4SAndroid Build Coastguard Worker         };
634*bb4ee6a4SAndroid Build Coastguard Worker         let ret =
635*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
636*bb4ee6a4SAndroid Build Coastguard Worker             // Safe because we know our file is a VM fd, we know the kernel will only write
637*bb4ee6a4SAndroid Build Coastguard Worker             // correct amount of memory to our pointer, and we verify the return result.
638*bb4ee6a4SAndroid Build Coastguard Worker             unsafe {
639*bb4ee6a4SAndroid Build Coastguard Worker                 ioctl_with_mut_ref(self, KVM_GET_IRQCHIP, &mut irqchip_state)
640*bb4ee6a4SAndroid Build Coastguard Worker         };
641*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
642*bb4ee6a4SAndroid Build Coastguard Worker             Ok(
643*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
644*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe as we know that we are retrieving data related to the
645*bb4ee6a4SAndroid Build Coastguard Worker                 // IOAPIC and not PIC.
646*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe { irqchip_state.chip.ioapic },
647*bb4ee6a4SAndroid Build Coastguard Worker             )
648*bb4ee6a4SAndroid Build Coastguard Worker         } else {
649*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
650*bb4ee6a4SAndroid Build Coastguard Worker         }
651*bb4ee6a4SAndroid Build Coastguard Worker     }
652*bb4ee6a4SAndroid Build Coastguard Worker 
653*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the state of IOAPIC by issuing KVM_SET_IRQCHIP ioctl.
654*bb4ee6a4SAndroid Build Coastguard Worker     ///
655*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
656*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_ioapic_state(&self, state: &kvm_ioapic_state) -> Result<()>657*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_ioapic_state(&self, state: &kvm_ioapic_state) -> Result<()> {
658*bb4ee6a4SAndroid Build Coastguard Worker         let mut irqchip_state = kvm_irqchip {
659*bb4ee6a4SAndroid Build Coastguard Worker             chip_id: 2,
660*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
661*bb4ee6a4SAndroid Build Coastguard Worker         };
662*bb4ee6a4SAndroid Build Coastguard Worker         irqchip_state.chip.ioapic = *state;
663*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
664*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read
665*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
666*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_IRQCHIP, &irqchip_state) };
667*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
668*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
669*bb4ee6a4SAndroid Build Coastguard Worker         } else {
670*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
671*bb4ee6a4SAndroid Build Coastguard Worker         }
672*bb4ee6a4SAndroid Build Coastguard Worker     }
673*bb4ee6a4SAndroid Build Coastguard Worker 
674*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the level on the given irq to 1 if `active` is true, and 0 otherwise.
675*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
set_irq_line(&self, irq: u32, active: bool) -> Result<()>676*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_irq_line(&self, irq: u32, active: bool) -> Result<()> {
677*bb4ee6a4SAndroid Build Coastguard Worker         let mut irq_level = kvm_irq_level::default();
678*bb4ee6a4SAndroid Build Coastguard Worker         irq_level.__bindgen_anon_1.irq = irq;
679*bb4ee6a4SAndroid Build Coastguard Worker         irq_level.level = active.into();
680*bb4ee6a4SAndroid Build Coastguard Worker 
681*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
682*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read the
683*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
684*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_IRQ_LINE, &irq_level) };
685*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
686*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
687*bb4ee6a4SAndroid Build Coastguard Worker         } else {
688*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
689*bb4ee6a4SAndroid Build Coastguard Worker         }
690*bb4ee6a4SAndroid Build Coastguard Worker     }
691*bb4ee6a4SAndroid Build Coastguard Worker 
692*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a PIT as per the KVM_CREATE_PIT2 ioctl.
693*bb4ee6a4SAndroid Build Coastguard Worker     ///
694*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
695*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
create_pit(&self) -> Result<()>696*bb4ee6a4SAndroid Build Coastguard Worker     pub fn create_pit(&self) -> Result<()> {
697*bb4ee6a4SAndroid Build Coastguard Worker         let pit_config = kvm_pit_config::default();
698*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
699*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read the
700*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
701*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_CREATE_PIT2, &pit_config) };
702*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
703*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
704*bb4ee6a4SAndroid Build Coastguard Worker         } else {
705*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
706*bb4ee6a4SAndroid Build Coastguard Worker         }
707*bb4ee6a4SAndroid Build Coastguard Worker     }
708*bb4ee6a4SAndroid Build Coastguard Worker 
709*bb4ee6a4SAndroid Build Coastguard Worker     /// Retrieves the state of PIT by issuing KVM_GET_PIT2 ioctl.
710*bb4ee6a4SAndroid Build Coastguard Worker     ///
711*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_pit`.
712*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_pit_state(&self) -> Result<kvm_pit_state2>713*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_pit_state(&self) -> Result<kvm_pit_state2> {
714*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
715*bb4ee6a4SAndroid Build Coastguard Worker         let mut pit_state = unsafe { std::mem::zeroed() };
716*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
717*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only write
718*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
719*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_PIT2, &mut pit_state) };
720*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
721*bb4ee6a4SAndroid Build Coastguard Worker             Ok(pit_state)
722*bb4ee6a4SAndroid Build Coastguard Worker         } else {
723*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
724*bb4ee6a4SAndroid Build Coastguard Worker         }
725*bb4ee6a4SAndroid Build Coastguard Worker     }
726*bb4ee6a4SAndroid Build Coastguard Worker 
727*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the state of PIT by issuing KVM_SET_PIT2 ioctl.
728*bb4ee6a4SAndroid Build Coastguard Worker     ///
729*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this call can only succeed after a call to `Vm::create_pit`.
730*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_pit_state(&self, pit_state: &kvm_pit_state2) -> Result<()>731*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_pit_state(&self, pit_state: &kvm_pit_state2) -> Result<()> {
732*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
733*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read
734*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
735*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_PIT2, pit_state) };
736*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
737*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
738*bb4ee6a4SAndroid Build Coastguard Worker         } else {
739*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
740*bb4ee6a4SAndroid Build Coastguard Worker         }
741*bb4ee6a4SAndroid Build Coastguard Worker     }
742*bb4ee6a4SAndroid Build Coastguard Worker 
743*bb4ee6a4SAndroid Build Coastguard Worker     /// Registers an event to be signaled whenever a certain address is written to.
744*bb4ee6a4SAndroid Build Coastguard Worker     ///
745*bb4ee6a4SAndroid Build Coastguard Worker     /// The `datamatch` parameter can be used to limit signaling `evt` to only the cases where the
746*bb4ee6a4SAndroid Build Coastguard Worker     /// value being written is equal to `datamatch`. Note that the size of `datamatch` is important
747*bb4ee6a4SAndroid Build Coastguard Worker     /// and must match the expected size of the guest's write.
748*bb4ee6a4SAndroid Build Coastguard Worker     ///
749*bb4ee6a4SAndroid Build Coastguard Worker     /// In all cases where `evt` is signaled, the ordinary vmexit to userspace that would be
750*bb4ee6a4SAndroid Build Coastguard Worker     /// triggered is prevented.
register_ioevent( &self, evt: &Event, addr: IoeventAddress, datamatch: Datamatch, ) -> Result<()>751*bb4ee6a4SAndroid Build Coastguard Worker     pub fn register_ioevent(
752*bb4ee6a4SAndroid Build Coastguard Worker         &self,
753*bb4ee6a4SAndroid Build Coastguard Worker         evt: &Event,
754*bb4ee6a4SAndroid Build Coastguard Worker         addr: IoeventAddress,
755*bb4ee6a4SAndroid Build Coastguard Worker         datamatch: Datamatch,
756*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
757*bb4ee6a4SAndroid Build Coastguard Worker         self.ioeventfd(evt, addr, datamatch, false)
758*bb4ee6a4SAndroid Build Coastguard Worker     }
759*bb4ee6a4SAndroid Build Coastguard Worker 
760*bb4ee6a4SAndroid Build Coastguard Worker     /// Unregisters an event previously registered with `register_ioevent`.
761*bb4ee6a4SAndroid Build Coastguard Worker     ///
762*bb4ee6a4SAndroid Build Coastguard Worker     /// The `evt`, `addr`, and `datamatch` set must be the same as the ones passed into
763*bb4ee6a4SAndroid Build Coastguard Worker     /// `register_ioevent`.
unregister_ioevent( &self, evt: &Event, addr: IoeventAddress, datamatch: Datamatch, ) -> Result<()>764*bb4ee6a4SAndroid Build Coastguard Worker     pub fn unregister_ioevent(
765*bb4ee6a4SAndroid Build Coastguard Worker         &self,
766*bb4ee6a4SAndroid Build Coastguard Worker         evt: &Event,
767*bb4ee6a4SAndroid Build Coastguard Worker         addr: IoeventAddress,
768*bb4ee6a4SAndroid Build Coastguard Worker         datamatch: Datamatch,
769*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
770*bb4ee6a4SAndroid Build Coastguard Worker         self.ioeventfd(evt, addr, datamatch, true)
771*bb4ee6a4SAndroid Build Coastguard Worker     }
772*bb4ee6a4SAndroid Build Coastguard Worker 
ioeventfd( &self, evt: &Event, addr: IoeventAddress, datamatch: Datamatch, deassign: bool, ) -> Result<()>773*bb4ee6a4SAndroid Build Coastguard Worker     fn ioeventfd(
774*bb4ee6a4SAndroid Build Coastguard Worker         &self,
775*bb4ee6a4SAndroid Build Coastguard Worker         evt: &Event,
776*bb4ee6a4SAndroid Build Coastguard Worker         addr: IoeventAddress,
777*bb4ee6a4SAndroid Build Coastguard Worker         datamatch: Datamatch,
778*bb4ee6a4SAndroid Build Coastguard Worker         deassign: bool,
779*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
780*bb4ee6a4SAndroid Build Coastguard Worker         let (do_datamatch, datamatch_value, datamatch_len) = match datamatch {
781*bb4ee6a4SAndroid Build Coastguard Worker             Datamatch::AnyLength => (false, 0, 0),
782*bb4ee6a4SAndroid Build Coastguard Worker             Datamatch::U8(v) => match v {
783*bb4ee6a4SAndroid Build Coastguard Worker                 Some(u) => (true, u as u64, 1),
784*bb4ee6a4SAndroid Build Coastguard Worker                 None => (false, 0, 1),
785*bb4ee6a4SAndroid Build Coastguard Worker             },
786*bb4ee6a4SAndroid Build Coastguard Worker             Datamatch::U16(v) => match v {
787*bb4ee6a4SAndroid Build Coastguard Worker                 Some(u) => (true, u as u64, 2),
788*bb4ee6a4SAndroid Build Coastguard Worker                 None => (false, 0, 2),
789*bb4ee6a4SAndroid Build Coastguard Worker             },
790*bb4ee6a4SAndroid Build Coastguard Worker             Datamatch::U32(v) => match v {
791*bb4ee6a4SAndroid Build Coastguard Worker                 Some(u) => (true, u as u64, 4),
792*bb4ee6a4SAndroid Build Coastguard Worker                 None => (false, 0, 4),
793*bb4ee6a4SAndroid Build Coastguard Worker             },
794*bb4ee6a4SAndroid Build Coastguard Worker             Datamatch::U64(v) => match v {
795*bb4ee6a4SAndroid Build Coastguard Worker                 Some(u) => (true, u, 8),
796*bb4ee6a4SAndroid Build Coastguard Worker                 None => (false, 0, 8),
797*bb4ee6a4SAndroid Build Coastguard Worker             },
798*bb4ee6a4SAndroid Build Coastguard Worker         };
799*bb4ee6a4SAndroid Build Coastguard Worker         let mut flags = 0;
800*bb4ee6a4SAndroid Build Coastguard Worker         if deassign {
801*bb4ee6a4SAndroid Build Coastguard Worker             flags |= 1 << kvm_ioeventfd_flag_nr_deassign;
802*bb4ee6a4SAndroid Build Coastguard Worker         }
803*bb4ee6a4SAndroid Build Coastguard Worker         if do_datamatch {
804*bb4ee6a4SAndroid Build Coastguard Worker             flags |= 1 << kvm_ioeventfd_flag_nr_datamatch
805*bb4ee6a4SAndroid Build Coastguard Worker         }
806*bb4ee6a4SAndroid Build Coastguard Worker         if let IoeventAddress::Pio(_) = addr {
807*bb4ee6a4SAndroid Build Coastguard Worker             flags |= 1 << kvm_ioeventfd_flag_nr_pio;
808*bb4ee6a4SAndroid Build Coastguard Worker         }
809*bb4ee6a4SAndroid Build Coastguard Worker         let ioeventfd = kvm_ioeventfd {
810*bb4ee6a4SAndroid Build Coastguard Worker             datamatch: datamatch_value,
811*bb4ee6a4SAndroid Build Coastguard Worker             len: datamatch_len,
812*bb4ee6a4SAndroid Build Coastguard Worker             addr: match addr {
813*bb4ee6a4SAndroid Build Coastguard Worker                 IoeventAddress::Pio(p) => p,
814*bb4ee6a4SAndroid Build Coastguard Worker                 IoeventAddress::Mmio(m) => m,
815*bb4ee6a4SAndroid Build Coastguard Worker             },
816*bb4ee6a4SAndroid Build Coastguard Worker             fd: evt.as_raw_descriptor(),
817*bb4ee6a4SAndroid Build Coastguard Worker             flags,
818*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
819*bb4ee6a4SAndroid Build Coastguard Worker         };
820*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
821*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read the
822*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
823*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_IOEVENTFD, &ioeventfd) };
824*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
825*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
826*bb4ee6a4SAndroid Build Coastguard Worker         } else {
827*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
828*bb4ee6a4SAndroid Build Coastguard Worker         }
829*bb4ee6a4SAndroid Build Coastguard Worker     }
830*bb4ee6a4SAndroid Build Coastguard Worker 
831*bb4ee6a4SAndroid Build Coastguard Worker     /// Registers an event that will, when signalled, trigger the `gsi` irq, and `resample_evt` will
832*bb4ee6a4SAndroid Build Coastguard Worker     /// get triggered when the irqchip is resampled.
833*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
register_irqfd_resample( &self, evt: &Event, resample_evt: &Event, gsi: u32, ) -> Result<()>834*bb4ee6a4SAndroid Build Coastguard Worker     pub fn register_irqfd_resample(
835*bb4ee6a4SAndroid Build Coastguard Worker         &self,
836*bb4ee6a4SAndroid Build Coastguard Worker         evt: &Event,
837*bb4ee6a4SAndroid Build Coastguard Worker         resample_evt: &Event,
838*bb4ee6a4SAndroid Build Coastguard Worker         gsi: u32,
839*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
840*bb4ee6a4SAndroid Build Coastguard Worker         let irqfd = kvm_irqfd {
841*bb4ee6a4SAndroid Build Coastguard Worker             flags: KVM_IRQFD_FLAG_RESAMPLE,
842*bb4ee6a4SAndroid Build Coastguard Worker             fd: evt.as_raw_descriptor() as u32,
843*bb4ee6a4SAndroid Build Coastguard Worker             resamplefd: resample_evt.as_raw_descriptor() as u32,
844*bb4ee6a4SAndroid Build Coastguard Worker             gsi,
845*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
846*bb4ee6a4SAndroid Build Coastguard Worker         };
847*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
848*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read the
849*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
850*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_IRQFD, &irqfd) };
851*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
852*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
853*bb4ee6a4SAndroid Build Coastguard Worker         } else {
854*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
855*bb4ee6a4SAndroid Build Coastguard Worker         }
856*bb4ee6a4SAndroid Build Coastguard Worker     }
857*bb4ee6a4SAndroid Build Coastguard Worker 
858*bb4ee6a4SAndroid Build Coastguard Worker     /// Unregisters an event that was previously registered with
859*bb4ee6a4SAndroid Build Coastguard Worker     /// `register_irqfd`/`register_irqfd_resample`.
860*bb4ee6a4SAndroid Build Coastguard Worker     ///
861*bb4ee6a4SAndroid Build Coastguard Worker     /// The `evt` and `gsi` pair must be the same as the ones passed into
862*bb4ee6a4SAndroid Build Coastguard Worker     /// `register_irqfd`/`register_irqfd_resample`.
863*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
unregister_irqfd(&self, evt: &Event, gsi: u32) -> Result<()>864*bb4ee6a4SAndroid Build Coastguard Worker     pub fn unregister_irqfd(&self, evt: &Event, gsi: u32) -> Result<()> {
865*bb4ee6a4SAndroid Build Coastguard Worker         let irqfd = kvm_irqfd {
866*bb4ee6a4SAndroid Build Coastguard Worker             fd: evt.as_raw_descriptor() as u32,
867*bb4ee6a4SAndroid Build Coastguard Worker             gsi,
868*bb4ee6a4SAndroid Build Coastguard Worker             flags: KVM_IRQFD_FLAG_DEASSIGN,
869*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
870*bb4ee6a4SAndroid Build Coastguard Worker         };
871*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
872*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VM fd, we know the kernel will only read the
873*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
874*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_IRQFD, &irqfd) };
875*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
876*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
877*bb4ee6a4SAndroid Build Coastguard Worker         } else {
878*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
879*bb4ee6a4SAndroid Build Coastguard Worker         }
880*bb4ee6a4SAndroid Build Coastguard Worker     }
881*bb4ee6a4SAndroid Build Coastguard Worker 
882*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the GSI routing table, replacing any table set with previous calls to
883*bb4ee6a4SAndroid Build Coastguard Worker     /// `set_gsi_routing`.
884*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_gsi_routing(&self, routes: &[IrqRoute]) -> Result<()>885*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_gsi_routing(&self, routes: &[IrqRoute]) -> Result<()> {
886*bb4ee6a4SAndroid Build Coastguard Worker         let mut irq_routing =
887*bb4ee6a4SAndroid Build Coastguard Worker             vec_with_array_field::<kvm_irq_routing, kvm_irq_routing_entry>(routes.len());
888*bb4ee6a4SAndroid Build Coastguard Worker         irq_routing[0].nr = routes.len() as u32;
889*bb4ee6a4SAndroid Build Coastguard Worker 
890*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
891*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we ensured there is enough space in irq_routing to hold the number of
892*bb4ee6a4SAndroid Build Coastguard Worker         // route entries.
893*bb4ee6a4SAndroid Build Coastguard Worker         let irq_routes = unsafe { irq_routing[0].entries.as_mut_slice(routes.len()) };
894*bb4ee6a4SAndroid Build Coastguard Worker         for (route, irq_route) in routes.iter().zip(irq_routes.iter_mut()) {
895*bb4ee6a4SAndroid Build Coastguard Worker             irq_route.gsi = route.gsi;
896*bb4ee6a4SAndroid Build Coastguard Worker             match route.source {
897*bb4ee6a4SAndroid Build Coastguard Worker                 IrqSource::Irqchip { chip, pin } => {
898*bb4ee6a4SAndroid Build Coastguard Worker                     irq_route.type_ = KVM_IRQ_ROUTING_IRQCHIP;
899*bb4ee6a4SAndroid Build Coastguard Worker                     irq_route.u.irqchip = kvm_irq_routing_irqchip { irqchip: chip, pin }
900*bb4ee6a4SAndroid Build Coastguard Worker                 }
901*bb4ee6a4SAndroid Build Coastguard Worker                 IrqSource::Msi { address, data } => {
902*bb4ee6a4SAndroid Build Coastguard Worker                     irq_route.type_ = KVM_IRQ_ROUTING_MSI;
903*bb4ee6a4SAndroid Build Coastguard Worker                     irq_route.u.msi = kvm_irq_routing_msi {
904*bb4ee6a4SAndroid Build Coastguard Worker                         address_lo: address as u32,
905*bb4ee6a4SAndroid Build Coastguard Worker                         address_hi: (address >> 32) as u32,
906*bb4ee6a4SAndroid Build Coastguard Worker                         data,
907*bb4ee6a4SAndroid Build Coastguard Worker                         ..Default::default()
908*bb4ee6a4SAndroid Build Coastguard Worker                     }
909*bb4ee6a4SAndroid Build Coastguard Worker                 }
910*bb4ee6a4SAndroid Build Coastguard Worker             }
911*bb4ee6a4SAndroid Build Coastguard Worker         }
912*bb4ee6a4SAndroid Build Coastguard Worker 
913*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
914*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
915*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_GSI_ROUTING, &irq_routing[0]) };
916*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
917*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
918*bb4ee6a4SAndroid Build Coastguard Worker         } else {
919*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
920*bb4ee6a4SAndroid Build Coastguard Worker         }
921*bb4ee6a4SAndroid Build Coastguard Worker     }
922*bb4ee6a4SAndroid Build Coastguard Worker 
923*bb4ee6a4SAndroid Build Coastguard Worker     /// Enable the specified capability.
924*bb4ee6a4SAndroid Build Coastguard Worker     /// See documentation for KVM_ENABLE_CAP.
925*bb4ee6a4SAndroid Build Coastguard Worker     /// # Safety
926*bb4ee6a4SAndroid Build Coastguard Worker     /// This function is marked as unsafe because `cap` may contain values which are interpreted as
927*bb4ee6a4SAndroid Build Coastguard Worker     /// pointers by the kernel.
kvm_enable_cap(&self, cap: &kvm_enable_cap) -> Result<()>928*bb4ee6a4SAndroid Build Coastguard Worker     pub unsafe fn kvm_enable_cap(&self, cap: &kvm_enable_cap) -> Result<()> {
929*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we allocated the struct and we know the kernel will read exactly the size of
930*bb4ee6a4SAndroid Build Coastguard Worker         // the struct.
931*bb4ee6a4SAndroid Build Coastguard Worker         let ret = ioctl_with_ref(self, KVM_ENABLE_CAP, cap);
932*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
933*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
934*bb4ee6a4SAndroid Build Coastguard Worker         } else {
935*bb4ee6a4SAndroid Build Coastguard Worker             Ok(())
936*bb4ee6a4SAndroid Build Coastguard Worker         }
937*bb4ee6a4SAndroid Build Coastguard Worker     }
938*bb4ee6a4SAndroid Build Coastguard Worker }
939*bb4ee6a4SAndroid Build Coastguard Worker 
940*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Vm {
as_raw_descriptor(&self) -> RawDescriptor941*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
942*bb4ee6a4SAndroid Build Coastguard Worker         self.vm.as_raw_descriptor()
943*bb4ee6a4SAndroid Build Coastguard Worker     }
944*bb4ee6a4SAndroid Build Coastguard Worker }
945*bb4ee6a4SAndroid Build Coastguard Worker 
946*bb4ee6a4SAndroid Build Coastguard Worker /// A reason why a VCPU exited. One of these returns every time `Vcpu::run` is called.
947*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug)]
948*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuExit {
949*bb4ee6a4SAndroid Build Coastguard Worker     /// An out port instruction was run on the given port with the given data.
950*bb4ee6a4SAndroid Build Coastguard Worker     IoOut {
951*bb4ee6a4SAndroid Build Coastguard Worker         port: u16,
952*bb4ee6a4SAndroid Build Coastguard Worker         size: usize,
953*bb4ee6a4SAndroid Build Coastguard Worker         data: [u8; 8],
954*bb4ee6a4SAndroid Build Coastguard Worker     },
955*bb4ee6a4SAndroid Build Coastguard Worker     /// An in port instruction was run on the given port.
956*bb4ee6a4SAndroid Build Coastguard Worker     ///
957*bb4ee6a4SAndroid Build Coastguard Worker     /// The date that the instruction receives should be set with `set_data` before `Vcpu::run` is
958*bb4ee6a4SAndroid Build Coastguard Worker     /// called again.
959*bb4ee6a4SAndroid Build Coastguard Worker     IoIn {
960*bb4ee6a4SAndroid Build Coastguard Worker         port: u16,
961*bb4ee6a4SAndroid Build Coastguard Worker         size: usize,
962*bb4ee6a4SAndroid Build Coastguard Worker     },
963*bb4ee6a4SAndroid Build Coastguard Worker     /// A read instruction was run against the given MMIO address.
964*bb4ee6a4SAndroid Build Coastguard Worker     ///
965*bb4ee6a4SAndroid Build Coastguard Worker     /// The date that the instruction receives should be set with `set_data` before `Vcpu::run` is
966*bb4ee6a4SAndroid Build Coastguard Worker     /// called again.
967*bb4ee6a4SAndroid Build Coastguard Worker     MmioRead {
968*bb4ee6a4SAndroid Build Coastguard Worker         address: u64,
969*bb4ee6a4SAndroid Build Coastguard Worker         size: usize,
970*bb4ee6a4SAndroid Build Coastguard Worker     },
971*bb4ee6a4SAndroid Build Coastguard Worker     /// A write instruction was run against the given MMIO address with the given data.
972*bb4ee6a4SAndroid Build Coastguard Worker     MmioWrite {
973*bb4ee6a4SAndroid Build Coastguard Worker         address: u64,
974*bb4ee6a4SAndroid Build Coastguard Worker         size: usize,
975*bb4ee6a4SAndroid Build Coastguard Worker         data: [u8; 8],
976*bb4ee6a4SAndroid Build Coastguard Worker     },
977*bb4ee6a4SAndroid Build Coastguard Worker     IoapicEoi {
978*bb4ee6a4SAndroid Build Coastguard Worker         vector: u8,
979*bb4ee6a4SAndroid Build Coastguard Worker     },
980*bb4ee6a4SAndroid Build Coastguard Worker     HypervSynic {
981*bb4ee6a4SAndroid Build Coastguard Worker         msr: u32,
982*bb4ee6a4SAndroid Build Coastguard Worker         control: u64,
983*bb4ee6a4SAndroid Build Coastguard Worker         evt_page: u64,
984*bb4ee6a4SAndroid Build Coastguard Worker         msg_page: u64,
985*bb4ee6a4SAndroid Build Coastguard Worker     },
986*bb4ee6a4SAndroid Build Coastguard Worker     HypervHcall {
987*bb4ee6a4SAndroid Build Coastguard Worker         input: u64,
988*bb4ee6a4SAndroid Build Coastguard Worker         params: [u64; 2],
989*bb4ee6a4SAndroid Build Coastguard Worker     },
990*bb4ee6a4SAndroid Build Coastguard Worker     Unknown,
991*bb4ee6a4SAndroid Build Coastguard Worker     Exception,
992*bb4ee6a4SAndroid Build Coastguard Worker     Hypercall,
993*bb4ee6a4SAndroid Build Coastguard Worker     Debug,
994*bb4ee6a4SAndroid Build Coastguard Worker     Hlt,
995*bb4ee6a4SAndroid Build Coastguard Worker     IrqWindowOpen,
996*bb4ee6a4SAndroid Build Coastguard Worker     Shutdown,
997*bb4ee6a4SAndroid Build Coastguard Worker     FailEntry {
998*bb4ee6a4SAndroid Build Coastguard Worker         hardware_entry_failure_reason: u64,
999*bb4ee6a4SAndroid Build Coastguard Worker     },
1000*bb4ee6a4SAndroid Build Coastguard Worker     Intr,
1001*bb4ee6a4SAndroid Build Coastguard Worker     SetTpr,
1002*bb4ee6a4SAndroid Build Coastguard Worker     TprAccess,
1003*bb4ee6a4SAndroid Build Coastguard Worker     S390Sieic,
1004*bb4ee6a4SAndroid Build Coastguard Worker     S390Reset,
1005*bb4ee6a4SAndroid Build Coastguard Worker     Dcr,
1006*bb4ee6a4SAndroid Build Coastguard Worker     Nmi,
1007*bb4ee6a4SAndroid Build Coastguard Worker     InternalError,
1008*bb4ee6a4SAndroid Build Coastguard Worker     Osi,
1009*bb4ee6a4SAndroid Build Coastguard Worker     PaprHcall,
1010*bb4ee6a4SAndroid Build Coastguard Worker     S390Ucontrol,
1011*bb4ee6a4SAndroid Build Coastguard Worker     Watchdog,
1012*bb4ee6a4SAndroid Build Coastguard Worker     S390Tsch,
1013*bb4ee6a4SAndroid Build Coastguard Worker     Epr,
1014*bb4ee6a4SAndroid Build Coastguard Worker     /// The cpu triggered a system level event which is specified by the type field.
1015*bb4ee6a4SAndroid Build Coastguard Worker     /// The first field is the event type and the second field is flags.
1016*bb4ee6a4SAndroid Build Coastguard Worker     /// The possible event types are shutdown, reset, or crash.  So far there
1017*bb4ee6a4SAndroid Build Coastguard Worker     /// are not any flags defined.
1018*bb4ee6a4SAndroid Build Coastguard Worker     SystemEvent(u32 /* event_type */, u64 /* flags */),
1019*bb4ee6a4SAndroid Build Coastguard Worker }
1020*bb4ee6a4SAndroid Build Coastguard Worker 
1021*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around creating and using a VCPU.
1022*bb4ee6a4SAndroid Build Coastguard Worker /// `Vcpu` provides all functionality except for running. To run, `to_runnable` must be called to
1023*bb4ee6a4SAndroid Build Coastguard Worker /// lock the vcpu to a thread. Then the returned `RunnableVcpu` can be used for running.
1024*bb4ee6a4SAndroid Build Coastguard Worker pub struct Vcpu {
1025*bb4ee6a4SAndroid Build Coastguard Worker     vcpu: File,
1026*bb4ee6a4SAndroid Build Coastguard Worker     run_mmap: MemoryMapping,
1027*bb4ee6a4SAndroid Build Coastguard Worker }
1028*bb4ee6a4SAndroid Build Coastguard Worker 
1029*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuThread {
1030*bb4ee6a4SAndroid Build Coastguard Worker     run: *mut kvm_run,
1031*bb4ee6a4SAndroid Build Coastguard Worker     signal_num: Option<c_int>,
1032*bb4ee6a4SAndroid Build Coastguard Worker }
1033*bb4ee6a4SAndroid Build Coastguard Worker 
1034*bb4ee6a4SAndroid Build Coastguard Worker thread_local!(static VCPU_THREAD: RefCell<Option<VcpuThread>> = const { RefCell::new(None) });
1035*bb4ee6a4SAndroid Build Coastguard Worker 
1036*bb4ee6a4SAndroid Build Coastguard Worker impl Vcpu {
1037*bb4ee6a4SAndroid Build Coastguard Worker     /// Constructs a new VCPU for `vm`.
1038*bb4ee6a4SAndroid Build Coastguard Worker     ///
1039*bb4ee6a4SAndroid Build Coastguard Worker     /// The `id` argument is the CPU number between [0, max vcpus).
new(id: c_ulong, kvm: &Kvm, vm: &Vm) -> Result<Vcpu>1040*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(id: c_ulong, kvm: &Kvm, vm: &Vm) -> Result<Vcpu> {
1041*bb4ee6a4SAndroid Build Coastguard Worker         let run_mmap_size = kvm.get_vcpu_mmap_size()?;
1042*bb4ee6a4SAndroid Build Coastguard Worker 
1043*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1044*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that vm a VM fd and we verify the return result.
1045*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu_fd = unsafe { ioctl_with_val(vm, KVM_CREATE_VCPU, id) };
1046*bb4ee6a4SAndroid Build Coastguard Worker         if vcpu_fd < 0 {
1047*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1048*bb4ee6a4SAndroid Build Coastguard Worker         }
1049*bb4ee6a4SAndroid Build Coastguard Worker 
1050*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1051*bb4ee6a4SAndroid Build Coastguard Worker         // Wrap the vcpu now in case the following ? returns early. This is safe because we verified
1052*bb4ee6a4SAndroid Build Coastguard Worker         // the value of the fd and we own the fd.
1053*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = unsafe { File::from_raw_descriptor(vcpu_fd) };
1054*bb4ee6a4SAndroid Build Coastguard Worker 
1055*bb4ee6a4SAndroid Build Coastguard Worker         let run_mmap = MemoryMappingBuilder::new(run_mmap_size)
1056*bb4ee6a4SAndroid Build Coastguard Worker             .from_file(&vcpu)
1057*bb4ee6a4SAndroid Build Coastguard Worker             .build()
1058*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(|_| Error::new(ENOSPC))?;
1059*bb4ee6a4SAndroid Build Coastguard Worker 
1060*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Vcpu { vcpu, run_mmap })
1061*bb4ee6a4SAndroid Build Coastguard Worker     }
1062*bb4ee6a4SAndroid Build Coastguard Worker 
1063*bb4ee6a4SAndroid Build Coastguard Worker     /// Consumes `self` and returns a `RunnableVcpu`. A `RunnableVcpu` is required to run the
1064*bb4ee6a4SAndroid Build Coastguard Worker     /// guest.
1065*bb4ee6a4SAndroid Build Coastguard Worker     /// Assigns a vcpu to the current thread and stores it in a hash map that can be used by signal
1066*bb4ee6a4SAndroid Build Coastguard Worker     /// handlers to call set_local_immediate_exit(). An optional signal number will be temporarily
1067*bb4ee6a4SAndroid Build Coastguard Worker     /// blocked while assigning the vcpu to the thread and later blocked when `RunnableVcpu` is
1068*bb4ee6a4SAndroid Build Coastguard Worker     /// destroyed.
1069*bb4ee6a4SAndroid Build Coastguard Worker     ///
1070*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns an error, `EBUSY`, if the current thread already contains a Vcpu.
1071*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
to_runnable(self, signal_num: Option<c_int>) -> Result<RunnableVcpu>1072*bb4ee6a4SAndroid Build Coastguard Worker     pub fn to_runnable(self, signal_num: Option<c_int>) -> Result<RunnableVcpu> {
1073*bb4ee6a4SAndroid Build Coastguard Worker         // Block signal while we add -- if a signal fires (very unlikely,
1074*bb4ee6a4SAndroid Build Coastguard Worker         // as this means something is trying to pause the vcpu before it has
1075*bb4ee6a4SAndroid Build Coastguard Worker         // even started) it'll try to grab the read lock while this write
1076*bb4ee6a4SAndroid Build Coastguard Worker         // lock is grabbed and cause a deadlock.
1077*bb4ee6a4SAndroid Build Coastguard Worker         // Assuming that a failure to block means it's already blocked.
1078*bb4ee6a4SAndroid Build Coastguard Worker         let _blocked_signal = signal_num.map(BlockedSignal::new);
1079*bb4ee6a4SAndroid Build Coastguard Worker 
1080*bb4ee6a4SAndroid Build Coastguard Worker         VCPU_THREAD.with(|v| {
1081*bb4ee6a4SAndroid Build Coastguard Worker             if v.borrow().is_none() {
1082*bb4ee6a4SAndroid Build Coastguard Worker                 *v.borrow_mut() = Some(VcpuThread {
1083*bb4ee6a4SAndroid Build Coastguard Worker                     run: self.run_mmap.as_ptr() as *mut kvm_run,
1084*bb4ee6a4SAndroid Build Coastguard Worker                     signal_num,
1085*bb4ee6a4SAndroid Build Coastguard Worker                 });
1086*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
1087*bb4ee6a4SAndroid Build Coastguard Worker             } else {
1088*bb4ee6a4SAndroid Build Coastguard Worker                 Err(Error::new(EBUSY))
1089*bb4ee6a4SAndroid Build Coastguard Worker             }
1090*bb4ee6a4SAndroid Build Coastguard Worker         })?;
1091*bb4ee6a4SAndroid Build Coastguard Worker 
1092*bb4ee6a4SAndroid Build Coastguard Worker         Ok(RunnableVcpu {
1093*bb4ee6a4SAndroid Build Coastguard Worker             vcpu: self,
1094*bb4ee6a4SAndroid Build Coastguard Worker             phantom: Default::default(),
1095*bb4ee6a4SAndroid Build Coastguard Worker         })
1096*bb4ee6a4SAndroid Build Coastguard Worker     }
1097*bb4ee6a4SAndroid Build Coastguard Worker 
1098*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the data received by a mmio read, ioport in, or hypercall instruction.
1099*bb4ee6a4SAndroid Build Coastguard Worker     ///
1100*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should be called after `Vcpu::run` returns an `VcpuExit::IoIn`,
1101*bb4ee6a4SAndroid Build Coastguard Worker     /// `VcpuExit::MmioRead`, or 'VcpuExit::HypervHcall`.
1102*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
set_data(&self, data: &[u8]) -> Result<()>1103*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_data(&self, data: &[u8]) -> Result<()> {
1104*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1105*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the kvm_run struct because the
1106*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was. The pointer is page aligned so casting to a different
1107*bb4ee6a4SAndroid Build Coastguard Worker         // type is well defined, hence the clippy allow attribute.
1108*bb4ee6a4SAndroid Build Coastguard Worker         let run = unsafe { &mut *(self.run_mmap.as_ptr() as *mut kvm_run) };
1109*bb4ee6a4SAndroid Build Coastguard Worker         match run.exit_reason {
1110*bb4ee6a4SAndroid Build Coastguard Worker             KVM_EXIT_IO => {
1111*bb4ee6a4SAndroid Build Coastguard Worker                 let run_start = run as *mut kvm_run as *mut u8;
1112*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
1113*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because the exit_reason (which comes from the kernel) told us which
1114*bb4ee6a4SAndroid Build Coastguard Worker                 // union field to use.
1115*bb4ee6a4SAndroid Build Coastguard Worker                 let io = unsafe { run.__bindgen_anon_1.io };
1116*bb4ee6a4SAndroid Build Coastguard Worker                 if io.direction as u32 != KVM_EXIT_IO_IN {
1117*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
1118*bb4ee6a4SAndroid Build Coastguard Worker                 }
1119*bb4ee6a4SAndroid Build Coastguard Worker                 let data_size = (io.count as usize) * (io.size as usize);
1120*bb4ee6a4SAndroid Build Coastguard Worker                 if data_size != data.len() {
1121*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
1122*bb4ee6a4SAndroid Build Coastguard Worker                 }
1123*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
1124*bb4ee6a4SAndroid Build Coastguard Worker                 // The data_offset is defined by the kernel to be some number of bytes into the
1125*bb4ee6a4SAndroid Build Coastguard Worker                 // kvm_run structure, which we have fully mmap'd.
1126*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe {
1127*bb4ee6a4SAndroid Build Coastguard Worker                     let data_ptr = run_start.offset(io.data_offset as isize);
1128*bb4ee6a4SAndroid Build Coastguard Worker                     copy_nonoverlapping(data.as_ptr(), data_ptr, data_size);
1129*bb4ee6a4SAndroid Build Coastguard Worker                 }
1130*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
1131*bb4ee6a4SAndroid Build Coastguard Worker             }
1132*bb4ee6a4SAndroid Build Coastguard Worker             KVM_EXIT_MMIO => {
1133*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
1134*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because the exit_reason (which comes from the kernel) told us which
1135*bb4ee6a4SAndroid Build Coastguard Worker                 // union field to use.
1136*bb4ee6a4SAndroid Build Coastguard Worker                 let mmio = unsafe { &mut run.__bindgen_anon_1.mmio };
1137*bb4ee6a4SAndroid Build Coastguard Worker                 if mmio.is_write != 0 {
1138*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
1139*bb4ee6a4SAndroid Build Coastguard Worker                 }
1140*bb4ee6a4SAndroid Build Coastguard Worker                 let len = mmio.len as usize;
1141*bb4ee6a4SAndroid Build Coastguard Worker                 if len != data.len() {
1142*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
1143*bb4ee6a4SAndroid Build Coastguard Worker                 }
1144*bb4ee6a4SAndroid Build Coastguard Worker                 mmio.data[..len].copy_from_slice(data);
1145*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
1146*bb4ee6a4SAndroid Build Coastguard Worker             }
1147*bb4ee6a4SAndroid Build Coastguard Worker             KVM_EXIT_HYPERV => {
1148*bb4ee6a4SAndroid Build Coastguard Worker                 // SAFETY:
1149*bb4ee6a4SAndroid Build Coastguard Worker                 // Safe because the exit_reason (which comes from the kernel) told us which
1150*bb4ee6a4SAndroid Build Coastguard Worker                 // union field to use.
1151*bb4ee6a4SAndroid Build Coastguard Worker                 let hyperv = unsafe { &mut run.__bindgen_anon_1.hyperv };
1152*bb4ee6a4SAndroid Build Coastguard Worker                 if hyperv.type_ != KVM_EXIT_HYPERV_HCALL {
1153*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(Error::new(EINVAL));
1154*bb4ee6a4SAndroid Build Coastguard Worker                 }
1155*bb4ee6a4SAndroid Build Coastguard Worker                 // TODO(b/315998194): Add safety comment
1156*bb4ee6a4SAndroid Build Coastguard Worker                 #[allow(clippy::undocumented_unsafe_blocks)]
1157*bb4ee6a4SAndroid Build Coastguard Worker                 let hcall = unsafe { &mut hyperv.u.hcall };
1158*bb4ee6a4SAndroid Build Coastguard Worker                 match data.try_into() {
1159*bb4ee6a4SAndroid Build Coastguard Worker                     Ok(data) => {
1160*bb4ee6a4SAndroid Build Coastguard Worker                         hcall.result = u64::from_ne_bytes(data);
1161*bb4ee6a4SAndroid Build Coastguard Worker                     }
1162*bb4ee6a4SAndroid Build Coastguard Worker                     _ => return Err(Error::new(EINVAL)),
1163*bb4ee6a4SAndroid Build Coastguard Worker                 }
1164*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(())
1165*bb4ee6a4SAndroid Build Coastguard Worker             }
1166*bb4ee6a4SAndroid Build Coastguard Worker             _ => Err(Error::new(EINVAL)),
1167*bb4ee6a4SAndroid Build Coastguard Worker         }
1168*bb4ee6a4SAndroid Build Coastguard Worker     }
1169*bb4ee6a4SAndroid Build Coastguard Worker 
1170*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the bit that requests an immediate exit.
1171*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
set_immediate_exit(&self, exit: bool)1172*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_immediate_exit(&self, exit: bool) {
1173*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1174*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know we mapped enough memory to hold the kvm_run struct because the
1175*bb4ee6a4SAndroid Build Coastguard Worker         // kernel told us how large it was. The pointer is page aligned so casting to a different
1176*bb4ee6a4SAndroid Build Coastguard Worker         // type is well defined, hence the clippy allow attribute.
1177*bb4ee6a4SAndroid Build Coastguard Worker         let run = unsafe { &mut *(self.run_mmap.as_ptr() as *mut kvm_run) };
1178*bb4ee6a4SAndroid Build Coastguard Worker         run.immediate_exit = exit.into();
1179*bb4ee6a4SAndroid Build Coastguard Worker     }
1180*bb4ee6a4SAndroid Build Coastguard Worker 
1181*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets/clears the bit for immediate exit for the vcpu on the current thread.
set_local_immediate_exit(exit: bool)1182*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_local_immediate_exit(exit: bool) {
1183*bb4ee6a4SAndroid Build Coastguard Worker         VCPU_THREAD.with(|v| {
1184*bb4ee6a4SAndroid Build Coastguard Worker             if let Some(state) = &(*v.borrow()) {
1185*bb4ee6a4SAndroid Build Coastguard Worker                 // TODO(b/315998194): Add safety comment
1186*bb4ee6a4SAndroid Build Coastguard Worker                 #[allow(clippy::undocumented_unsafe_blocks)]
1187*bb4ee6a4SAndroid Build Coastguard Worker                 unsafe {
1188*bb4ee6a4SAndroid Build Coastguard Worker                     (*state.run).immediate_exit = exit.into();
1189*bb4ee6a4SAndroid Build Coastguard Worker                 };
1190*bb4ee6a4SAndroid Build Coastguard Worker             }
1191*bb4ee6a4SAndroid Build Coastguard Worker         });
1192*bb4ee6a4SAndroid Build Coastguard Worker     }
1193*bb4ee6a4SAndroid Build Coastguard Worker 
1194*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU registers.
1195*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
get_regs(&self) -> Result<kvm_regs>1196*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_regs(&self) -> Result<kvm_regs> {
1197*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1198*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = unsafe { std::mem::zeroed() };
1199*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1200*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only read the
1201*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
1202*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_REGS, &mut regs) };
1203*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1204*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1205*bb4ee6a4SAndroid Build Coastguard Worker         }
1206*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regs)
1207*bb4ee6a4SAndroid Build Coastguard Worker     }
1208*bb4ee6a4SAndroid Build Coastguard Worker 
1209*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU registers.
1210*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
set_regs(&self, regs: &kvm_regs) -> Result<()>1211*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_regs(&self, regs: &kvm_regs) -> Result<()> {
1212*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1213*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only read the
1214*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
1215*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_REGS, regs) };
1216*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1217*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1218*bb4ee6a4SAndroid Build Coastguard Worker         }
1219*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1220*bb4ee6a4SAndroid Build Coastguard Worker     }
1221*bb4ee6a4SAndroid Build Coastguard Worker 
1222*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU special registers.
1223*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_sregs(&self) -> Result<kvm_sregs>1224*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_sregs(&self) -> Result<kvm_sregs> {
1225*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1226*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = unsafe { std::mem::zeroed() };
1227*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1228*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1229*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
1230*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_SREGS, &mut regs) };
1231*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1232*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1233*bb4ee6a4SAndroid Build Coastguard Worker         }
1234*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regs)
1235*bb4ee6a4SAndroid Build Coastguard Worker     }
1236*bb4ee6a4SAndroid Build Coastguard Worker 
1237*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU special registers.
1238*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_sregs(&self, sregs: &kvm_sregs) -> Result<()>1239*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_sregs(&self, sregs: &kvm_sregs) -> Result<()> {
1240*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1241*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only read the
1242*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory from our pointer, and we verify the return result.
1243*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_SREGS, sregs) };
1244*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1245*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1246*bb4ee6a4SAndroid Build Coastguard Worker         }
1247*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1248*bb4ee6a4SAndroid Build Coastguard Worker     }
1249*bb4ee6a4SAndroid Build Coastguard Worker 
1250*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU FPU registers.
1251*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_fpu(&self) -> Result<kvm_fpu>1252*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_fpu(&self) -> Result<kvm_fpu> {
1253*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1254*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
1255*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = unsafe { std::mem::zeroed() };
1256*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1257*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1258*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_FPU, &mut regs) };
1259*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1260*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1261*bb4ee6a4SAndroid Build Coastguard Worker         }
1262*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regs)
1263*bb4ee6a4SAndroid Build Coastguard Worker     }
1264*bb4ee6a4SAndroid Build Coastguard Worker 
1265*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to setup the FPU
1266*bb4ee6a4SAndroid Build Coastguard Worker     ///
1267*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_FPU.
1268*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_fpu(&self, fpu: &kvm_fpu) -> Result<()>1269*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_fpu(&self, fpu: &kvm_fpu) -> Result<()> {
1270*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1271*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1272*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read past the end of the kvm_fpu struct.
1273*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_FPU, fpu) }
1274*bb4ee6a4SAndroid Build Coastguard Worker         };
1275*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1276*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1277*bb4ee6a4SAndroid Build Coastguard Worker         }
1278*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1279*bb4ee6a4SAndroid Build Coastguard Worker     }
1280*bb4ee6a4SAndroid Build Coastguard Worker 
1281*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU debug registers.
1282*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_debugregs(&self) -> Result<kvm_debugregs>1283*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_debugregs(&self) -> Result<kvm_debugregs> {
1284*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1285*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = unsafe { std::mem::zeroed() };
1286*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1287*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1288*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
1289*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_DEBUGREGS, &mut regs) };
1290*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1291*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1292*bb4ee6a4SAndroid Build Coastguard Worker         }
1293*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regs)
1294*bb4ee6a4SAndroid Build Coastguard Worker     }
1295*bb4ee6a4SAndroid Build Coastguard Worker 
1296*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU debug registers
1297*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_debugregs(&self, dregs: &kvm_debugregs) -> Result<()>1298*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_debugregs(&self, dregs: &kvm_debugregs) -> Result<()> {
1299*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1300*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1301*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read past the end of the kvm_fpu struct.
1302*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_DEBUGREGS, dregs) }
1303*bb4ee6a4SAndroid Build Coastguard Worker         };
1304*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1305*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1306*bb4ee6a4SAndroid Build Coastguard Worker         }
1307*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1308*bb4ee6a4SAndroid Build Coastguard Worker     }
1309*bb4ee6a4SAndroid Build Coastguard Worker 
1310*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU extended control registers
1311*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_xcrs(&self) -> Result<kvm_xcrs>1312*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_xcrs(&self) -> Result<kvm_xcrs> {
1313*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1314*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = unsafe { std::mem::zeroed() };
1315*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1316*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1317*bb4ee6a4SAndroid Build Coastguard Worker         // correct amount of memory to our pointer, and we verify the return result.
1318*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_XCRS, &mut regs) };
1319*bb4ee6a4SAndroid Build Coastguard Worker         if ret != 0 {
1320*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1321*bb4ee6a4SAndroid Build Coastguard Worker         }
1322*bb4ee6a4SAndroid Build Coastguard Worker         Ok(regs)
1323*bb4ee6a4SAndroid Build Coastguard Worker     }
1324*bb4ee6a4SAndroid Build Coastguard Worker 
1325*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU extended control registers
1326*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_xcrs(&self, xcrs: &kvm_xcrs) -> Result<()>1327*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_xcrs(&self, xcrs: &kvm_xcrs) -> Result<()> {
1328*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1329*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1330*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read past the end of the kvm_xcrs struct.
1331*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_XCRS, xcrs) }
1332*bb4ee6a4SAndroid Build Coastguard Worker         };
1333*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1334*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1335*bb4ee6a4SAndroid Build Coastguard Worker         }
1336*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1337*bb4ee6a4SAndroid Build Coastguard Worker     }
1338*bb4ee6a4SAndroid Build Coastguard Worker 
1339*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get the MSRS
1340*bb4ee6a4SAndroid Build Coastguard Worker     ///
1341*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_MSRS.
1342*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_msrs(&self, msr_entries: &mut Vec<kvm_msr_entry>) -> Result<()>1343*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_msrs(&self, msr_entries: &mut Vec<kvm_msr_entry>) -> Result<()> {
1344*bb4ee6a4SAndroid Build Coastguard Worker         let mut msrs = vec_with_array_field::<kvm_msrs, kvm_msr_entry>(msr_entries.len());
1345*bb4ee6a4SAndroid Build Coastguard Worker         {
1346*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1347*bb4ee6a4SAndroid Build Coastguard Worker             // Mapping the unsized array to a slice is unsafe because the length isn't known.
1348*bb4ee6a4SAndroid Build Coastguard Worker             // Providing the length used to create the struct guarantees the entire slice is valid.
1349*bb4ee6a4SAndroid Build Coastguard Worker             unsafe {
1350*bb4ee6a4SAndroid Build Coastguard Worker                 let entries: &mut [kvm_msr_entry] = msrs[0].entries.as_mut_slice(msr_entries.len());
1351*bb4ee6a4SAndroid Build Coastguard Worker                 entries.copy_from_slice(msr_entries);
1352*bb4ee6a4SAndroid Build Coastguard Worker             }
1353*bb4ee6a4SAndroid Build Coastguard Worker         }
1354*bb4ee6a4SAndroid Build Coastguard Worker         msrs[0].nmsrs = msr_entries.len() as u32;
1355*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1356*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1357*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read or write past the end of the kvm_msrs struct.
1358*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_mut_ref(self, KVM_GET_MSRS, &mut msrs[0]) }
1359*bb4ee6a4SAndroid Build Coastguard Worker         };
1360*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1361*bb4ee6a4SAndroid Build Coastguard Worker             // KVM_SET_MSRS actually returns the number of msr entries written.
1362*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1363*bb4ee6a4SAndroid Build Coastguard Worker         }
1364*bb4ee6a4SAndroid Build Coastguard Worker         // TODO(b/315998194): Add safety comment
1365*bb4ee6a4SAndroid Build Coastguard Worker         #[allow(clippy::undocumented_unsafe_blocks)]
1366*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
1367*bb4ee6a4SAndroid Build Coastguard Worker             let count = ret as usize;
1368*bb4ee6a4SAndroid Build Coastguard Worker             assert!(count <= msr_entries.len());
1369*bb4ee6a4SAndroid Build Coastguard Worker             let entries: &mut [kvm_msr_entry] = msrs[0].entries.as_mut_slice(count);
1370*bb4ee6a4SAndroid Build Coastguard Worker             msr_entries.truncate(count);
1371*bb4ee6a4SAndroid Build Coastguard Worker             msr_entries.copy_from_slice(entries);
1372*bb4ee6a4SAndroid Build Coastguard Worker         }
1373*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1374*bb4ee6a4SAndroid Build Coastguard Worker     }
1375*bb4ee6a4SAndroid Build Coastguard Worker 
1376*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to setup the MSRS
1377*bb4ee6a4SAndroid Build Coastguard Worker     ///
1378*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_MSRS.
1379*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_msrs(&self, msrs: &kvm_msrs) -> Result<()>1380*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_msrs(&self, msrs: &kvm_msrs) -> Result<()> {
1381*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1382*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1383*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read past the end of the kvm_msrs struct.
1384*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_MSRS, msrs) }
1385*bb4ee6a4SAndroid Build Coastguard Worker         };
1386*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1387*bb4ee6a4SAndroid Build Coastguard Worker             // KVM_SET_MSRS actually returns the number of msr entries written.
1388*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1389*bb4ee6a4SAndroid Build Coastguard Worker         }
1390*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1391*bb4ee6a4SAndroid Build Coastguard Worker     }
1392*bb4ee6a4SAndroid Build Coastguard Worker 
1393*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to setup the CPUID registers
1394*bb4ee6a4SAndroid Build Coastguard Worker     ///
1395*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_CPUID2.
1396*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_cpuid2(&self, cpuid: &CpuId) -> Result<()>1397*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()> {
1398*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1399*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1400*bb4ee6a4SAndroid Build Coastguard Worker             // Here we trust the kernel not to read past the end of the kvm_msrs struct.
1401*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ptr(self, KVM_SET_CPUID2, cpuid.as_ptr()) }
1402*bb4ee6a4SAndroid Build Coastguard Worker         };
1403*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1404*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1405*bb4ee6a4SAndroid Build Coastguard Worker         }
1406*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1407*bb4ee6a4SAndroid Build Coastguard Worker     }
1408*bb4ee6a4SAndroid Build Coastguard Worker 
1409*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get the system emulated hyper-v CPUID values
1410*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_hyperv_cpuid(&self) -> Result<CpuId>1411*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_hyperv_cpuid(&self) -> Result<CpuId> {
1412*bb4ee6a4SAndroid Build Coastguard Worker         const MAX_KVM_CPUID_ENTRIES: usize = 256;
1413*bb4ee6a4SAndroid Build Coastguard Worker         let mut cpuid = CpuId::new(MAX_KVM_CPUID_ENTRIES);
1414*bb4ee6a4SAndroid Build Coastguard Worker 
1415*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1416*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1417*bb4ee6a4SAndroid Build Coastguard Worker             // ioctl is unsafe. The kernel is trusted not to write beyond the bounds of the memory
1418*bb4ee6a4SAndroid Build Coastguard Worker             // allocated for the struct. The limit is read from nent, which is set to the allocated
1419*bb4ee6a4SAndroid Build Coastguard Worker             // size(MAX_KVM_CPUID_ENTRIES) above.
1420*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_mut_ptr(self, KVM_GET_SUPPORTED_HV_CPUID, cpuid.as_mut_ptr()) }
1421*bb4ee6a4SAndroid Build Coastguard Worker         };
1422*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1423*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1424*bb4ee6a4SAndroid Build Coastguard Worker         }
1425*bb4ee6a4SAndroid Build Coastguard Worker         Ok(cpuid)
1426*bb4ee6a4SAndroid Build Coastguard Worker     }
1427*bb4ee6a4SAndroid Build Coastguard Worker 
1428*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to get the state of the "Local Advanced Programmable Interrupt
1429*bb4ee6a4SAndroid Build Coastguard Worker     /// Controller".
1430*bb4ee6a4SAndroid Build Coastguard Worker     ///
1431*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_GET_LAPIC.
1432*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_lapic(&self) -> Result<kvm_lapic_state>1433*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_lapic(&self) -> Result<kvm_lapic_state> {
1434*bb4ee6a4SAndroid Build Coastguard Worker         let mut klapic: kvm_lapic_state = Default::default();
1435*bb4ee6a4SAndroid Build Coastguard Worker 
1436*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1437*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1438*bb4ee6a4SAndroid Build Coastguard Worker             // The ioctl is unsafe unless you trust the kernel not to write past the end of the
1439*bb4ee6a4SAndroid Build Coastguard Worker             // local_apic struct.
1440*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_mut_ref(self, KVM_GET_LAPIC, &mut klapic) }
1441*bb4ee6a4SAndroid Build Coastguard Worker         };
1442*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1443*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1444*bb4ee6a4SAndroid Build Coastguard Worker         }
1445*bb4ee6a4SAndroid Build Coastguard Worker         Ok(klapic)
1446*bb4ee6a4SAndroid Build Coastguard Worker     }
1447*bb4ee6a4SAndroid Build Coastguard Worker 
1448*bb4ee6a4SAndroid Build Coastguard Worker     /// X86 specific call to set the state of the "Local Advanced Programmable Interrupt
1449*bb4ee6a4SAndroid Build Coastguard Worker     /// Controller".
1450*bb4ee6a4SAndroid Build Coastguard Worker     ///
1451*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_LAPIC.
1452*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_lapic(&self, klapic: &kvm_lapic_state) -> Result<()>1453*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_lapic(&self, klapic: &kvm_lapic_state) -> Result<()> {
1454*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1455*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1456*bb4ee6a4SAndroid Build Coastguard Worker             // The ioctl is safe because the kernel will only read from the klapic struct.
1457*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_LAPIC, klapic) }
1458*bb4ee6a4SAndroid Build Coastguard Worker         };
1459*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1460*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1461*bb4ee6a4SAndroid Build Coastguard Worker         }
1462*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1463*bb4ee6a4SAndroid Build Coastguard Worker     }
1464*bb4ee6a4SAndroid Build Coastguard Worker 
1465*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the vcpu's current "multiprocessing state".
1466*bb4ee6a4SAndroid Build Coastguard Worker     ///
1467*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_GET_MP_STATE. This call can only succeed after
1468*bb4ee6a4SAndroid Build Coastguard Worker     /// a call to `Vm::create_irq_chip`.
1469*bb4ee6a4SAndroid Build Coastguard Worker     ///
1470*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that KVM defines the call for both x86 and s390 but we do not expect anyone
1471*bb4ee6a4SAndroid Build Coastguard Worker     /// to run crosvm on s390.
1472*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_mp_state(&self) -> Result<kvm_mp_state>1473*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_mp_state(&self) -> Result<kvm_mp_state> {
1474*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1475*bb4ee6a4SAndroid Build Coastguard Worker         let mut state: kvm_mp_state = unsafe { std::mem::zeroed() };
1476*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1477*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel will only
1478*bb4ee6a4SAndroid Build Coastguard Worker         // write correct amount of memory to our pointer, and we verify the return result.
1479*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_MP_STATE, &mut state) };
1480*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1481*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1482*bb4ee6a4SAndroid Build Coastguard Worker         }
1483*bb4ee6a4SAndroid Build Coastguard Worker         Ok(state)
1484*bb4ee6a4SAndroid Build Coastguard Worker     }
1485*bb4ee6a4SAndroid Build Coastguard Worker 
1486*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the vcpu's current "multiprocessing state".
1487*bb4ee6a4SAndroid Build Coastguard Worker     ///
1488*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_MP_STATE. This call can only succeed after
1489*bb4ee6a4SAndroid Build Coastguard Worker     /// a call to `Vm::create_irq_chip`.
1490*bb4ee6a4SAndroid Build Coastguard Worker     ///
1491*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that KVM defines the call for both x86 and s390 but we do not expect anyone
1492*bb4ee6a4SAndroid Build Coastguard Worker     /// to run crosvm on s390.
1493*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_mp_state(&self, state: &kvm_mp_state) -> Result<()>1494*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_mp_state(&self, state: &kvm_mp_state) -> Result<()> {
1495*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1496*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1497*bb4ee6a4SAndroid Build Coastguard Worker             // The ioctl is safe because the kernel will only read from the kvm_mp_state struct.
1498*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_MP_STATE, state) }
1499*bb4ee6a4SAndroid Build Coastguard Worker         };
1500*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1501*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1502*bb4ee6a4SAndroid Build Coastguard Worker         }
1503*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1504*bb4ee6a4SAndroid Build Coastguard Worker     }
1505*bb4ee6a4SAndroid Build Coastguard Worker 
1506*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the vcpu's currently pending exceptions, interrupts, NMIs, etc
1507*bb4ee6a4SAndroid Build Coastguard Worker     ///
1508*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_GET_VCPU_EVENTS.
1509*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
get_vcpu_events(&self) -> Result<kvm_vcpu_events>1510*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_vcpu_events(&self) -> Result<kvm_vcpu_events> {
1511*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
1512*bb4ee6a4SAndroid Build Coastguard Worker         let mut events: kvm_vcpu_events = unsafe { std::mem::zeroed() };
1513*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1514*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd, we know the kernel
1515*bb4ee6a4SAndroid Build Coastguard Worker         // will only write correct amount of memory to our pointer, and we
1516*bb4ee6a4SAndroid Build Coastguard Worker         // verify the return result.
1517*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_VCPU_EVENTS, &mut events) };
1518*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1519*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1520*bb4ee6a4SAndroid Build Coastguard Worker         }
1521*bb4ee6a4SAndroid Build Coastguard Worker         Ok(events)
1522*bb4ee6a4SAndroid Build Coastguard Worker     }
1523*bb4ee6a4SAndroid Build Coastguard Worker 
1524*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the vcpu's currently pending exceptions, interrupts, NMIs, etc
1525*bb4ee6a4SAndroid Build Coastguard Worker     ///
1526*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_VCPU_EVENTS.
1527*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_arch = "x86_64")]
set_vcpu_events(&self, events: &kvm_vcpu_events) -> Result<()>1528*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_vcpu_events(&self, events: &kvm_vcpu_events) -> Result<()> {
1529*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1530*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1531*bb4ee6a4SAndroid Build Coastguard Worker             // The ioctl is safe because the kernel will only read from the
1532*bb4ee6a4SAndroid Build Coastguard Worker             // kvm_vcpu_events.
1533*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_VCPU_EVENTS, events) }
1534*bb4ee6a4SAndroid Build Coastguard Worker         };
1535*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1536*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1537*bb4ee6a4SAndroid Build Coastguard Worker         }
1538*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1539*bb4ee6a4SAndroid Build Coastguard Worker     }
1540*bb4ee6a4SAndroid Build Coastguard Worker 
1541*bb4ee6a4SAndroid Build Coastguard Worker     /// Enable the specified capability.
1542*bb4ee6a4SAndroid Build Coastguard Worker     /// See documentation for KVM_ENABLE_CAP.
1543*bb4ee6a4SAndroid Build Coastguard Worker     /// # Safety
1544*bb4ee6a4SAndroid Build Coastguard Worker     /// This function is marked as unsafe because `cap` may contain values which are interpreted as
1545*bb4ee6a4SAndroid Build Coastguard Worker     /// pointers by the kernel.
kvm_enable_cap(&self, cap: &kvm_enable_cap) -> Result<()>1546*bb4ee6a4SAndroid Build Coastguard Worker     pub unsafe fn kvm_enable_cap(&self, cap: &kvm_enable_cap) -> Result<()> {
1547*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1548*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we allocated the struct and we know the kernel will read exactly the size of
1549*bb4ee6a4SAndroid Build Coastguard Worker         // the struct.
1550*bb4ee6a4SAndroid Build Coastguard Worker         let ret = ioctl_with_ref(self, KVM_ENABLE_CAP, cap);
1551*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1552*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1553*bb4ee6a4SAndroid Build Coastguard Worker         }
1554*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1555*bb4ee6a4SAndroid Build Coastguard Worker     }
1556*bb4ee6a4SAndroid Build Coastguard Worker 
1557*bb4ee6a4SAndroid Build Coastguard Worker     /// Specifies set of signals that are blocked during execution of KVM_RUN.
1558*bb4ee6a4SAndroid Build Coastguard Worker     /// Signals that are not blocked will cause KVM_RUN to return with -EINTR.
1559*bb4ee6a4SAndroid Build Coastguard Worker     ///
1560*bb4ee6a4SAndroid Build Coastguard Worker     /// See the documentation for KVM_SET_SIGNAL_MASK
set_signal_mask(&self, signals: &[c_int]) -> Result<()>1561*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_signal_mask(&self, signals: &[c_int]) -> Result<()> {
1562*bb4ee6a4SAndroid Build Coastguard Worker         let sigset = signal::create_sigset(signals)?;
1563*bb4ee6a4SAndroid Build Coastguard Worker 
1564*bb4ee6a4SAndroid Build Coastguard Worker         let mut kvm_sigmask = vec_with_array_field::<kvm_signal_mask, sigset_t>(1);
1565*bb4ee6a4SAndroid Build Coastguard Worker         // Rust definition of sigset_t takes 128 bytes, but the kernel only
1566*bb4ee6a4SAndroid Build Coastguard Worker         // expects 8-bytes structure, so we can't write
1567*bb4ee6a4SAndroid Build Coastguard Worker         // kvm_sigmask.len  = size_of::<sigset_t>() as u32;
1568*bb4ee6a4SAndroid Build Coastguard Worker         kvm_sigmask[0].len = 8;
1569*bb4ee6a4SAndroid Build Coastguard Worker         // Ensure the length is not too big.
1570*bb4ee6a4SAndroid Build Coastguard Worker         const _ASSERT: usize = size_of::<sigset_t>() - 8usize;
1571*bb4ee6a4SAndroid Build Coastguard Worker 
1572*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1573*bb4ee6a4SAndroid Build Coastguard Worker         // Safe as we allocated exactly the needed space
1574*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
1575*bb4ee6a4SAndroid Build Coastguard Worker             copy_nonoverlapping(
1576*bb4ee6a4SAndroid Build Coastguard Worker                 &sigset as *const sigset_t as *const u8,
1577*bb4ee6a4SAndroid Build Coastguard Worker                 kvm_sigmask[0].sigset.as_mut_ptr(),
1578*bb4ee6a4SAndroid Build Coastguard Worker                 8,
1579*bb4ee6a4SAndroid Build Coastguard Worker             );
1580*bb4ee6a4SAndroid Build Coastguard Worker         }
1581*bb4ee6a4SAndroid Build Coastguard Worker 
1582*bb4ee6a4SAndroid Build Coastguard Worker         let ret = {
1583*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1584*bb4ee6a4SAndroid Build Coastguard Worker             // The ioctl is safe because the kernel will only read from the
1585*bb4ee6a4SAndroid Build Coastguard Worker             // kvm_signal_mask structure.
1586*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { ioctl_with_ref(self, KVM_SET_SIGNAL_MASK, &kvm_sigmask[0]) }
1587*bb4ee6a4SAndroid Build Coastguard Worker         };
1588*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1589*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1590*bb4ee6a4SAndroid Build Coastguard Worker         }
1591*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1592*bb4ee6a4SAndroid Build Coastguard Worker     }
1593*bb4ee6a4SAndroid Build Coastguard Worker 
1594*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the value of one register on this VCPU.  The id of the register is
1595*bb4ee6a4SAndroid Build Coastguard Worker     /// encoded as specified in the kernel documentation for KVM_SET_ONE_REG.
1596*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
set_one_reg(&self, reg_id: u64, data: u64) -> Result<()>1597*bb4ee6a4SAndroid Build Coastguard Worker     pub fn set_one_reg(&self, reg_id: u64, data: u64) -> Result<()> {
1598*bb4ee6a4SAndroid Build Coastguard Worker         let data_ref = &data as *const u64;
1599*bb4ee6a4SAndroid Build Coastguard Worker         let onereg = kvm_one_reg {
1600*bb4ee6a4SAndroid Build Coastguard Worker             id: reg_id,
1601*bb4ee6a4SAndroid Build Coastguard Worker             addr: data_ref as u64,
1602*bb4ee6a4SAndroid Build Coastguard Worker         };
1603*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1604*bb4ee6a4SAndroid Build Coastguard Worker         // safe because we allocated the struct and we know the kernel will read
1605*bb4ee6a4SAndroid Build Coastguard Worker         // exactly the size of the struct
1606*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl_with_ref(self, KVM_SET_ONE_REG, &onereg) };
1607*bb4ee6a4SAndroid Build Coastguard Worker         if ret < 0 {
1608*bb4ee6a4SAndroid Build Coastguard Worker             return errno_result();
1609*bb4ee6a4SAndroid Build Coastguard Worker         }
1610*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
1611*bb4ee6a4SAndroid Build Coastguard Worker     }
1612*bb4ee6a4SAndroid Build Coastguard Worker }
1613*bb4ee6a4SAndroid Build Coastguard Worker 
1614*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Vcpu {
as_raw_descriptor(&self) -> RawDescriptor1615*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
1616*bb4ee6a4SAndroid Build Coastguard Worker         self.vcpu.as_raw_descriptor()
1617*bb4ee6a4SAndroid Build Coastguard Worker     }
1618*bb4ee6a4SAndroid Build Coastguard Worker }
1619*bb4ee6a4SAndroid Build Coastguard Worker 
1620*bb4ee6a4SAndroid Build Coastguard Worker /// A Vcpu that has a thread and can be run. Created by calling `to_runnable` on a `Vcpu`.
1621*bb4ee6a4SAndroid Build Coastguard Worker /// Implements `Deref` to a `Vcpu` so all `Vcpu` methods are usable, with the addition of the `run`
1622*bb4ee6a4SAndroid Build Coastguard Worker /// function to execute the guest.
1623*bb4ee6a4SAndroid Build Coastguard Worker pub struct RunnableVcpu {
1624*bb4ee6a4SAndroid Build Coastguard Worker     vcpu: Vcpu,
1625*bb4ee6a4SAndroid Build Coastguard Worker     // vcpus must stay on the same thread once they start.
1626*bb4ee6a4SAndroid Build Coastguard Worker     // Add the PhantomData pointer to ensure RunnableVcpu is not `Send`.
1627*bb4ee6a4SAndroid Build Coastguard Worker     phantom: std::marker::PhantomData<*mut u8>,
1628*bb4ee6a4SAndroid Build Coastguard Worker }
1629*bb4ee6a4SAndroid Build Coastguard Worker 
1630*bb4ee6a4SAndroid Build Coastguard Worker impl RunnableVcpu {
1631*bb4ee6a4SAndroid Build Coastguard Worker     /// Runs the VCPU until it exits, returning the reason for the exit.
1632*bb4ee6a4SAndroid Build Coastguard Worker     ///
1633*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that the state of the VCPU and associated VM must be setup first for this to do
1634*bb4ee6a4SAndroid Build Coastguard Worker     /// anything useful.
1635*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::cast_ptr_alignment)]
1636*bb4ee6a4SAndroid Build Coastguard Worker     // The pointer is page aligned so casting to a different type is well defined, hence the clippy
1637*bb4ee6a4SAndroid Build Coastguard Worker     // allow attribute.
run(&self) -> Result<VcpuExit>1638*bb4ee6a4SAndroid Build Coastguard Worker     pub fn run(&self) -> Result<VcpuExit> {
1639*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
1640*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we know that our file is a VCPU fd and we verify the return result.
1641*bb4ee6a4SAndroid Build Coastguard Worker         let ret = unsafe { ioctl(self, KVM_RUN) };
1642*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 {
1643*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
1644*bb4ee6a4SAndroid Build Coastguard Worker             // Safe because we know we mapped enough memory to hold the kvm_run struct because the
1645*bb4ee6a4SAndroid Build Coastguard Worker             // kernel told us how large it was.
1646*bb4ee6a4SAndroid Build Coastguard Worker             let run = unsafe { &*(self.run_mmap.as_ptr() as *const kvm_run) };
1647*bb4ee6a4SAndroid Build Coastguard Worker             match run.exit_reason {
1648*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_IO => {
1649*bb4ee6a4SAndroid Build Coastguard Worker                     // SAFETY:
1650*bb4ee6a4SAndroid Build Coastguard Worker                     // Safe because the exit_reason (which comes from the kernel) told us which
1651*bb4ee6a4SAndroid Build Coastguard Worker                     // union field to use.
1652*bb4ee6a4SAndroid Build Coastguard Worker                     let io = unsafe { run.__bindgen_anon_1.io };
1653*bb4ee6a4SAndroid Build Coastguard Worker                     let port = io.port;
1654*bb4ee6a4SAndroid Build Coastguard Worker                     let size = (io.count as usize) * (io.size as usize);
1655*bb4ee6a4SAndroid Build Coastguard Worker                     match io.direction as u32 {
1656*bb4ee6a4SAndroid Build Coastguard Worker                         KVM_EXIT_IO_IN => Ok(VcpuExit::IoIn { port, size }),
1657*bb4ee6a4SAndroid Build Coastguard Worker                         KVM_EXIT_IO_OUT => {
1658*bb4ee6a4SAndroid Build Coastguard Worker                             let mut data = [0; 8];
1659*bb4ee6a4SAndroid Build Coastguard Worker                             let run_start = run as *const kvm_run as *const u8;
1660*bb4ee6a4SAndroid Build Coastguard Worker                             // SAFETY:
1661*bb4ee6a4SAndroid Build Coastguard Worker                             // The data_offset is defined by the kernel to be some number of bytes
1662*bb4ee6a4SAndroid Build Coastguard Worker                             // into the kvm_run structure, which we have fully mmap'd.
1663*bb4ee6a4SAndroid Build Coastguard Worker                             unsafe {
1664*bb4ee6a4SAndroid Build Coastguard Worker                                 let data_ptr = run_start.offset(io.data_offset as isize);
1665*bb4ee6a4SAndroid Build Coastguard Worker                                 copy_nonoverlapping(
1666*bb4ee6a4SAndroid Build Coastguard Worker                                     data_ptr,
1667*bb4ee6a4SAndroid Build Coastguard Worker                                     data.as_mut_ptr(),
1668*bb4ee6a4SAndroid Build Coastguard Worker                                     min(size, data.len()),
1669*bb4ee6a4SAndroid Build Coastguard Worker                                 );
1670*bb4ee6a4SAndroid Build Coastguard Worker                             }
1671*bb4ee6a4SAndroid Build Coastguard Worker                             Ok(VcpuExit::IoOut { port, size, data })
1672*bb4ee6a4SAndroid Build Coastguard Worker                         }
1673*bb4ee6a4SAndroid Build Coastguard Worker                         _ => Err(Error::new(EINVAL)),
1674*bb4ee6a4SAndroid Build Coastguard Worker                     }
1675*bb4ee6a4SAndroid Build Coastguard Worker                 }
1676*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_MMIO => {
1677*bb4ee6a4SAndroid Build Coastguard Worker                     // SAFETY:
1678*bb4ee6a4SAndroid Build Coastguard Worker                     // Safe because the exit_reason (which comes from the kernel) told us which
1679*bb4ee6a4SAndroid Build Coastguard Worker                     // union field to use.
1680*bb4ee6a4SAndroid Build Coastguard Worker                     let mmio = unsafe { &run.__bindgen_anon_1.mmio };
1681*bb4ee6a4SAndroid Build Coastguard Worker                     let address = mmio.phys_addr;
1682*bb4ee6a4SAndroid Build Coastguard Worker                     let size = min(mmio.len as usize, mmio.data.len());
1683*bb4ee6a4SAndroid Build Coastguard Worker                     if mmio.is_write != 0 {
1684*bb4ee6a4SAndroid Build Coastguard Worker                         Ok(VcpuExit::MmioWrite {
1685*bb4ee6a4SAndroid Build Coastguard Worker                             address,
1686*bb4ee6a4SAndroid Build Coastguard Worker                             size,
1687*bb4ee6a4SAndroid Build Coastguard Worker                             data: mmio.data,
1688*bb4ee6a4SAndroid Build Coastguard Worker                         })
1689*bb4ee6a4SAndroid Build Coastguard Worker                     } else {
1690*bb4ee6a4SAndroid Build Coastguard Worker                         Ok(VcpuExit::MmioRead { address, size })
1691*bb4ee6a4SAndroid Build Coastguard Worker                     }
1692*bb4ee6a4SAndroid Build Coastguard Worker                 }
1693*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_IOAPIC_EOI => {
1694*bb4ee6a4SAndroid Build Coastguard Worker                     // SAFETY:
1695*bb4ee6a4SAndroid Build Coastguard Worker                     // Safe because the exit_reason (which comes from the kernel) told us which
1696*bb4ee6a4SAndroid Build Coastguard Worker                     // union field to use.
1697*bb4ee6a4SAndroid Build Coastguard Worker                     let vector = unsafe { run.__bindgen_anon_1.eoi.vector };
1698*bb4ee6a4SAndroid Build Coastguard Worker                     Ok(VcpuExit::IoapicEoi { vector })
1699*bb4ee6a4SAndroid Build Coastguard Worker                 }
1700*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_HYPERV => {
1701*bb4ee6a4SAndroid Build Coastguard Worker                     // SAFETY:
1702*bb4ee6a4SAndroid Build Coastguard Worker                     // Safe because the exit_reason (which comes from the kernel) told us which
1703*bb4ee6a4SAndroid Build Coastguard Worker                     // union field to use.
1704*bb4ee6a4SAndroid Build Coastguard Worker                     let hyperv = unsafe { &run.__bindgen_anon_1.hyperv };
1705*bb4ee6a4SAndroid Build Coastguard Worker                     match hyperv.type_ {
1706*bb4ee6a4SAndroid Build Coastguard Worker                         KVM_EXIT_HYPERV_SYNIC => {
1707*bb4ee6a4SAndroid Build Coastguard Worker                             // TODO(b/315998194): Add safety comment
1708*bb4ee6a4SAndroid Build Coastguard Worker                             #[allow(clippy::undocumented_unsafe_blocks)]
1709*bb4ee6a4SAndroid Build Coastguard Worker                             let synic = unsafe { &hyperv.u.synic };
1710*bb4ee6a4SAndroid Build Coastguard Worker                             Ok(VcpuExit::HypervSynic {
1711*bb4ee6a4SAndroid Build Coastguard Worker                                 msr: synic.msr,
1712*bb4ee6a4SAndroid Build Coastguard Worker                                 control: synic.control,
1713*bb4ee6a4SAndroid Build Coastguard Worker                                 evt_page: synic.evt_page,
1714*bb4ee6a4SAndroid Build Coastguard Worker                                 msg_page: synic.msg_page,
1715*bb4ee6a4SAndroid Build Coastguard Worker                             })
1716*bb4ee6a4SAndroid Build Coastguard Worker                         }
1717*bb4ee6a4SAndroid Build Coastguard Worker                         KVM_EXIT_HYPERV_HCALL => {
1718*bb4ee6a4SAndroid Build Coastguard Worker                             // TODO(b/315998194): Add safety comment
1719*bb4ee6a4SAndroid Build Coastguard Worker                             #[allow(clippy::undocumented_unsafe_blocks)]
1720*bb4ee6a4SAndroid Build Coastguard Worker                             let hcall = unsafe { &hyperv.u.hcall };
1721*bb4ee6a4SAndroid Build Coastguard Worker                             Ok(VcpuExit::HypervHcall {
1722*bb4ee6a4SAndroid Build Coastguard Worker                                 input: hcall.input,
1723*bb4ee6a4SAndroid Build Coastguard Worker                                 params: hcall.params,
1724*bb4ee6a4SAndroid Build Coastguard Worker                             })
1725*bb4ee6a4SAndroid Build Coastguard Worker                         }
1726*bb4ee6a4SAndroid Build Coastguard Worker                         _ => Err(Error::new(EINVAL)),
1727*bb4ee6a4SAndroid Build Coastguard Worker                     }
1728*bb4ee6a4SAndroid Build Coastguard Worker                 }
1729*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_UNKNOWN => Ok(VcpuExit::Unknown),
1730*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_EXCEPTION => Ok(VcpuExit::Exception),
1731*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_HYPERCALL => Ok(VcpuExit::Hypercall),
1732*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_DEBUG => Ok(VcpuExit::Debug),
1733*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_HLT => Ok(VcpuExit::Hlt),
1734*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_IRQ_WINDOW_OPEN => Ok(VcpuExit::IrqWindowOpen),
1735*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_SHUTDOWN => Ok(VcpuExit::Shutdown),
1736*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_FAIL_ENTRY => {
1737*bb4ee6a4SAndroid Build Coastguard Worker                     // SAFETY:
1738*bb4ee6a4SAndroid Build Coastguard Worker                     // Safe because the exit_reason (which comes from the kernel) told us which
1739*bb4ee6a4SAndroid Build Coastguard Worker                     // union field to use.
1740*bb4ee6a4SAndroid Build Coastguard Worker                     let hardware_entry_failure_reason = unsafe {
1741*bb4ee6a4SAndroid Build Coastguard Worker                         run.__bindgen_anon_1
1742*bb4ee6a4SAndroid Build Coastguard Worker                             .fail_entry
1743*bb4ee6a4SAndroid Build Coastguard Worker                             .hardware_entry_failure_reason
1744*bb4ee6a4SAndroid Build Coastguard Worker                     };
1745*bb4ee6a4SAndroid Build Coastguard Worker                     Ok(VcpuExit::FailEntry {
1746*bb4ee6a4SAndroid Build Coastguard Worker                         hardware_entry_failure_reason,
1747*bb4ee6a4SAndroid Build Coastguard Worker                     })
1748*bb4ee6a4SAndroid Build Coastguard Worker                 }
1749*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_INTR => Ok(VcpuExit::Intr),
1750*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_SET_TPR => Ok(VcpuExit::SetTpr),
1751*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_TPR_ACCESS => Ok(VcpuExit::TprAccess),
1752*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_S390_SIEIC => Ok(VcpuExit::S390Sieic),
1753*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_S390_RESET => Ok(VcpuExit::S390Reset),
1754*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_DCR => Ok(VcpuExit::Dcr),
1755*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_NMI => Ok(VcpuExit::Nmi),
1756*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_INTERNAL_ERROR => Ok(VcpuExit::InternalError),
1757*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_OSI => Ok(VcpuExit::Osi),
1758*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_PAPR_HCALL => Ok(VcpuExit::PaprHcall),
1759*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_S390_UCONTROL => Ok(VcpuExit::S390Ucontrol),
1760*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_WATCHDOG => Ok(VcpuExit::Watchdog),
1761*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_S390_TSCH => Ok(VcpuExit::S390Tsch),
1762*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_EPR => Ok(VcpuExit::Epr),
1763*bb4ee6a4SAndroid Build Coastguard Worker                 KVM_EXIT_SYSTEM_EVENT => {
1764*bb4ee6a4SAndroid Build Coastguard Worker                     let event_type = {
1765*bb4ee6a4SAndroid Build Coastguard Worker                         // SAFETY:
1766*bb4ee6a4SAndroid Build Coastguard Worker                         // Safe because we know the exit reason told us this union
1767*bb4ee6a4SAndroid Build Coastguard Worker                         // field is valid
1768*bb4ee6a4SAndroid Build Coastguard Worker                         unsafe { run.__bindgen_anon_1.system_event.type_ }
1769*bb4ee6a4SAndroid Build Coastguard Worker                     };
1770*bb4ee6a4SAndroid Build Coastguard Worker                     // TODO(b/315998194): Add safety comment
1771*bb4ee6a4SAndroid Build Coastguard Worker                     #[allow(clippy::undocumented_unsafe_blocks)]
1772*bb4ee6a4SAndroid Build Coastguard Worker                     let event_flags =
1773*bb4ee6a4SAndroid Build Coastguard Worker                         unsafe { run.__bindgen_anon_1.system_event.__bindgen_anon_1.flags };
1774*bb4ee6a4SAndroid Build Coastguard Worker                     Ok(VcpuExit::SystemEvent(event_type, event_flags))
1775*bb4ee6a4SAndroid Build Coastguard Worker                 }
1776*bb4ee6a4SAndroid Build Coastguard Worker                 r => panic!("unknown kvm exit reason: {}", r),
1777*bb4ee6a4SAndroid Build Coastguard Worker             }
1778*bb4ee6a4SAndroid Build Coastguard Worker         } else {
1779*bb4ee6a4SAndroid Build Coastguard Worker             errno_result()
1780*bb4ee6a4SAndroid Build Coastguard Worker         }
1781*bb4ee6a4SAndroid Build Coastguard Worker     }
1782*bb4ee6a4SAndroid Build Coastguard Worker }
1783*bb4ee6a4SAndroid Build Coastguard Worker 
1784*bb4ee6a4SAndroid Build Coastguard Worker impl Deref for RunnableVcpu {
1785*bb4ee6a4SAndroid Build Coastguard Worker     type Target = Vcpu;
deref(&self) -> &Self::Target1786*bb4ee6a4SAndroid Build Coastguard Worker     fn deref(&self) -> &Self::Target {
1787*bb4ee6a4SAndroid Build Coastguard Worker         &self.vcpu
1788*bb4ee6a4SAndroid Build Coastguard Worker     }
1789*bb4ee6a4SAndroid Build Coastguard Worker }
1790*bb4ee6a4SAndroid Build Coastguard Worker 
1791*bb4ee6a4SAndroid Build Coastguard Worker impl DerefMut for RunnableVcpu {
deref_mut(&mut self) -> &mut Self::Target1792*bb4ee6a4SAndroid Build Coastguard Worker     fn deref_mut(&mut self) -> &mut Self::Target {
1793*bb4ee6a4SAndroid Build Coastguard Worker         &mut self.vcpu
1794*bb4ee6a4SAndroid Build Coastguard Worker     }
1795*bb4ee6a4SAndroid Build Coastguard Worker }
1796*bb4ee6a4SAndroid Build Coastguard Worker 
1797*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for RunnableVcpu {
as_raw_descriptor(&self) -> RawDescriptor1798*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
1799*bb4ee6a4SAndroid Build Coastguard Worker         self.vcpu.as_raw_descriptor()
1800*bb4ee6a4SAndroid Build Coastguard Worker     }
1801*bb4ee6a4SAndroid Build Coastguard Worker }
1802*bb4ee6a4SAndroid Build Coastguard Worker 
1803*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for RunnableVcpu {
drop(&mut self)1804*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
1805*bb4ee6a4SAndroid Build Coastguard Worker         VCPU_THREAD.with(|v| {
1806*bb4ee6a4SAndroid Build Coastguard Worker             // This assumes that a failure in `BlockedSignal::new` means the signal is already
1807*bb4ee6a4SAndroid Build Coastguard Worker             // blocked and there it should not be unblocked on exit.
1808*bb4ee6a4SAndroid Build Coastguard Worker             let _blocked_signal = &(*v.borrow())
1809*bb4ee6a4SAndroid Build Coastguard Worker                 .as_ref()
1810*bb4ee6a4SAndroid Build Coastguard Worker                 .and_then(|state| state.signal_num)
1811*bb4ee6a4SAndroid Build Coastguard Worker                 .map(BlockedSignal::new);
1812*bb4ee6a4SAndroid Build Coastguard Worker 
1813*bb4ee6a4SAndroid Build Coastguard Worker             *v.borrow_mut() = None;
1814*bb4ee6a4SAndroid Build Coastguard Worker         });
1815*bb4ee6a4SAndroid Build Coastguard Worker     }
1816*bb4ee6a4SAndroid Build Coastguard Worker }
1817*bb4ee6a4SAndroid Build Coastguard Worker 
1818*bb4ee6a4SAndroid Build Coastguard Worker /// Wrapper for kvm_cpuid2 which has a zero length array at the end.
1819*bb4ee6a4SAndroid Build Coastguard Worker /// Hides the zero length array behind a bounds check.
1820*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")]
1821*bb4ee6a4SAndroid Build Coastguard Worker pub type CpuId = FlexibleArrayWrapper<kvm_cpuid2, kvm_cpuid_entry2>;
1822