xref: /aosp_15_r20/external/crosvm/hypervisor/src/x86_64.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::CpuidResult;
6*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(unix, feature = "haxm", feature = "whpx"))]
7*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::__cpuid;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::arch::x86_64::_rdtsc;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::HashSet;
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context;
13*bb4ee6a4SAndroid Build Coastguard Worker use base::custom_serde::deserialize_seq_to_arr;
14*bb4ee6a4SAndroid Build Coastguard Worker use base::custom_serde::serialize_arr;
15*bb4ee6a4SAndroid Build Coastguard Worker use base::error;
16*bb4ee6a4SAndroid Build Coastguard Worker use base::warn;
17*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
18*bb4ee6a4SAndroid Build Coastguard Worker use bit_field::*;
19*bb4ee6a4SAndroid Build Coastguard Worker use downcast_rs::impl_downcast;
20*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_void;
21*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
22*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
23*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker use crate::Hypervisor;
26*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqRoute;
27*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSource;
28*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSourceChip;
29*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vcpu;
30*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vm;
31*bb4ee6a4SAndroid Build Coastguard Worker 
32*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL0: u32 = 0xc0010200;
33*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL1: u32 = 0xc0010202;
34*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL2: u32 = 0xc0010204;
35*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL3: u32 = 0xc0010206;
36*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL4: u32 = 0xc0010208;
37*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTL5: u32 = 0xc001020a;
38*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR0: u32 = 0xc0010201;
39*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR1: u32 = 0xc0010203;
40*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR2: u32 = 0xc0010205;
41*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR3: u32 = 0xc0010207;
42*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR4: u32 = 0xc0010209;
43*bb4ee6a4SAndroid Build Coastguard Worker const MSR_F15H_PERF_CTR5: u32 = 0xc001020b;
44*bb4ee6a4SAndroid Build Coastguard Worker const MSR_IA32_PERF_CAPABILITIES: u32 = 0x00000345;
45*bb4ee6a4SAndroid Build Coastguard Worker 
46*bb4ee6a4SAndroid Build Coastguard Worker /// A trait for managing cpuids for an x86_64 hypervisor and for checking its capabilities.
47*bb4ee6a4SAndroid Build Coastguard Worker pub trait HypervisorX86_64: Hypervisor {
48*bb4ee6a4SAndroid Build Coastguard Worker     /// Get the system supported CPUID values.
get_supported_cpuid(&self) -> Result<CpuId>49*bb4ee6a4SAndroid Build Coastguard Worker     fn get_supported_cpuid(&self) -> Result<CpuId>;
50*bb4ee6a4SAndroid Build Coastguard Worker 
51*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the list of supported MSRs.
get_msr_index_list(&self) -> Result<Vec<u32>>52*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr_index_list(&self) -> Result<Vec<u32>>;
53*bb4ee6a4SAndroid Build Coastguard Worker }
54*bb4ee6a4SAndroid Build Coastguard Worker 
55*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper for using a VM on x86_64 and getting/setting its state.
56*bb4ee6a4SAndroid Build Coastguard Worker pub trait VmX86_64: Vm {
57*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the `HypervisorX86_64` that created this VM.
get_hypervisor(&self) -> &dyn HypervisorX86_6458*bb4ee6a4SAndroid Build Coastguard Worker     fn get_hypervisor(&self) -> &dyn HypervisorX86_64;
59*bb4ee6a4SAndroid Build Coastguard Worker 
60*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a Vcpu with the specified Vcpu ID.
create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuX86_64>>61*bb4ee6a4SAndroid Build Coastguard Worker     fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuX86_64>>;
62*bb4ee6a4SAndroid Build Coastguard Worker 
63*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the address of the three-page region in the VM's address space.
set_tss_addr(&self, addr: GuestAddress) -> Result<()>64*bb4ee6a4SAndroid Build Coastguard Worker     fn set_tss_addr(&self, addr: GuestAddress) -> Result<()>;
65*bb4ee6a4SAndroid Build Coastguard Worker 
66*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the address of a one-page region in the VM's address space.
set_identity_map_addr(&self, addr: GuestAddress) -> Result<()>67*bb4ee6a4SAndroid Build Coastguard Worker     fn set_identity_map_addr(&self, addr: GuestAddress) -> Result<()>;
68*bb4ee6a4SAndroid Build Coastguard Worker }
69*bb4ee6a4SAndroid Build Coastguard Worker 
70*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around creating and using a VCPU on x86_64.
71*bb4ee6a4SAndroid Build Coastguard Worker pub trait VcpuX86_64: Vcpu {
72*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets or clears the flag that requests the VCPU to exit when it becomes possible to inject
73*bb4ee6a4SAndroid Build Coastguard Worker     /// interrupts into the guest.
set_interrupt_window_requested(&self, requested: bool)74*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_window_requested(&self, requested: bool);
75*bb4ee6a4SAndroid Build Coastguard Worker 
76*bb4ee6a4SAndroid Build Coastguard Worker     /// Checks if we can inject an interrupt into the VCPU.
ready_for_interrupt(&self) -> bool77*bb4ee6a4SAndroid Build Coastguard Worker     fn ready_for_interrupt(&self) -> bool;
78*bb4ee6a4SAndroid Build Coastguard Worker 
79*bb4ee6a4SAndroid Build Coastguard Worker     /// Injects interrupt vector `irq` into the VCPU.
80*bb4ee6a4SAndroid Build Coastguard Worker     ///
81*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should only be called when [`Self::ready_for_interrupt`] returns true.
82*bb4ee6a4SAndroid Build Coastguard Worker     /// Otherwise the interrupt injection may fail or the next VCPU run may fail. However, if
83*bb4ee6a4SAndroid Build Coastguard Worker     /// [`Self::interrupt`] returns [`Ok`], the implementation must guarantee that the interrupt
84*bb4ee6a4SAndroid Build Coastguard Worker     /// isn't injected in an uninterruptible window (e.g. right after the mov ss instruction).
85*bb4ee6a4SAndroid Build Coastguard Worker     ///
86*bb4ee6a4SAndroid Build Coastguard Worker     /// The caller should avoid calling this function more than 1 time for one VMEXIT, because the
87*bb4ee6a4SAndroid Build Coastguard Worker     /// hypervisor may behave differently: some hypervisors(e.g. WHPX, KVM) will only try to inject
88*bb4ee6a4SAndroid Build Coastguard Worker     /// the last `irq` requested, while some other hypervisors(e.g. HAXM) may try to inject all
89*bb4ee6a4SAndroid Build Coastguard Worker     /// `irq`s requested.
interrupt(&self, irq: u8) -> Result<()>90*bb4ee6a4SAndroid Build Coastguard Worker     fn interrupt(&self, irq: u8) -> Result<()>;
91*bb4ee6a4SAndroid Build Coastguard Worker 
92*bb4ee6a4SAndroid Build Coastguard Worker     /// Injects a non-maskable interrupt into the VCPU.
inject_nmi(&self) -> Result<()>93*bb4ee6a4SAndroid Build Coastguard Worker     fn inject_nmi(&self) -> Result<()>;
94*bb4ee6a4SAndroid Build Coastguard Worker 
95*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU general purpose registers.
get_regs(&self) -> Result<Regs>96*bb4ee6a4SAndroid Build Coastguard Worker     fn get_regs(&self) -> Result<Regs>;
97*bb4ee6a4SAndroid Build Coastguard Worker 
98*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU general purpose registers.
set_regs(&self, regs: &Regs) -> Result<()>99*bb4ee6a4SAndroid Build Coastguard Worker     fn set_regs(&self, regs: &Regs) -> Result<()>;
100*bb4ee6a4SAndroid Build Coastguard Worker 
101*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU special registers.
get_sregs(&self) -> Result<Sregs>102*bb4ee6a4SAndroid Build Coastguard Worker     fn get_sregs(&self) -> Result<Sregs>;
103*bb4ee6a4SAndroid Build Coastguard Worker 
104*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU special registers.
set_sregs(&self, sregs: &Sregs) -> Result<()>105*bb4ee6a4SAndroid Build Coastguard Worker     fn set_sregs(&self, sregs: &Sregs) -> Result<()>;
106*bb4ee6a4SAndroid Build Coastguard Worker 
107*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU FPU registers.
get_fpu(&self) -> Result<Fpu>108*bb4ee6a4SAndroid Build Coastguard Worker     fn get_fpu(&self) -> Result<Fpu>;
109*bb4ee6a4SAndroid Build Coastguard Worker 
110*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU FPU registers.
set_fpu(&self, fpu: &Fpu) -> Result<()>111*bb4ee6a4SAndroid Build Coastguard Worker     fn set_fpu(&self, fpu: &Fpu) -> Result<()>;
112*bb4ee6a4SAndroid Build Coastguard Worker 
113*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU debug registers.
get_debugregs(&self) -> Result<DebugRegs>114*bb4ee6a4SAndroid Build Coastguard Worker     fn get_debugregs(&self) -> Result<DebugRegs>;
115*bb4ee6a4SAndroid Build Coastguard Worker 
116*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU debug registers.
set_debugregs(&self, debugregs: &DebugRegs) -> Result<()>117*bb4ee6a4SAndroid Build Coastguard Worker     fn set_debugregs(&self, debugregs: &DebugRegs) -> Result<()>;
118*bb4ee6a4SAndroid Build Coastguard Worker 
119*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU extended control registers.
get_xcrs(&self) -> Result<BTreeMap<u32, u64>>120*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>>;
121*bb4ee6a4SAndroid Build Coastguard Worker 
122*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets a VCPU extended control register.
set_xcr(&self, xcr: u32, value: u64) -> Result<()>123*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xcr(&self, xcr: u32, value: u64) -> Result<()>;
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the VCPU x87 FPU, MMX, XMM, YMM and MXCSR registers.
get_xsave(&self) -> Result<Xsave>126*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xsave(&self) -> Result<Xsave>;
127*bb4ee6a4SAndroid Build Coastguard Worker 
128*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the VCPU x87 FPU, MMX, XMM, YMM and MXCSR registers.
set_xsave(&self, xsave: &Xsave) -> Result<()>129*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xsave(&self, xsave: &Xsave) -> Result<()>;
130*bb4ee6a4SAndroid Build Coastguard Worker 
131*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets interrupt state (hypervisor specific) for this VCPU that must be
132*bb4ee6a4SAndroid Build Coastguard Worker     /// saved/restored for snapshotting.
get_interrupt_state(&self) -> Result<serde_json::Value>133*bb4ee6a4SAndroid Build Coastguard Worker     fn get_interrupt_state(&self) -> Result<serde_json::Value>;
134*bb4ee6a4SAndroid Build Coastguard Worker 
135*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets interrupt state (hypervisor specific) for this VCPU. Only used for
136*bb4ee6a4SAndroid Build Coastguard Worker     /// snapshotting.
set_interrupt_state(&self, data: serde_json::Value) -> Result<()>137*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_state(&self, data: serde_json::Value) -> Result<()>;
138*bb4ee6a4SAndroid Build Coastguard Worker 
139*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets a single model-specific register's value.
get_msr(&self, msr_index: u32) -> Result<u64>140*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr(&self, msr_index: u32) -> Result<u64>;
141*bb4ee6a4SAndroid Build Coastguard Worker 
142*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the model-specific registers. Returns all the MSRs for the VCPU.
get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>143*bb4ee6a4SAndroid Build Coastguard Worker     fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>;
144*bb4ee6a4SAndroid Build Coastguard Worker 
145*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets a single model-specific register's value.
set_msr(&self, msr_index: u32, value: u64) -> Result<()>146*bb4ee6a4SAndroid Build Coastguard Worker     fn set_msr(&self, msr_index: u32, value: u64) -> Result<()>;
147*bb4ee6a4SAndroid Build Coastguard Worker 
148*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets up the data returned by the CPUID instruction.
set_cpuid(&self, cpuid: &CpuId) -> Result<()>149*bb4ee6a4SAndroid Build Coastguard Worker     fn set_cpuid(&self, cpuid: &CpuId) -> Result<()>;
150*bb4ee6a4SAndroid Build Coastguard Worker 
151*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets up debug registers and configure vcpu for handling guest debug events.
set_guest_debug(&self, addrs: &[GuestAddress], enable_singlestep: bool) -> Result<()>152*bb4ee6a4SAndroid Build Coastguard Worker     fn set_guest_debug(&self, addrs: &[GuestAddress], enable_singlestep: bool) -> Result<()>;
153*bb4ee6a4SAndroid Build Coastguard Worker 
154*bb4ee6a4SAndroid Build Coastguard Worker     /// This function should be called after `Vcpu::run` returns `VcpuExit::Cpuid`, and `entry`
155*bb4ee6a4SAndroid Build Coastguard Worker     /// should represent the result of emulating the CPUID instruction. The `handle_cpuid` function
156*bb4ee6a4SAndroid Build Coastguard Worker     /// will then set the appropriate registers on the vcpu.
handle_cpuid(&mut self, entry: &CpuIdEntry) -> Result<()>157*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_cpuid(&mut self, entry: &CpuIdEntry) -> Result<()>;
158*bb4ee6a4SAndroid Build Coastguard Worker 
159*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets the guest->host TSC offset.
160*bb4ee6a4SAndroid Build Coastguard Worker     ///
161*bb4ee6a4SAndroid Build Coastguard Worker     /// The default implementation uses [`VcpuX86_64::get_msr()`] to read the guest TSC.
get_tsc_offset(&self) -> Result<u64>162*bb4ee6a4SAndroid Build Coastguard Worker     fn get_tsc_offset(&self) -> Result<u64> {
163*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
164*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because _rdtsc takes no arguments
165*bb4ee6a4SAndroid Build Coastguard Worker         let host_before_tsc = unsafe { _rdtsc() };
166*bb4ee6a4SAndroid Build Coastguard Worker 
167*bb4ee6a4SAndroid Build Coastguard Worker         // get guest TSC value from our hypervisor
168*bb4ee6a4SAndroid Build Coastguard Worker         let guest_tsc = self.get_msr(crate::MSR_IA32_TSC)?;
169*bb4ee6a4SAndroid Build Coastguard Worker 
170*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
171*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because _rdtsc takes no arguments
172*bb4ee6a4SAndroid Build Coastguard Worker         let host_after_tsc = unsafe { _rdtsc() };
173*bb4ee6a4SAndroid Build Coastguard Worker 
174*bb4ee6a4SAndroid Build Coastguard Worker         // Average the before and after host tsc to get the best value
175*bb4ee6a4SAndroid Build Coastguard Worker         let host_tsc = ((host_before_tsc as u128 + host_after_tsc as u128) / 2) as u64;
176*bb4ee6a4SAndroid Build Coastguard Worker 
177*bb4ee6a4SAndroid Build Coastguard Worker         Ok(guest_tsc.wrapping_sub(host_tsc))
178*bb4ee6a4SAndroid Build Coastguard Worker     }
179*bb4ee6a4SAndroid Build Coastguard Worker 
180*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the guest->host TSC offset.
181*bb4ee6a4SAndroid Build Coastguard Worker     ///
182*bb4ee6a4SAndroid Build Coastguard Worker     /// The default implementation uses [`VcpuX86_64::set_tsc_value()`] to set the TSC value.
183*bb4ee6a4SAndroid Build Coastguard Worker     ///
184*bb4ee6a4SAndroid Build Coastguard Worker     /// It sets TSC_OFFSET (VMCS / CB field) by setting the TSC MSR to the current
185*bb4ee6a4SAndroid Build Coastguard Worker     /// host TSC value plus the desired offset. We rely on the fact that hypervisors
186*bb4ee6a4SAndroid Build Coastguard Worker     /// determine the value of TSC_OFFSET by computing TSC_OFFSET = `new_tsc_value - _rdtsc()` =
187*bb4ee6a4SAndroid Build Coastguard Worker     /// `_rdtsc() + offset - _rdtsc()` ~= `offset`. Note that the ~= is important: this is an
188*bb4ee6a4SAndroid Build Coastguard Worker     /// approximate operation, because the two _rdtsc() calls
189*bb4ee6a4SAndroid Build Coastguard Worker     /// are separated by at least a few ticks.
190*bb4ee6a4SAndroid Build Coastguard Worker     ///
191*bb4ee6a4SAndroid Build Coastguard Worker     /// Note: TSC_OFFSET, host TSC, guest TSC, and TSC MSR are all different
192*bb4ee6a4SAndroid Build Coastguard Worker     /// concepts.
193*bb4ee6a4SAndroid Build Coastguard Worker     /// * When a guest executes rdtsc, the value (guest TSC) returned is host_tsc * TSC_MULTIPLIER +
194*bb4ee6a4SAndroid Build Coastguard Worker     ///   TSC_OFFSET + TSC_ADJUST.
195*bb4ee6a4SAndroid Build Coastguard Worker     /// * The TSC MSR is a special MSR that when written to by the host, will cause TSC_OFFSET to be
196*bb4ee6a4SAndroid Build Coastguard Worker     ///   set accordingly by the hypervisor.
197*bb4ee6a4SAndroid Build Coastguard Worker     /// * When the guest *writes* to TSC MSR, it actually changes the TSC_ADJUST MSR *for the
198*bb4ee6a4SAndroid Build Coastguard Worker     ///   guest*. Generally this is only happens if the guest is trying to re-zero or synchronize
199*bb4ee6a4SAndroid Build Coastguard Worker     ///   TSCs.
set_tsc_offset(&self, offset: u64) -> Result<()>200*bb4ee6a4SAndroid Build Coastguard Worker     fn set_tsc_offset(&self, offset: u64) -> Result<()> {
201*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: _rdtsc takes no arguments.
202*bb4ee6a4SAndroid Build Coastguard Worker         let host_tsc = unsafe { _rdtsc() };
203*bb4ee6a4SAndroid Build Coastguard Worker         self.set_tsc_value(host_tsc.wrapping_add(offset))
204*bb4ee6a4SAndroid Build Coastguard Worker     }
205*bb4ee6a4SAndroid Build Coastguard Worker 
206*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the guest TSC exactly to the provided value.
207*bb4ee6a4SAndroid Build Coastguard Worker     ///
208*bb4ee6a4SAndroid Build Coastguard Worker     /// The default implementation sets the guest's TSC by writing the value to the MSR directly.
209*bb4ee6a4SAndroid Build Coastguard Worker     ///
210*bb4ee6a4SAndroid Build Coastguard Worker     /// See [`VcpuX86_64::set_tsc_offset()`] for an explanation of how this value is actually read
211*bb4ee6a4SAndroid Build Coastguard Worker     /// by the guest after being set.
set_tsc_value(&self, value: u64) -> Result<()>212*bb4ee6a4SAndroid Build Coastguard Worker     fn set_tsc_value(&self, value: u64) -> Result<()> {
213*bb4ee6a4SAndroid Build Coastguard Worker         self.set_msr(crate::MSR_IA32_TSC, value)
214*bb4ee6a4SAndroid Build Coastguard Worker     }
215*bb4ee6a4SAndroid Build Coastguard Worker 
216*bb4ee6a4SAndroid Build Coastguard Worker     /// Some hypervisors require special handling to restore timekeeping when
217*bb4ee6a4SAndroid Build Coastguard Worker     /// a snapshot is restored. They are provided with a host TSC reference
218*bb4ee6a4SAndroid Build Coastguard Worker     /// moment, guaranteed to be the same across all Vcpus, and the Vcpu's TSC
219*bb4ee6a4SAndroid Build Coastguard Worker     /// offset at the moment it was snapshotted.
restore_timekeeping(&self, host_tsc_reference_moment: u64, tsc_offset: u64) -> Result<()>220*bb4ee6a4SAndroid Build Coastguard Worker     fn restore_timekeeping(&self, host_tsc_reference_moment: u64, tsc_offset: u64) -> Result<()>;
221*bb4ee6a4SAndroid Build Coastguard Worker 
222*bb4ee6a4SAndroid Build Coastguard Worker     /// Snapshot vCPU state
snapshot(&self) -> anyhow::Result<VcpuSnapshot>223*bb4ee6a4SAndroid Build Coastguard Worker     fn snapshot(&self) -> anyhow::Result<VcpuSnapshot> {
224*bb4ee6a4SAndroid Build Coastguard Worker         Ok(VcpuSnapshot {
225*bb4ee6a4SAndroid Build Coastguard Worker             vcpu_id: self.id(),
226*bb4ee6a4SAndroid Build Coastguard Worker             regs: self.get_regs()?,
227*bb4ee6a4SAndroid Build Coastguard Worker             sregs: self.get_sregs()?,
228*bb4ee6a4SAndroid Build Coastguard Worker             debug_regs: self.get_debugregs()?,
229*bb4ee6a4SAndroid Build Coastguard Worker             xcrs: self.get_xcrs()?,
230*bb4ee6a4SAndroid Build Coastguard Worker             msrs: self.get_all_msrs()?,
231*bb4ee6a4SAndroid Build Coastguard Worker             xsave: self.get_xsave()?,
232*bb4ee6a4SAndroid Build Coastguard Worker             hypervisor_data: self.get_interrupt_state()?,
233*bb4ee6a4SAndroid Build Coastguard Worker             tsc_offset: self.get_tsc_offset()?,
234*bb4ee6a4SAndroid Build Coastguard Worker         })
235*bb4ee6a4SAndroid Build Coastguard Worker     }
236*bb4ee6a4SAndroid Build Coastguard Worker 
restore( &mut self, snapshot: &VcpuSnapshot, host_tsc_reference_moment: u64, ) -> anyhow::Result<()>237*bb4ee6a4SAndroid Build Coastguard Worker     fn restore(
238*bb4ee6a4SAndroid Build Coastguard Worker         &mut self,
239*bb4ee6a4SAndroid Build Coastguard Worker         snapshot: &VcpuSnapshot,
240*bb4ee6a4SAndroid Build Coastguard Worker         host_tsc_reference_moment: u64,
241*bb4ee6a4SAndroid Build Coastguard Worker     ) -> anyhow::Result<()> {
242*bb4ee6a4SAndroid Build Coastguard Worker         // List of MSRs that may fail to restore due to lack of support in the host kernel.
243*bb4ee6a4SAndroid Build Coastguard Worker         // Some hosts are may be running older kernels which do not support all MSRs, but
244*bb4ee6a4SAndroid Build Coastguard Worker         // get_all_msrs will still fetch the MSRs supported by the CPU. Trying to set those MSRs
245*bb4ee6a4SAndroid Build Coastguard Worker         // will result in failures, so they will throw a warning instead.
246*bb4ee6a4SAndroid Build Coastguard Worker         let msr_allowlist = HashSet::from([
247*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL0,
248*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL1,
249*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL2,
250*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL3,
251*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL4,
252*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTL5,
253*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR0,
254*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR1,
255*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR2,
256*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR3,
257*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR4,
258*bb4ee6a4SAndroid Build Coastguard Worker             MSR_F15H_PERF_CTR5,
259*bb4ee6a4SAndroid Build Coastguard Worker             MSR_IA32_PERF_CAPABILITIES,
260*bb4ee6a4SAndroid Build Coastguard Worker         ]);
261*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(snapshot.vcpu_id, self.id());
262*bb4ee6a4SAndroid Build Coastguard Worker         self.set_regs(&snapshot.regs)?;
263*bb4ee6a4SAndroid Build Coastguard Worker         self.set_sregs(&snapshot.sregs)?;
264*bb4ee6a4SAndroid Build Coastguard Worker         self.set_debugregs(&snapshot.debug_regs)?;
265*bb4ee6a4SAndroid Build Coastguard Worker         for (xcr_index, value) in &snapshot.xcrs {
266*bb4ee6a4SAndroid Build Coastguard Worker             self.set_xcr(*xcr_index, *value)?;
267*bb4ee6a4SAndroid Build Coastguard Worker         }
268*bb4ee6a4SAndroid Build Coastguard Worker 
269*bb4ee6a4SAndroid Build Coastguard Worker         for (msr_index, value) in snapshot.msrs.iter() {
270*bb4ee6a4SAndroid Build Coastguard Worker             if self.get_msr(*msr_index) == Ok(*value) {
271*bb4ee6a4SAndroid Build Coastguard Worker                 continue; // no need to set MSR since the values are the same.
272*bb4ee6a4SAndroid Build Coastguard Worker             }
273*bb4ee6a4SAndroid Build Coastguard Worker             if let Err(e) = self.set_msr(*msr_index, *value) {
274*bb4ee6a4SAndroid Build Coastguard Worker                 if msr_allowlist.contains(msr_index) {
275*bb4ee6a4SAndroid Build Coastguard Worker                     warn!(
276*bb4ee6a4SAndroid Build Coastguard Worker                         "Failed to set MSR. MSR might not be supported in this kernel. Err: {}",
277*bb4ee6a4SAndroid Build Coastguard Worker                         e
278*bb4ee6a4SAndroid Build Coastguard Worker                     );
279*bb4ee6a4SAndroid Build Coastguard Worker                 } else {
280*bb4ee6a4SAndroid Build Coastguard Worker                     return Err(e).context(
281*bb4ee6a4SAndroid Build Coastguard Worker                         "Failed to set MSR. MSR might not be supported by the CPU or by the kernel,
282*bb4ee6a4SAndroid Build Coastguard Worker                          and was not allow-listed.",
283*bb4ee6a4SAndroid Build Coastguard Worker                     );
284*bb4ee6a4SAndroid Build Coastguard Worker                 }
285*bb4ee6a4SAndroid Build Coastguard Worker             };
286*bb4ee6a4SAndroid Build Coastguard Worker         }
287*bb4ee6a4SAndroid Build Coastguard Worker         self.set_xsave(&snapshot.xsave)?;
288*bb4ee6a4SAndroid Build Coastguard Worker         self.set_interrupt_state(snapshot.hypervisor_data.clone())?;
289*bb4ee6a4SAndroid Build Coastguard Worker         self.restore_timekeeping(host_tsc_reference_moment, snapshot.tsc_offset)?;
290*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
291*bb4ee6a4SAndroid Build Coastguard Worker     }
292*bb4ee6a4SAndroid Build Coastguard Worker }
293*bb4ee6a4SAndroid Build Coastguard Worker 
294*bb4ee6a4SAndroid Build Coastguard Worker /// x86 specific vCPU snapshot.
295*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Serialize, Deserialize)]
296*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuSnapshot {
297*bb4ee6a4SAndroid Build Coastguard Worker     pub vcpu_id: usize,
298*bb4ee6a4SAndroid Build Coastguard Worker     regs: Regs,
299*bb4ee6a4SAndroid Build Coastguard Worker     sregs: Sregs,
300*bb4ee6a4SAndroid Build Coastguard Worker     debug_regs: DebugRegs,
301*bb4ee6a4SAndroid Build Coastguard Worker     xcrs: BTreeMap<u32, u64>,
302*bb4ee6a4SAndroid Build Coastguard Worker     msrs: BTreeMap<u32, u64>,
303*bb4ee6a4SAndroid Build Coastguard Worker     xsave: Xsave,
304*bb4ee6a4SAndroid Build Coastguard Worker     hypervisor_data: serde_json::Value,
305*bb4ee6a4SAndroid Build Coastguard Worker     tsc_offset: u64,
306*bb4ee6a4SAndroid Build Coastguard Worker }
307*bb4ee6a4SAndroid Build Coastguard Worker 
308*bb4ee6a4SAndroid Build Coastguard Worker impl_downcast!(VcpuX86_64);
309*bb4ee6a4SAndroid Build Coastguard Worker 
310*bb4ee6a4SAndroid Build Coastguard Worker // TSC MSR
311*bb4ee6a4SAndroid Build Coastguard Worker pub const MSR_IA32_TSC: u32 = 0x00000010;
312*bb4ee6a4SAndroid Build Coastguard Worker 
313*bb4ee6a4SAndroid Build Coastguard Worker /// Gets host cpu max physical address bits.
314*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(unix, feature = "haxm", feature = "whpx"))]
host_phys_addr_bits() -> u8315*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) fn host_phys_addr_bits() -> u8 {
316*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: trivially safe
317*bb4ee6a4SAndroid Build Coastguard Worker     let highest_ext_function = unsafe { __cpuid(0x80000000) };
318*bb4ee6a4SAndroid Build Coastguard Worker     if highest_ext_function.eax >= 0x80000008 {
319*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
320*bb4ee6a4SAndroid Build Coastguard Worker         let addr_size = unsafe { __cpuid(0x80000008) };
321*bb4ee6a4SAndroid Build Coastguard Worker         // Low 8 bits of 0x80000008 leaf: host physical address size in bits.
322*bb4ee6a4SAndroid Build Coastguard Worker         addr_size.eax as u8
323*bb4ee6a4SAndroid Build Coastguard Worker     } else {
324*bb4ee6a4SAndroid Build Coastguard Worker         36
325*bb4ee6a4SAndroid Build Coastguard Worker     }
326*bb4ee6a4SAndroid Build Coastguard Worker }
327*bb4ee6a4SAndroid Build Coastguard Worker 
328*bb4ee6a4SAndroid Build Coastguard Worker /// Initial state for x86_64 VCPUs.
329*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Default)]
330*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuInitX86_64 {
331*bb4ee6a4SAndroid Build Coastguard Worker     /// General-purpose registers.
332*bb4ee6a4SAndroid Build Coastguard Worker     pub regs: Regs,
333*bb4ee6a4SAndroid Build Coastguard Worker 
334*bb4ee6a4SAndroid Build Coastguard Worker     /// Special registers.
335*bb4ee6a4SAndroid Build Coastguard Worker     pub sregs: Sregs,
336*bb4ee6a4SAndroid Build Coastguard Worker 
337*bb4ee6a4SAndroid Build Coastguard Worker     /// Floating-point registers.
338*bb4ee6a4SAndroid Build Coastguard Worker     pub fpu: Fpu,
339*bb4ee6a4SAndroid Build Coastguard Worker 
340*bb4ee6a4SAndroid Build Coastguard Worker     /// Machine-specific registers.
341*bb4ee6a4SAndroid Build Coastguard Worker     pub msrs: BTreeMap<u32, u64>,
342*bb4ee6a4SAndroid Build Coastguard Worker }
343*bb4ee6a4SAndroid Build Coastguard Worker 
344*bb4ee6a4SAndroid Build Coastguard Worker /// Hold the CPU feature configurations that are needed to setup a vCPU.
345*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, PartialEq, Eq)]
346*bb4ee6a4SAndroid Build Coastguard Worker pub struct CpuConfigX86_64 {
347*bb4ee6a4SAndroid Build Coastguard Worker     /// whether to force using a calibrated TSC leaf (0x15).
348*bb4ee6a4SAndroid Build Coastguard Worker     pub force_calibrated_tsc_leaf: bool,
349*bb4ee6a4SAndroid Build Coastguard Worker 
350*bb4ee6a4SAndroid Build Coastguard Worker     /// whether enabling host cpu topology.
351*bb4ee6a4SAndroid Build Coastguard Worker     pub host_cpu_topology: bool,
352*bb4ee6a4SAndroid Build Coastguard Worker 
353*bb4ee6a4SAndroid Build Coastguard Worker     /// whether expose HWP feature to the guest.
354*bb4ee6a4SAndroid Build Coastguard Worker     pub enable_hwp: bool,
355*bb4ee6a4SAndroid Build Coastguard Worker 
356*bb4ee6a4SAndroid Build Coastguard Worker     /// Wheter diabling SMT (Simultaneous Multithreading).
357*bb4ee6a4SAndroid Build Coastguard Worker     pub no_smt: bool,
358*bb4ee6a4SAndroid Build Coastguard Worker 
359*bb4ee6a4SAndroid Build Coastguard Worker     /// whether enabling ITMT scheduler
360*bb4ee6a4SAndroid Build Coastguard Worker     pub itmt: bool,
361*bb4ee6a4SAndroid Build Coastguard Worker 
362*bb4ee6a4SAndroid Build Coastguard Worker     /// whether setting hybrid CPU type
363*bb4ee6a4SAndroid Build Coastguard Worker     pub hybrid_type: Option<CpuHybridType>,
364*bb4ee6a4SAndroid Build Coastguard Worker }
365*bb4ee6a4SAndroid Build Coastguard Worker 
366*bb4ee6a4SAndroid Build Coastguard Worker impl CpuConfigX86_64 {
new( force_calibrated_tsc_leaf: bool, host_cpu_topology: bool, enable_hwp: bool, no_smt: bool, itmt: bool, hybrid_type: Option<CpuHybridType>, ) -> Self367*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(
368*bb4ee6a4SAndroid Build Coastguard Worker         force_calibrated_tsc_leaf: bool,
369*bb4ee6a4SAndroid Build Coastguard Worker         host_cpu_topology: bool,
370*bb4ee6a4SAndroid Build Coastguard Worker         enable_hwp: bool,
371*bb4ee6a4SAndroid Build Coastguard Worker         no_smt: bool,
372*bb4ee6a4SAndroid Build Coastguard Worker         itmt: bool,
373*bb4ee6a4SAndroid Build Coastguard Worker         hybrid_type: Option<CpuHybridType>,
374*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Self {
375*bb4ee6a4SAndroid Build Coastguard Worker         CpuConfigX86_64 {
376*bb4ee6a4SAndroid Build Coastguard Worker             force_calibrated_tsc_leaf,
377*bb4ee6a4SAndroid Build Coastguard Worker             host_cpu_topology,
378*bb4ee6a4SAndroid Build Coastguard Worker             enable_hwp,
379*bb4ee6a4SAndroid Build Coastguard Worker             no_smt,
380*bb4ee6a4SAndroid Build Coastguard Worker             itmt,
381*bb4ee6a4SAndroid Build Coastguard Worker             hybrid_type,
382*bb4ee6a4SAndroid Build Coastguard Worker         }
383*bb4ee6a4SAndroid Build Coastguard Worker     }
384*bb4ee6a4SAndroid Build Coastguard Worker }
385*bb4ee6a4SAndroid Build Coastguard Worker 
386*bb4ee6a4SAndroid Build Coastguard Worker /// A CpuId Entry contains supported feature information for the given processor.
387*bb4ee6a4SAndroid Build Coastguard Worker /// This can be modified by the hypervisor to pass additional information to the guest kernel
388*bb4ee6a4SAndroid Build Coastguard Worker /// about the hypervisor or vm. Information is returned in the eax, ebx, ecx and edx registers
389*bb4ee6a4SAndroid Build Coastguard Worker /// by the cpu for a given function and index/subfunction (passed into the cpu via the eax and ecx
390*bb4ee6a4SAndroid Build Coastguard Worker /// register respectively).
391*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
392*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)]
393*bb4ee6a4SAndroid Build Coastguard Worker pub struct CpuIdEntry {
394*bb4ee6a4SAndroid Build Coastguard Worker     pub function: u32,
395*bb4ee6a4SAndroid Build Coastguard Worker     pub index: u32,
396*bb4ee6a4SAndroid Build Coastguard Worker     // flags is needed for KVM.  We store it on CpuIdEntry to preserve the flags across
397*bb4ee6a4SAndroid Build Coastguard Worker     // get_supported_cpuids() -> kvm_cpuid2 -> CpuId -> kvm_cpuid2 -> set_cpuid().
398*bb4ee6a4SAndroid Build Coastguard Worker     pub flags: u32,
399*bb4ee6a4SAndroid Build Coastguard Worker     pub cpuid: CpuidResult,
400*bb4ee6a4SAndroid Build Coastguard Worker }
401*bb4ee6a4SAndroid Build Coastguard Worker 
402*bb4ee6a4SAndroid Build Coastguard Worker /// A container for the list of cpu id entries for the hypervisor and underlying cpu.
403*bb4ee6a4SAndroid Build Coastguard Worker pub struct CpuId {
404*bb4ee6a4SAndroid Build Coastguard Worker     pub cpu_id_entries: Vec<CpuIdEntry>,
405*bb4ee6a4SAndroid Build Coastguard Worker }
406*bb4ee6a4SAndroid Build Coastguard Worker 
407*bb4ee6a4SAndroid Build Coastguard Worker impl CpuId {
408*bb4ee6a4SAndroid Build Coastguard Worker     /// Constructs a new CpuId, with space allocated for `initial_capacity` CpuIdEntries.
new(initial_capacity: usize) -> Self409*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(initial_capacity: usize) -> Self {
410*bb4ee6a4SAndroid Build Coastguard Worker         CpuId {
411*bb4ee6a4SAndroid Build Coastguard Worker             cpu_id_entries: Vec::with_capacity(initial_capacity),
412*bb4ee6a4SAndroid Build Coastguard Worker         }
413*bb4ee6a4SAndroid Build Coastguard Worker     }
414*bb4ee6a4SAndroid Build Coastguard Worker }
415*bb4ee6a4SAndroid Build Coastguard Worker 
416*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
417*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)]
418*bb4ee6a4SAndroid Build Coastguard Worker pub enum DestinationMode {
419*bb4ee6a4SAndroid Build Coastguard Worker     Physical = 0,
420*bb4ee6a4SAndroid Build Coastguard Worker     Logical = 1,
421*bb4ee6a4SAndroid Build Coastguard Worker }
422*bb4ee6a4SAndroid Build Coastguard Worker 
423*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
424*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)]
425*bb4ee6a4SAndroid Build Coastguard Worker pub enum TriggerMode {
426*bb4ee6a4SAndroid Build Coastguard Worker     Edge = 0,
427*bb4ee6a4SAndroid Build Coastguard Worker     Level = 1,
428*bb4ee6a4SAndroid Build Coastguard Worker }
429*bb4ee6a4SAndroid Build Coastguard Worker 
430*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
431*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq)]
432*bb4ee6a4SAndroid Build Coastguard Worker pub enum DeliveryMode {
433*bb4ee6a4SAndroid Build Coastguard Worker     Fixed = 0b000,
434*bb4ee6a4SAndroid Build Coastguard Worker     Lowest = 0b001,
435*bb4ee6a4SAndroid Build Coastguard Worker     SMI = 0b010,        // System management interrupt
436*bb4ee6a4SAndroid Build Coastguard Worker     RemoteRead = 0b011, // This is no longer supported by intel.
437*bb4ee6a4SAndroid Build Coastguard Worker     NMI = 0b100,        // Non maskable interrupt
438*bb4ee6a4SAndroid Build Coastguard Worker     Init = 0b101,
439*bb4ee6a4SAndroid Build Coastguard Worker     Startup = 0b110,
440*bb4ee6a4SAndroid Build Coastguard Worker     External = 0b111,
441*bb4ee6a4SAndroid Build Coastguard Worker }
442*bb4ee6a4SAndroid Build Coastguard Worker 
443*bb4ee6a4SAndroid Build Coastguard Worker // These MSI structures are for Intel's implementation of MSI.  The PCI spec defines most of MSI,
444*bb4ee6a4SAndroid Build Coastguard Worker // but the Intel spec defines the format of messages for raising interrupts.  The PCI spec defines
445*bb4ee6a4SAndroid Build Coastguard Worker // three u32s -- the address, address_high, and data -- but Intel only makes use of the address and
446*bb4ee6a4SAndroid Build Coastguard Worker // data.  The Intel portion of the specification is in Volume 3 section 10.11.
447*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
448*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq)]
449*bb4ee6a4SAndroid Build Coastguard Worker pub struct MsiAddressMessage {
450*bb4ee6a4SAndroid Build Coastguard Worker     pub reserved: BitField2,
451*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
452*bb4ee6a4SAndroid Build Coastguard Worker     pub destination_mode: DestinationMode,
453*bb4ee6a4SAndroid Build Coastguard Worker     pub redirection_hint: BitField1,
454*bb4ee6a4SAndroid Build Coastguard Worker     pub reserved_2: BitField8,
455*bb4ee6a4SAndroid Build Coastguard Worker     pub destination_id: BitField8,
456*bb4ee6a4SAndroid Build Coastguard Worker     // According to Intel's implementation of MSI, these bits must always be 0xfee.
457*bb4ee6a4SAndroid Build Coastguard Worker     pub always_0xfee: BitField12,
458*bb4ee6a4SAndroid Build Coastguard Worker }
459*bb4ee6a4SAndroid Build Coastguard Worker 
460*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
461*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq)]
462*bb4ee6a4SAndroid Build Coastguard Worker pub struct MsiDataMessage {
463*bb4ee6a4SAndroid Build Coastguard Worker     pub vector: BitField8,
464*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 3]
465*bb4ee6a4SAndroid Build Coastguard Worker     pub delivery_mode: DeliveryMode,
466*bb4ee6a4SAndroid Build Coastguard Worker     pub reserved: BitField3,
467*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
468*bb4ee6a4SAndroid Build Coastguard Worker     pub level: Level,
469*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
470*bb4ee6a4SAndroid Build Coastguard Worker     pub trigger: TriggerMode,
471*bb4ee6a4SAndroid Build Coastguard Worker     pub reserved2: BitField16,
472*bb4ee6a4SAndroid Build Coastguard Worker }
473*bb4ee6a4SAndroid Build Coastguard Worker 
474*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
475*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq)]
476*bb4ee6a4SAndroid Build Coastguard Worker pub enum DeliveryStatus {
477*bb4ee6a4SAndroid Build Coastguard Worker     Idle = 0,
478*bb4ee6a4SAndroid Build Coastguard Worker     Pending = 1,
479*bb4ee6a4SAndroid Build Coastguard Worker }
480*bb4ee6a4SAndroid Build Coastguard Worker 
481*bb4ee6a4SAndroid Build Coastguard Worker /// The level of a level-triggered interrupt: asserted or deasserted.
482*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
483*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq)]
484*bb4ee6a4SAndroid Build Coastguard Worker pub enum Level {
485*bb4ee6a4SAndroid Build Coastguard Worker     Deassert = 0,
486*bb4ee6a4SAndroid Build Coastguard Worker     Assert = 1,
487*bb4ee6a4SAndroid Build Coastguard Worker }
488*bb4ee6a4SAndroid Build Coastguard Worker 
489*bb4ee6a4SAndroid Build Coastguard Worker /// Represents a IOAPIC redirection table entry.
490*bb4ee6a4SAndroid Build Coastguard Worker #[bitfield]
491*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
492*bb4ee6a4SAndroid Build Coastguard Worker pub struct IoapicRedirectionTableEntry {
493*bb4ee6a4SAndroid Build Coastguard Worker     vector: BitField8,
494*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 3]
495*bb4ee6a4SAndroid Build Coastguard Worker     delivery_mode: DeliveryMode,
496*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
497*bb4ee6a4SAndroid Build Coastguard Worker     dest_mode: DestinationMode,
498*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
499*bb4ee6a4SAndroid Build Coastguard Worker     delivery_status: DeliveryStatus,
500*bb4ee6a4SAndroid Build Coastguard Worker     polarity: BitField1,
501*bb4ee6a4SAndroid Build Coastguard Worker     remote_irr: bool,
502*bb4ee6a4SAndroid Build Coastguard Worker     #[bits = 1]
503*bb4ee6a4SAndroid Build Coastguard Worker     trigger_mode: TriggerMode,
504*bb4ee6a4SAndroid Build Coastguard Worker     interrupt_mask: bool, // true iff interrupts are masked.
505*bb4ee6a4SAndroid Build Coastguard Worker     reserved: BitField39,
506*bb4ee6a4SAndroid Build Coastguard Worker     dest_id: BitField8,
507*bb4ee6a4SAndroid Build Coastguard Worker }
508*bb4ee6a4SAndroid Build Coastguard Worker 
509*bb4ee6a4SAndroid Build Coastguard Worker /// Number of pins on the standard KVM/IOAPIC.
510*bb4ee6a4SAndroid Build Coastguard Worker pub const NUM_IOAPIC_PINS: usize = 24;
511*bb4ee6a4SAndroid Build Coastguard Worker 
512*bb4ee6a4SAndroid Build Coastguard Worker /// Represents the state of the IOAPIC.
513*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
514*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
515*bb4ee6a4SAndroid Build Coastguard Worker pub struct IoapicState {
516*bb4ee6a4SAndroid Build Coastguard Worker     /// base_address is the memory base address for this IOAPIC. It cannot be changed.
517*bb4ee6a4SAndroid Build Coastguard Worker     pub base_address: u64,
518*bb4ee6a4SAndroid Build Coastguard Worker     /// ioregsel register. Used for selecting which entry of the redirect table to read/write.
519*bb4ee6a4SAndroid Build Coastguard Worker     pub ioregsel: u8,
520*bb4ee6a4SAndroid Build Coastguard Worker     /// ioapicid register. Bits 24 - 27 contain the APIC ID for this device.
521*bb4ee6a4SAndroid Build Coastguard Worker     pub ioapicid: u32,
522*bb4ee6a4SAndroid Build Coastguard Worker     /// current_interrupt_level_bitmap represents a bitmap of the state of all of the irq lines
523*bb4ee6a4SAndroid Build Coastguard Worker     pub current_interrupt_level_bitmap: u32,
524*bb4ee6a4SAndroid Build Coastguard Worker     /// redirect_table contains the irq settings for each irq line
525*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(
526*bb4ee6a4SAndroid Build Coastguard Worker         serialize_with = "serialize_arr",
527*bb4ee6a4SAndroid Build Coastguard Worker         deserialize_with = "deserialize_seq_to_arr"
528*bb4ee6a4SAndroid Build Coastguard Worker     )]
529*bb4ee6a4SAndroid Build Coastguard Worker     pub redirect_table: [IoapicRedirectionTableEntry; NUM_IOAPIC_PINS],
530*bb4ee6a4SAndroid Build Coastguard Worker }
531*bb4ee6a4SAndroid Build Coastguard Worker 
532*bb4ee6a4SAndroid Build Coastguard Worker impl Default for IoapicState {
default() -> IoapicState533*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> IoapicState {
534*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: trivially safe
535*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { std::mem::zeroed() }
536*bb4ee6a4SAndroid Build Coastguard Worker     }
537*bb4ee6a4SAndroid Build Coastguard Worker }
538*bb4ee6a4SAndroid Build Coastguard Worker 
539*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
540*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq)]
541*bb4ee6a4SAndroid Build Coastguard Worker pub enum PicSelect {
542*bb4ee6a4SAndroid Build Coastguard Worker     Primary = 0,
543*bb4ee6a4SAndroid Build Coastguard Worker     Secondary = 1,
544*bb4ee6a4SAndroid Build Coastguard Worker }
545*bb4ee6a4SAndroid Build Coastguard Worker 
546*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
547*bb4ee6a4SAndroid Build Coastguard Worker #[derive(enumn::N, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
548*bb4ee6a4SAndroid Build Coastguard Worker pub enum PicInitState {
549*bb4ee6a4SAndroid Build Coastguard Worker     #[default]
550*bb4ee6a4SAndroid Build Coastguard Worker     Icw1 = 0,
551*bb4ee6a4SAndroid Build Coastguard Worker     Icw2 = 1,
552*bb4ee6a4SAndroid Build Coastguard Worker     Icw3 = 2,
553*bb4ee6a4SAndroid Build Coastguard Worker     Icw4 = 3,
554*bb4ee6a4SAndroid Build Coastguard Worker }
555*bb4ee6a4SAndroid Build Coastguard Worker 
556*bb4ee6a4SAndroid Build Coastguard Worker /// Convenience implementation for converting from a u8
557*bb4ee6a4SAndroid Build Coastguard Worker impl From<u8> for PicInitState {
from(item: u8) -> Self558*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: u8) -> Self {
559*bb4ee6a4SAndroid Build Coastguard Worker         PicInitState::n(item).unwrap_or_else(|| {
560*bb4ee6a4SAndroid Build Coastguard Worker             error!("Invalid PicInitState {}, setting to 0", item);
561*bb4ee6a4SAndroid Build Coastguard Worker             PicInitState::Icw1
562*bb4ee6a4SAndroid Build Coastguard Worker         })
563*bb4ee6a4SAndroid Build Coastguard Worker     }
564*bb4ee6a4SAndroid Build Coastguard Worker }
565*bb4ee6a4SAndroid Build Coastguard Worker 
566*bb4ee6a4SAndroid Build Coastguard Worker /// Represents the state of the PIC.
567*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
568*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
569*bb4ee6a4SAndroid Build Coastguard Worker pub struct PicState {
570*bb4ee6a4SAndroid Build Coastguard Worker     /// Edge detection.
571*bb4ee6a4SAndroid Build Coastguard Worker     pub last_irr: u8,
572*bb4ee6a4SAndroid Build Coastguard Worker     /// Interrupt Request Register.
573*bb4ee6a4SAndroid Build Coastguard Worker     pub irr: u8,
574*bb4ee6a4SAndroid Build Coastguard Worker     /// Interrupt Mask Register.
575*bb4ee6a4SAndroid Build Coastguard Worker     pub imr: u8,
576*bb4ee6a4SAndroid Build Coastguard Worker     /// Interrupt Service Register.
577*bb4ee6a4SAndroid Build Coastguard Worker     pub isr: u8,
578*bb4ee6a4SAndroid Build Coastguard Worker     /// Highest priority, for priority rotation.
579*bb4ee6a4SAndroid Build Coastguard Worker     pub priority_add: u8,
580*bb4ee6a4SAndroid Build Coastguard Worker     pub irq_base: u8,
581*bb4ee6a4SAndroid Build Coastguard Worker     pub read_reg_select: bool,
582*bb4ee6a4SAndroid Build Coastguard Worker     pub poll: bool,
583*bb4ee6a4SAndroid Build Coastguard Worker     pub special_mask: bool,
584*bb4ee6a4SAndroid Build Coastguard Worker     pub init_state: PicInitState,
585*bb4ee6a4SAndroid Build Coastguard Worker     pub auto_eoi: bool,
586*bb4ee6a4SAndroid Build Coastguard Worker     pub rotate_on_auto_eoi: bool,
587*bb4ee6a4SAndroid Build Coastguard Worker     pub special_fully_nested_mode: bool,
588*bb4ee6a4SAndroid Build Coastguard Worker     /// PIC takes either 3 or 4 bytes of initialization command word during
589*bb4ee6a4SAndroid Build Coastguard Worker     /// initialization. use_4_byte_icw is true if 4 bytes of ICW are needed.
590*bb4ee6a4SAndroid Build Coastguard Worker     pub use_4_byte_icw: bool,
591*bb4ee6a4SAndroid Build Coastguard Worker     /// "Edge/Level Control Registers", for edge trigger selection.
592*bb4ee6a4SAndroid Build Coastguard Worker     /// When a particular bit is set, the corresponding IRQ is in level-triggered mode. Otherwise
593*bb4ee6a4SAndroid Build Coastguard Worker     /// it is in edge-triggered mode.
594*bb4ee6a4SAndroid Build Coastguard Worker     pub elcr: u8,
595*bb4ee6a4SAndroid Build Coastguard Worker     pub elcr_mask: u8,
596*bb4ee6a4SAndroid Build Coastguard Worker }
597*bb4ee6a4SAndroid Build Coastguard Worker 
598*bb4ee6a4SAndroid Build Coastguard Worker /// The LapicState represents the state of an x86 CPU's Local APIC.
599*bb4ee6a4SAndroid Build Coastguard Worker /// The Local APIC consists of 64 128-bit registers, but only the first 32-bits of each register
600*bb4ee6a4SAndroid Build Coastguard Worker /// can be used, so this structure only stores the first 32-bits of each register.
601*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
602*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Serialize, Deserialize)]
603*bb4ee6a4SAndroid Build Coastguard Worker pub struct LapicState {
604*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(
605*bb4ee6a4SAndroid Build Coastguard Worker         serialize_with = "serialize_arr",
606*bb4ee6a4SAndroid Build Coastguard Worker         deserialize_with = "deserialize_seq_to_arr"
607*bb4ee6a4SAndroid Build Coastguard Worker     )]
608*bb4ee6a4SAndroid Build Coastguard Worker     pub regs: [LapicRegister; 64],
609*bb4ee6a4SAndroid Build Coastguard Worker }
610*bb4ee6a4SAndroid Build Coastguard Worker 
611*bb4ee6a4SAndroid Build Coastguard Worker pub type LapicRegister = u32;
612*bb4ee6a4SAndroid Build Coastguard Worker 
613*bb4ee6a4SAndroid Build Coastguard Worker // rust arrays longer than 32 need custom implementations of Debug
614*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Debug for LapicState {
fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result615*bb4ee6a4SAndroid Build Coastguard Worker     fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
616*bb4ee6a4SAndroid Build Coastguard Worker         self.regs[..].fmt(formatter)
617*bb4ee6a4SAndroid Build Coastguard Worker     }
618*bb4ee6a4SAndroid Build Coastguard Worker }
619*bb4ee6a4SAndroid Build Coastguard Worker 
620*bb4ee6a4SAndroid Build Coastguard Worker // rust arrays longer than 32 need custom implementations of PartialEq
621*bb4ee6a4SAndroid Build Coastguard Worker impl PartialEq for LapicState {
eq(&self, other: &LapicState) -> bool622*bb4ee6a4SAndroid Build Coastguard Worker     fn eq(&self, other: &LapicState) -> bool {
623*bb4ee6a4SAndroid Build Coastguard Worker         self.regs[..] == other.regs[..]
624*bb4ee6a4SAndroid Build Coastguard Worker     }
625*bb4ee6a4SAndroid Build Coastguard Worker }
626*bb4ee6a4SAndroid Build Coastguard Worker 
627*bb4ee6a4SAndroid Build Coastguard Worker // Lapic equality is reflexive, so we impl Eq
628*bb4ee6a4SAndroid Build Coastguard Worker impl Eq for LapicState {}
629*bb4ee6a4SAndroid Build Coastguard Worker 
630*bb4ee6a4SAndroid Build Coastguard Worker /// The PitState represents the state of the PIT (aka the Programmable Interval Timer).
631*bb4ee6a4SAndroid Build Coastguard Worker /// The state is simply the state of it's three channels.
632*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
633*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
634*bb4ee6a4SAndroid Build Coastguard Worker pub struct PitState {
635*bb4ee6a4SAndroid Build Coastguard Worker     pub channels: [PitChannelState; 3],
636*bb4ee6a4SAndroid Build Coastguard Worker     /// Hypervisor-specific flags for setting the pit state.
637*bb4ee6a4SAndroid Build Coastguard Worker     pub flags: u32,
638*bb4ee6a4SAndroid Build Coastguard Worker }
639*bb4ee6a4SAndroid Build Coastguard Worker 
640*bb4ee6a4SAndroid Build Coastguard Worker /// The PitRWMode enum represents the access mode of a PIT channel.
641*bb4ee6a4SAndroid Build Coastguard Worker /// Reads and writes to the Pit happen over Port-mapped I/O, which happens one byte at a time,
642*bb4ee6a4SAndroid Build Coastguard Worker /// but the count values and latch values are two bytes. So the access mode controls which of the
643*bb4ee6a4SAndroid Build Coastguard Worker /// two bytes will be read when.
644*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
645*bb4ee6a4SAndroid Build Coastguard Worker #[derive(enumn::N, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
646*bb4ee6a4SAndroid Build Coastguard Worker pub enum PitRWMode {
647*bb4ee6a4SAndroid Build Coastguard Worker     /// None mode means that no access mode has been set.
648*bb4ee6a4SAndroid Build Coastguard Worker     None = 0,
649*bb4ee6a4SAndroid Build Coastguard Worker     /// Least mode means all reads/writes will read/write the least significant byte.
650*bb4ee6a4SAndroid Build Coastguard Worker     Least = 1,
651*bb4ee6a4SAndroid Build Coastguard Worker     /// Most mode means all reads/writes will read/write the most significant byte.
652*bb4ee6a4SAndroid Build Coastguard Worker     Most = 2,
653*bb4ee6a4SAndroid Build Coastguard Worker     /// Both mode means first the least significant byte will be read/written, then the
654*bb4ee6a4SAndroid Build Coastguard Worker     /// next read/write will read/write the most significant byte.
655*bb4ee6a4SAndroid Build Coastguard Worker     Both = 3,
656*bb4ee6a4SAndroid Build Coastguard Worker }
657*bb4ee6a4SAndroid Build Coastguard Worker 
658*bb4ee6a4SAndroid Build Coastguard Worker /// Convenience implementation for converting from a u8
659*bb4ee6a4SAndroid Build Coastguard Worker impl From<u8> for PitRWMode {
from(item: u8) -> Self660*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: u8) -> Self {
661*bb4ee6a4SAndroid Build Coastguard Worker         PitRWMode::n(item).unwrap_or_else(|| {
662*bb4ee6a4SAndroid Build Coastguard Worker             error!("Invalid PitRWMode value {}, setting to 0", item);
663*bb4ee6a4SAndroid Build Coastguard Worker             PitRWMode::None
664*bb4ee6a4SAndroid Build Coastguard Worker         })
665*bb4ee6a4SAndroid Build Coastguard Worker     }
666*bb4ee6a4SAndroid Build Coastguard Worker }
667*bb4ee6a4SAndroid Build Coastguard Worker 
668*bb4ee6a4SAndroid Build Coastguard Worker /// The PitRWState enum represents the state of reading to or writing from a channel.
669*bb4ee6a4SAndroid Build Coastguard Worker /// This is related to the PitRWMode, it mainly gives more detail about the state of the channel
670*bb4ee6a4SAndroid Build Coastguard Worker /// with respect to PitRWMode::Both.
671*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
672*bb4ee6a4SAndroid Build Coastguard Worker #[derive(enumn::N, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
673*bb4ee6a4SAndroid Build Coastguard Worker pub enum PitRWState {
674*bb4ee6a4SAndroid Build Coastguard Worker     /// None mode means that no access mode has been set.
675*bb4ee6a4SAndroid Build Coastguard Worker     None = 0,
676*bb4ee6a4SAndroid Build Coastguard Worker     /// LSB means that the channel is in PitRWMode::Least access mode.
677*bb4ee6a4SAndroid Build Coastguard Worker     LSB = 1,
678*bb4ee6a4SAndroid Build Coastguard Worker     /// MSB means that the channel is in PitRWMode::Most access mode.
679*bb4ee6a4SAndroid Build Coastguard Worker     MSB = 2,
680*bb4ee6a4SAndroid Build Coastguard Worker     /// Word0 means that the channel is in PitRWMode::Both mode, and the least sginificant byte
681*bb4ee6a4SAndroid Build Coastguard Worker     /// has not been read/written yet.
682*bb4ee6a4SAndroid Build Coastguard Worker     Word0 = 3,
683*bb4ee6a4SAndroid Build Coastguard Worker     /// Word1 means that the channel is in PitRWMode::Both mode and the least significant byte
684*bb4ee6a4SAndroid Build Coastguard Worker     /// has already been read/written, and the next byte to be read/written will be the most
685*bb4ee6a4SAndroid Build Coastguard Worker     /// significant byte.
686*bb4ee6a4SAndroid Build Coastguard Worker     Word1 = 4,
687*bb4ee6a4SAndroid Build Coastguard Worker }
688*bb4ee6a4SAndroid Build Coastguard Worker 
689*bb4ee6a4SAndroid Build Coastguard Worker /// Convenience implementation for converting from a u8
690*bb4ee6a4SAndroid Build Coastguard Worker impl From<u8> for PitRWState {
from(item: u8) -> Self691*bb4ee6a4SAndroid Build Coastguard Worker     fn from(item: u8) -> Self {
692*bb4ee6a4SAndroid Build Coastguard Worker         PitRWState::n(item).unwrap_or_else(|| {
693*bb4ee6a4SAndroid Build Coastguard Worker             error!("Invalid PitRWState value {}, setting to 0", item);
694*bb4ee6a4SAndroid Build Coastguard Worker             PitRWState::None
695*bb4ee6a4SAndroid Build Coastguard Worker         })
696*bb4ee6a4SAndroid Build Coastguard Worker     }
697*bb4ee6a4SAndroid Build Coastguard Worker }
698*bb4ee6a4SAndroid Build Coastguard Worker 
699*bb4ee6a4SAndroid Build Coastguard Worker /// The PitChannelState represents the state of one of the PIT's three counters.
700*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
701*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
702*bb4ee6a4SAndroid Build Coastguard Worker pub struct PitChannelState {
703*bb4ee6a4SAndroid Build Coastguard Worker     /// The starting value for the counter.
704*bb4ee6a4SAndroid Build Coastguard Worker     pub count: u32,
705*bb4ee6a4SAndroid Build Coastguard Worker     /// Stores the channel count from the last time the count was latched.
706*bb4ee6a4SAndroid Build Coastguard Worker     pub latched_count: u16,
707*bb4ee6a4SAndroid Build Coastguard Worker     /// Indicates the PitRWState state of reading the latch value.
708*bb4ee6a4SAndroid Build Coastguard Worker     pub count_latched: PitRWState,
709*bb4ee6a4SAndroid Build Coastguard Worker     /// Indicates whether ReadBack status has been latched.
710*bb4ee6a4SAndroid Build Coastguard Worker     pub status_latched: bool,
711*bb4ee6a4SAndroid Build Coastguard Worker     /// Stores the channel status from the last time the status was latched. The status contains
712*bb4ee6a4SAndroid Build Coastguard Worker     /// information about the access mode of this channel, but changing those bits in the status
713*bb4ee6a4SAndroid Build Coastguard Worker     /// will not change the behavior of the pit.
714*bb4ee6a4SAndroid Build Coastguard Worker     pub status: u8,
715*bb4ee6a4SAndroid Build Coastguard Worker     /// Indicates the PitRWState state of reading the counter.
716*bb4ee6a4SAndroid Build Coastguard Worker     pub read_state: PitRWState,
717*bb4ee6a4SAndroid Build Coastguard Worker     /// Indicates the PitRWState state of writing the counter.
718*bb4ee6a4SAndroid Build Coastguard Worker     pub write_state: PitRWState,
719*bb4ee6a4SAndroid Build Coastguard Worker     /// Stores the value with which the counter was initialized. Counters are 16-
720*bb4ee6a4SAndroid Build Coastguard Worker     /// bit values with an effective range of 1-65536 (65536 represented by 0).
721*bb4ee6a4SAndroid Build Coastguard Worker     pub reload_value: u16,
722*bb4ee6a4SAndroid Build Coastguard Worker     /// The command access mode of this channel.
723*bb4ee6a4SAndroid Build Coastguard Worker     pub rw_mode: PitRWMode,
724*bb4ee6a4SAndroid Build Coastguard Worker     /// The operation mode of this channel.
725*bb4ee6a4SAndroid Build Coastguard Worker     pub mode: u8,
726*bb4ee6a4SAndroid Build Coastguard Worker     /// Whether or not we are in bcd mode. Not supported by KVM or crosvm's PIT implementation.
727*bb4ee6a4SAndroid Build Coastguard Worker     pub bcd: bool,
728*bb4ee6a4SAndroid Build Coastguard Worker     /// Value of the gate input pin. This only applies to channel 2.
729*bb4ee6a4SAndroid Build Coastguard Worker     pub gate: bool,
730*bb4ee6a4SAndroid Build Coastguard Worker     /// Nanosecond timestamp of when the count value was loaded.
731*bb4ee6a4SAndroid Build Coastguard Worker     pub count_load_time: u64,
732*bb4ee6a4SAndroid Build Coastguard Worker }
733*bb4ee6a4SAndroid Build Coastguard Worker 
734*bb4ee6a4SAndroid Build Coastguard Worker // Convenience constructors for IrqRoutes
735*bb4ee6a4SAndroid Build Coastguard Worker impl IrqRoute {
ioapic_irq_route(irq_num: u32) -> IrqRoute736*bb4ee6a4SAndroid Build Coastguard Worker     pub fn ioapic_irq_route(irq_num: u32) -> IrqRoute {
737*bb4ee6a4SAndroid Build Coastguard Worker         IrqRoute {
738*bb4ee6a4SAndroid Build Coastguard Worker             gsi: irq_num,
739*bb4ee6a4SAndroid Build Coastguard Worker             source: IrqSource::Irqchip {
740*bb4ee6a4SAndroid Build Coastguard Worker                 chip: IrqSourceChip::Ioapic,
741*bb4ee6a4SAndroid Build Coastguard Worker                 pin: irq_num,
742*bb4ee6a4SAndroid Build Coastguard Worker             },
743*bb4ee6a4SAndroid Build Coastguard Worker         }
744*bb4ee6a4SAndroid Build Coastguard Worker     }
745*bb4ee6a4SAndroid Build Coastguard Worker 
pic_irq_route(id: IrqSourceChip, irq_num: u32) -> IrqRoute746*bb4ee6a4SAndroid Build Coastguard Worker     pub fn pic_irq_route(id: IrqSourceChip, irq_num: u32) -> IrqRoute {
747*bb4ee6a4SAndroid Build Coastguard Worker         IrqRoute {
748*bb4ee6a4SAndroid Build Coastguard Worker             gsi: irq_num,
749*bb4ee6a4SAndroid Build Coastguard Worker             source: IrqSource::Irqchip {
750*bb4ee6a4SAndroid Build Coastguard Worker                 chip: id,
751*bb4ee6a4SAndroid Build Coastguard Worker                 pin: irq_num % 8,
752*bb4ee6a4SAndroid Build Coastguard Worker             },
753*bb4ee6a4SAndroid Build Coastguard Worker         }
754*bb4ee6a4SAndroid Build Coastguard Worker     }
755*bb4ee6a4SAndroid Build Coastguard Worker }
756*bb4ee6a4SAndroid Build Coastguard Worker 
757*bb4ee6a4SAndroid Build Coastguard Worker /// State of a VCPU's general purpose registers.
758*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
759*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
760*bb4ee6a4SAndroid Build Coastguard Worker pub struct Regs {
761*bb4ee6a4SAndroid Build Coastguard Worker     pub rax: u64,
762*bb4ee6a4SAndroid Build Coastguard Worker     pub rbx: u64,
763*bb4ee6a4SAndroid Build Coastguard Worker     pub rcx: u64,
764*bb4ee6a4SAndroid Build Coastguard Worker     pub rdx: u64,
765*bb4ee6a4SAndroid Build Coastguard Worker     pub rsi: u64,
766*bb4ee6a4SAndroid Build Coastguard Worker     pub rdi: u64,
767*bb4ee6a4SAndroid Build Coastguard Worker     pub rsp: u64,
768*bb4ee6a4SAndroid Build Coastguard Worker     pub rbp: u64,
769*bb4ee6a4SAndroid Build Coastguard Worker     pub r8: u64,
770*bb4ee6a4SAndroid Build Coastguard Worker     pub r9: u64,
771*bb4ee6a4SAndroid Build Coastguard Worker     pub r10: u64,
772*bb4ee6a4SAndroid Build Coastguard Worker     pub r11: u64,
773*bb4ee6a4SAndroid Build Coastguard Worker     pub r12: u64,
774*bb4ee6a4SAndroid Build Coastguard Worker     pub r13: u64,
775*bb4ee6a4SAndroid Build Coastguard Worker     pub r14: u64,
776*bb4ee6a4SAndroid Build Coastguard Worker     pub r15: u64,
777*bb4ee6a4SAndroid Build Coastguard Worker     pub rip: u64,
778*bb4ee6a4SAndroid Build Coastguard Worker     pub rflags: u64,
779*bb4ee6a4SAndroid Build Coastguard Worker }
780*bb4ee6a4SAndroid Build Coastguard Worker 
781*bb4ee6a4SAndroid Build Coastguard Worker impl Default for Regs {
default() -> Self782*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
783*bb4ee6a4SAndroid Build Coastguard Worker         Regs {
784*bb4ee6a4SAndroid Build Coastguard Worker             rax: 0,
785*bb4ee6a4SAndroid Build Coastguard Worker             rbx: 0,
786*bb4ee6a4SAndroid Build Coastguard Worker             rcx: 0,
787*bb4ee6a4SAndroid Build Coastguard Worker             rdx: 0,
788*bb4ee6a4SAndroid Build Coastguard Worker             rsi: 0,
789*bb4ee6a4SAndroid Build Coastguard Worker             rdi: 0,
790*bb4ee6a4SAndroid Build Coastguard Worker             rsp: 0,
791*bb4ee6a4SAndroid Build Coastguard Worker             rbp: 0,
792*bb4ee6a4SAndroid Build Coastguard Worker             r8: 0,
793*bb4ee6a4SAndroid Build Coastguard Worker             r9: 0,
794*bb4ee6a4SAndroid Build Coastguard Worker             r10: 0,
795*bb4ee6a4SAndroid Build Coastguard Worker             r11: 0,
796*bb4ee6a4SAndroid Build Coastguard Worker             r12: 0,
797*bb4ee6a4SAndroid Build Coastguard Worker             r13: 0,
798*bb4ee6a4SAndroid Build Coastguard Worker             r14: 0,
799*bb4ee6a4SAndroid Build Coastguard Worker             r15: 0,
800*bb4ee6a4SAndroid Build Coastguard Worker             rip: 0xfff0, // Reset vector.
801*bb4ee6a4SAndroid Build Coastguard Worker             rflags: 0x2, // Bit 1 (0x2) is always 1.
802*bb4ee6a4SAndroid Build Coastguard Worker         }
803*bb4ee6a4SAndroid Build Coastguard Worker     }
804*bb4ee6a4SAndroid Build Coastguard Worker }
805*bb4ee6a4SAndroid Build Coastguard Worker 
806*bb4ee6a4SAndroid Build Coastguard Worker /// State of a memory segment.
807*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
808*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
809*bb4ee6a4SAndroid Build Coastguard Worker pub struct Segment {
810*bb4ee6a4SAndroid Build Coastguard Worker     pub base: u64,
811*bb4ee6a4SAndroid Build Coastguard Worker     /// Limit of the segment - always in bytes, regardless of granularity (`g`) field.
812*bb4ee6a4SAndroid Build Coastguard Worker     pub limit_bytes: u32,
813*bb4ee6a4SAndroid Build Coastguard Worker     pub selector: u16,
814*bb4ee6a4SAndroid Build Coastguard Worker     pub type_: u8,
815*bb4ee6a4SAndroid Build Coastguard Worker     pub present: u8,
816*bb4ee6a4SAndroid Build Coastguard Worker     pub dpl: u8,
817*bb4ee6a4SAndroid Build Coastguard Worker     pub db: u8,
818*bb4ee6a4SAndroid Build Coastguard Worker     pub s: u8,
819*bb4ee6a4SAndroid Build Coastguard Worker     pub l: u8,
820*bb4ee6a4SAndroid Build Coastguard Worker     pub g: u8,
821*bb4ee6a4SAndroid Build Coastguard Worker     pub avl: u8,
822*bb4ee6a4SAndroid Build Coastguard Worker }
823*bb4ee6a4SAndroid Build Coastguard Worker 
824*bb4ee6a4SAndroid Build Coastguard Worker /// State of a global descriptor table or interrupt descriptor table.
825*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
826*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
827*bb4ee6a4SAndroid Build Coastguard Worker pub struct DescriptorTable {
828*bb4ee6a4SAndroid Build Coastguard Worker     pub base: u64,
829*bb4ee6a4SAndroid Build Coastguard Worker     pub limit: u16,
830*bb4ee6a4SAndroid Build Coastguard Worker }
831*bb4ee6a4SAndroid Build Coastguard Worker 
832*bb4ee6a4SAndroid Build Coastguard Worker /// State of a VCPU's special registers.
833*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
834*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
835*bb4ee6a4SAndroid Build Coastguard Worker pub struct Sregs {
836*bb4ee6a4SAndroid Build Coastguard Worker     pub cs: Segment,
837*bb4ee6a4SAndroid Build Coastguard Worker     pub ds: Segment,
838*bb4ee6a4SAndroid Build Coastguard Worker     pub es: Segment,
839*bb4ee6a4SAndroid Build Coastguard Worker     pub fs: Segment,
840*bb4ee6a4SAndroid Build Coastguard Worker     pub gs: Segment,
841*bb4ee6a4SAndroid Build Coastguard Worker     pub ss: Segment,
842*bb4ee6a4SAndroid Build Coastguard Worker     pub tr: Segment,
843*bb4ee6a4SAndroid Build Coastguard Worker     pub ldt: Segment,
844*bb4ee6a4SAndroid Build Coastguard Worker     pub gdt: DescriptorTable,
845*bb4ee6a4SAndroid Build Coastguard Worker     pub idt: DescriptorTable,
846*bb4ee6a4SAndroid Build Coastguard Worker     pub cr0: u64,
847*bb4ee6a4SAndroid Build Coastguard Worker     pub cr2: u64,
848*bb4ee6a4SAndroid Build Coastguard Worker     pub cr3: u64,
849*bb4ee6a4SAndroid Build Coastguard Worker     pub cr4: u64,
850*bb4ee6a4SAndroid Build Coastguard Worker     pub cr8: u64,
851*bb4ee6a4SAndroid Build Coastguard Worker     pub efer: u64,
852*bb4ee6a4SAndroid Build Coastguard Worker }
853*bb4ee6a4SAndroid Build Coastguard Worker 
854*bb4ee6a4SAndroid Build Coastguard Worker impl Default for Sregs {
default() -> Self855*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
856*bb4ee6a4SAndroid Build Coastguard Worker         // Intel SDM Vol. 3A, 3.4.5.1 ("Code- and Data-Segment Descriptor Types")
857*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_TYPE_DATA: u8 = 0b0000;
858*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_TYPE_DATA_WRITABLE: u8 = 0b0010;
859*bb4ee6a4SAndroid Build Coastguard Worker 
860*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_TYPE_CODE: u8 = 0b1000;
861*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_TYPE_CODE_READABLE: u8 = 0b0010;
862*bb4ee6a4SAndroid Build Coastguard Worker 
863*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_TYPE_ACCESSED: u8 = 0b0001;
864*bb4ee6a4SAndroid Build Coastguard Worker 
865*bb4ee6a4SAndroid Build Coastguard Worker         // Intel SDM Vol. 3A, 3.4.5 ("Segment Descriptors")
866*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_S_SYSTEM: u8 = 0; // System segment.
867*bb4ee6a4SAndroid Build Coastguard Worker         const SEG_S_CODE_OR_DATA: u8 = 1; // Data/code segment.
868*bb4ee6a4SAndroid Build Coastguard Worker 
869*bb4ee6a4SAndroid Build Coastguard Worker         // 16-bit real-mode code segment (reset vector).
870*bb4ee6a4SAndroid Build Coastguard Worker         let code_seg = Segment {
871*bb4ee6a4SAndroid Build Coastguard Worker             base: 0xffff0000,
872*bb4ee6a4SAndroid Build Coastguard Worker             limit_bytes: 0xffff,
873*bb4ee6a4SAndroid Build Coastguard Worker             selector: 0xf000,
874*bb4ee6a4SAndroid Build Coastguard Worker             type_: SEG_TYPE_CODE | SEG_TYPE_CODE_READABLE | SEG_TYPE_ACCESSED, // 11
875*bb4ee6a4SAndroid Build Coastguard Worker             present: 1,
876*bb4ee6a4SAndroid Build Coastguard Worker             s: SEG_S_CODE_OR_DATA,
877*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
878*bb4ee6a4SAndroid Build Coastguard Worker         };
879*bb4ee6a4SAndroid Build Coastguard Worker 
880*bb4ee6a4SAndroid Build Coastguard Worker         // 16-bit real-mode data segment.
881*bb4ee6a4SAndroid Build Coastguard Worker         let data_seg = Segment {
882*bb4ee6a4SAndroid Build Coastguard Worker             base: 0,
883*bb4ee6a4SAndroid Build Coastguard Worker             limit_bytes: 0xffff,
884*bb4ee6a4SAndroid Build Coastguard Worker             selector: 0,
885*bb4ee6a4SAndroid Build Coastguard Worker             type_: SEG_TYPE_DATA | SEG_TYPE_DATA_WRITABLE | SEG_TYPE_ACCESSED, // 3
886*bb4ee6a4SAndroid Build Coastguard Worker             present: 1,
887*bb4ee6a4SAndroid Build Coastguard Worker             s: SEG_S_CODE_OR_DATA,
888*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
889*bb4ee6a4SAndroid Build Coastguard Worker         };
890*bb4ee6a4SAndroid Build Coastguard Worker 
891*bb4ee6a4SAndroid Build Coastguard Worker         // 16-bit TSS segment.
892*bb4ee6a4SAndroid Build Coastguard Worker         let task_seg = Segment {
893*bb4ee6a4SAndroid Build Coastguard Worker             base: 0,
894*bb4ee6a4SAndroid Build Coastguard Worker             limit_bytes: 0xffff,
895*bb4ee6a4SAndroid Build Coastguard Worker             selector: 0,
896*bb4ee6a4SAndroid Build Coastguard Worker             type_: SEG_TYPE_CODE | SEG_TYPE_CODE_READABLE | SEG_TYPE_ACCESSED, // 11
897*bb4ee6a4SAndroid Build Coastguard Worker             present: 1,
898*bb4ee6a4SAndroid Build Coastguard Worker             s: SEG_S_SYSTEM,
899*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
900*bb4ee6a4SAndroid Build Coastguard Worker         };
901*bb4ee6a4SAndroid Build Coastguard Worker 
902*bb4ee6a4SAndroid Build Coastguard Worker         // Local descriptor table.
903*bb4ee6a4SAndroid Build Coastguard Worker         let ldt = Segment {
904*bb4ee6a4SAndroid Build Coastguard Worker             base: 0,
905*bb4ee6a4SAndroid Build Coastguard Worker             limit_bytes: 0xffff,
906*bb4ee6a4SAndroid Build Coastguard Worker             selector: 0,
907*bb4ee6a4SAndroid Build Coastguard Worker             type_: SEG_TYPE_DATA | SEG_TYPE_DATA_WRITABLE, // 2
908*bb4ee6a4SAndroid Build Coastguard Worker             present: 1,
909*bb4ee6a4SAndroid Build Coastguard Worker             s: SEG_S_SYSTEM,
910*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
911*bb4ee6a4SAndroid Build Coastguard Worker         };
912*bb4ee6a4SAndroid Build Coastguard Worker 
913*bb4ee6a4SAndroid Build Coastguard Worker         // Global descriptor table.
914*bb4ee6a4SAndroid Build Coastguard Worker         let gdt = DescriptorTable {
915*bb4ee6a4SAndroid Build Coastguard Worker             base: 0,
916*bb4ee6a4SAndroid Build Coastguard Worker             limit: 0xffff,
917*bb4ee6a4SAndroid Build Coastguard Worker         };
918*bb4ee6a4SAndroid Build Coastguard Worker 
919*bb4ee6a4SAndroid Build Coastguard Worker         // Interrupt descriptor table.
920*bb4ee6a4SAndroid Build Coastguard Worker         let idt = DescriptorTable {
921*bb4ee6a4SAndroid Build Coastguard Worker             base: 0,
922*bb4ee6a4SAndroid Build Coastguard Worker             limit: 0xffff,
923*bb4ee6a4SAndroid Build Coastguard Worker         };
924*bb4ee6a4SAndroid Build Coastguard Worker 
925*bb4ee6a4SAndroid Build Coastguard Worker         let cr0 = (1 << 4) // CR0.ET (reserved, always 1)
926*bb4ee6a4SAndroid Build Coastguard Worker                 | (1 << 30); // CR0.CD (cache disable)
927*bb4ee6a4SAndroid Build Coastguard Worker 
928*bb4ee6a4SAndroid Build Coastguard Worker         Sregs {
929*bb4ee6a4SAndroid Build Coastguard Worker             cs: code_seg,
930*bb4ee6a4SAndroid Build Coastguard Worker             ds: data_seg,
931*bb4ee6a4SAndroid Build Coastguard Worker             es: data_seg,
932*bb4ee6a4SAndroid Build Coastguard Worker             fs: data_seg,
933*bb4ee6a4SAndroid Build Coastguard Worker             gs: data_seg,
934*bb4ee6a4SAndroid Build Coastguard Worker             ss: data_seg,
935*bb4ee6a4SAndroid Build Coastguard Worker             tr: task_seg,
936*bb4ee6a4SAndroid Build Coastguard Worker             ldt,
937*bb4ee6a4SAndroid Build Coastguard Worker             gdt,
938*bb4ee6a4SAndroid Build Coastguard Worker             idt,
939*bb4ee6a4SAndroid Build Coastguard Worker             cr0,
940*bb4ee6a4SAndroid Build Coastguard Worker             cr2: 0,
941*bb4ee6a4SAndroid Build Coastguard Worker             cr3: 0,
942*bb4ee6a4SAndroid Build Coastguard Worker             cr4: 0,
943*bb4ee6a4SAndroid Build Coastguard Worker             cr8: 0,
944*bb4ee6a4SAndroid Build Coastguard Worker             efer: 0,
945*bb4ee6a4SAndroid Build Coastguard Worker         }
946*bb4ee6a4SAndroid Build Coastguard Worker     }
947*bb4ee6a4SAndroid Build Coastguard Worker }
948*bb4ee6a4SAndroid Build Coastguard Worker 
949*bb4ee6a4SAndroid Build Coastguard Worker /// x87 80-bit floating point value.
950*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
951*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
952*bb4ee6a4SAndroid Build Coastguard Worker pub struct FpuReg {
953*bb4ee6a4SAndroid Build Coastguard Worker     /// 64-bit mantissa.
954*bb4ee6a4SAndroid Build Coastguard Worker     pub significand: u64,
955*bb4ee6a4SAndroid Build Coastguard Worker 
956*bb4ee6a4SAndroid Build Coastguard Worker     /// 15-bit biased exponent and sign bit.
957*bb4ee6a4SAndroid Build Coastguard Worker     pub sign_exp: u16,
958*bb4ee6a4SAndroid Build Coastguard Worker }
959*bb4ee6a4SAndroid Build Coastguard Worker 
960*bb4ee6a4SAndroid Build Coastguard Worker impl FpuReg {
961*bb4ee6a4SAndroid Build Coastguard Worker     /// Convert an array of 8x16-byte arrays to an array of 8 `FpuReg`.
962*bb4ee6a4SAndroid Build Coastguard Worker     ///
963*bb4ee6a4SAndroid Build Coastguard Worker     /// Ignores any data in the upper 6 bytes of each element; the values represent 80-bit FPU
964*bb4ee6a4SAndroid Build Coastguard Worker     /// registers, so the upper 48 bits are unused.
from_16byte_arrays(byte_arrays: &[[u8; 16]; 8]) -> [FpuReg; 8]965*bb4ee6a4SAndroid Build Coastguard Worker     pub fn from_16byte_arrays(byte_arrays: &[[u8; 16]; 8]) -> [FpuReg; 8] {
966*bb4ee6a4SAndroid Build Coastguard Worker         let mut regs = [FpuReg::default(); 8];
967*bb4ee6a4SAndroid Build Coastguard Worker         for (dst, src) in regs.iter_mut().zip(byte_arrays.iter()) {
968*bb4ee6a4SAndroid Build Coastguard Worker             let tbyte: [u8; 10] = src[0..10].try_into().unwrap();
969*bb4ee6a4SAndroid Build Coastguard Worker             *dst = FpuReg::from(tbyte);
970*bb4ee6a4SAndroid Build Coastguard Worker         }
971*bb4ee6a4SAndroid Build Coastguard Worker         regs
972*bb4ee6a4SAndroid Build Coastguard Worker     }
973*bb4ee6a4SAndroid Build Coastguard Worker 
974*bb4ee6a4SAndroid Build Coastguard Worker     /// Convert an array of 8 `FpuReg` into 8x16-byte arrays.
to_16byte_arrays(regs: &[FpuReg; 8]) -> [[u8; 16]; 8]975*bb4ee6a4SAndroid Build Coastguard Worker     pub fn to_16byte_arrays(regs: &[FpuReg; 8]) -> [[u8; 16]; 8] {
976*bb4ee6a4SAndroid Build Coastguard Worker         let mut byte_arrays = [[0u8; 16]; 8];
977*bb4ee6a4SAndroid Build Coastguard Worker         for (dst, src) in byte_arrays.iter_mut().zip(regs.iter()) {
978*bb4ee6a4SAndroid Build Coastguard Worker             *dst = (*src).into();
979*bb4ee6a4SAndroid Build Coastguard Worker         }
980*bb4ee6a4SAndroid Build Coastguard Worker         byte_arrays
981*bb4ee6a4SAndroid Build Coastguard Worker     }
982*bb4ee6a4SAndroid Build Coastguard Worker }
983*bb4ee6a4SAndroid Build Coastguard Worker 
984*bb4ee6a4SAndroid Build Coastguard Worker impl From<[u8; 10]> for FpuReg {
985*bb4ee6a4SAndroid Build Coastguard Worker     /// Construct a `FpuReg` from an 80-bit representation.
from(value: [u8; 10]) -> FpuReg986*bb4ee6a4SAndroid Build Coastguard Worker     fn from(value: [u8; 10]) -> FpuReg {
987*bb4ee6a4SAndroid Build Coastguard Worker         // These array sub-slices can't fail, but there's no (safe) way to express that in Rust
988*bb4ee6a4SAndroid Build Coastguard Worker         // without an `unwrap()`.
989*bb4ee6a4SAndroid Build Coastguard Worker         let significand_bytes = value[0..8].try_into().unwrap();
990*bb4ee6a4SAndroid Build Coastguard Worker         let significand = u64::from_le_bytes(significand_bytes);
991*bb4ee6a4SAndroid Build Coastguard Worker         let sign_exp_bytes = value[8..10].try_into().unwrap();
992*bb4ee6a4SAndroid Build Coastguard Worker         let sign_exp = u16::from_le_bytes(sign_exp_bytes);
993*bb4ee6a4SAndroid Build Coastguard Worker         FpuReg {
994*bb4ee6a4SAndroid Build Coastguard Worker             significand,
995*bb4ee6a4SAndroid Build Coastguard Worker             sign_exp,
996*bb4ee6a4SAndroid Build Coastguard Worker         }
997*bb4ee6a4SAndroid Build Coastguard Worker     }
998*bb4ee6a4SAndroid Build Coastguard Worker }
999*bb4ee6a4SAndroid Build Coastguard Worker 
1000*bb4ee6a4SAndroid Build Coastguard Worker impl From<FpuReg> for [u8; 10] {
1001*bb4ee6a4SAndroid Build Coastguard Worker     /// Convert an `FpuReg` into its 80-bit "TBYTE" representation.
from(value: FpuReg) -> [u8; 10]1002*bb4ee6a4SAndroid Build Coastguard Worker     fn from(value: FpuReg) -> [u8; 10] {
1003*bb4ee6a4SAndroid Build Coastguard Worker         let mut bytes = [0u8; 10];
1004*bb4ee6a4SAndroid Build Coastguard Worker         bytes[0..8].copy_from_slice(&value.significand.to_le_bytes());
1005*bb4ee6a4SAndroid Build Coastguard Worker         bytes[8..10].copy_from_slice(&value.sign_exp.to_le_bytes());
1006*bb4ee6a4SAndroid Build Coastguard Worker         bytes
1007*bb4ee6a4SAndroid Build Coastguard Worker     }
1008*bb4ee6a4SAndroid Build Coastguard Worker }
1009*bb4ee6a4SAndroid Build Coastguard Worker 
1010*bb4ee6a4SAndroid Build Coastguard Worker impl From<FpuReg> for [u8; 16] {
1011*bb4ee6a4SAndroid Build Coastguard Worker     /// Convert an `FpuReg` into its 80-bit representation plus 6 unused upper bytes.
1012*bb4ee6a4SAndroid Build Coastguard Worker     /// This is a convenience function for converting to hypervisor types.
from(value: FpuReg) -> [u8; 16]1013*bb4ee6a4SAndroid Build Coastguard Worker     fn from(value: FpuReg) -> [u8; 16] {
1014*bb4ee6a4SAndroid Build Coastguard Worker         let mut bytes = [0u8; 16];
1015*bb4ee6a4SAndroid Build Coastguard Worker         bytes[0..8].copy_from_slice(&value.significand.to_le_bytes());
1016*bb4ee6a4SAndroid Build Coastguard Worker         bytes[8..10].copy_from_slice(&value.sign_exp.to_le_bytes());
1017*bb4ee6a4SAndroid Build Coastguard Worker         bytes
1018*bb4ee6a4SAndroid Build Coastguard Worker     }
1019*bb4ee6a4SAndroid Build Coastguard Worker }
1020*bb4ee6a4SAndroid Build Coastguard Worker 
1021*bb4ee6a4SAndroid Build Coastguard Worker /// State of a VCPU's floating point unit.
1022*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
1023*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
1024*bb4ee6a4SAndroid Build Coastguard Worker pub struct Fpu {
1025*bb4ee6a4SAndroid Build Coastguard Worker     pub fpr: [FpuReg; 8],
1026*bb4ee6a4SAndroid Build Coastguard Worker     pub fcw: u16,
1027*bb4ee6a4SAndroid Build Coastguard Worker     pub fsw: u16,
1028*bb4ee6a4SAndroid Build Coastguard Worker     pub ftwx: u8,
1029*bb4ee6a4SAndroid Build Coastguard Worker     pub last_opcode: u16,
1030*bb4ee6a4SAndroid Build Coastguard Worker     pub last_ip: u64,
1031*bb4ee6a4SAndroid Build Coastguard Worker     pub last_dp: u64,
1032*bb4ee6a4SAndroid Build Coastguard Worker     pub xmm: [[u8; 16usize]; 16usize],
1033*bb4ee6a4SAndroid Build Coastguard Worker     pub mxcsr: u32,
1034*bb4ee6a4SAndroid Build Coastguard Worker }
1035*bb4ee6a4SAndroid Build Coastguard Worker 
1036*bb4ee6a4SAndroid Build Coastguard Worker impl Default for Fpu {
default() -> Self1037*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
1038*bb4ee6a4SAndroid Build Coastguard Worker         Fpu {
1039*bb4ee6a4SAndroid Build Coastguard Worker             fpr: Default::default(),
1040*bb4ee6a4SAndroid Build Coastguard Worker             fcw: 0x37f, // Intel SDM Vol. 1, 13.6
1041*bb4ee6a4SAndroid Build Coastguard Worker             fsw: 0,
1042*bb4ee6a4SAndroid Build Coastguard Worker             ftwx: 0,
1043*bb4ee6a4SAndroid Build Coastguard Worker             last_opcode: 0,
1044*bb4ee6a4SAndroid Build Coastguard Worker             last_ip: 0,
1045*bb4ee6a4SAndroid Build Coastguard Worker             last_dp: 0,
1046*bb4ee6a4SAndroid Build Coastguard Worker             xmm: Default::default(),
1047*bb4ee6a4SAndroid Build Coastguard Worker             mxcsr: 0x1f80, // Intel SDM Vol. 1, 11.6.4
1048*bb4ee6a4SAndroid Build Coastguard Worker         }
1049*bb4ee6a4SAndroid Build Coastguard Worker     }
1050*bb4ee6a4SAndroid Build Coastguard Worker }
1051*bb4ee6a4SAndroid Build Coastguard Worker 
1052*bb4ee6a4SAndroid Build Coastguard Worker /// State of a VCPU's debug registers.
1053*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
1054*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
1055*bb4ee6a4SAndroid Build Coastguard Worker pub struct DebugRegs {
1056*bb4ee6a4SAndroid Build Coastguard Worker     pub db: [u64; 4usize],
1057*bb4ee6a4SAndroid Build Coastguard Worker     pub dr6: u64,
1058*bb4ee6a4SAndroid Build Coastguard Worker     pub dr7: u64,
1059*bb4ee6a4SAndroid Build Coastguard Worker }
1060*bb4ee6a4SAndroid Build Coastguard Worker 
1061*bb4ee6a4SAndroid Build Coastguard Worker /// The hybrid type for intel hybrid CPU.
1062*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
1063*bb4ee6a4SAndroid Build Coastguard Worker pub enum CpuHybridType {
1064*bb4ee6a4SAndroid Build Coastguard Worker     /// Intel Atom.
1065*bb4ee6a4SAndroid Build Coastguard Worker     Atom,
1066*bb4ee6a4SAndroid Build Coastguard Worker     /// Intel Core.
1067*bb4ee6a4SAndroid Build Coastguard Worker     Core,
1068*bb4ee6a4SAndroid Build Coastguard Worker }
1069*bb4ee6a4SAndroid Build Coastguard Worker 
1070*bb4ee6a4SAndroid Build Coastguard Worker /// State of the VCPU's x87 FPU, MMX, XMM, YMM registers.
1071*bb4ee6a4SAndroid Build Coastguard Worker /// May contain more state depending on enabled extensions.
1072*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Serialize, Deserialize)]
1073*bb4ee6a4SAndroid Build Coastguard Worker pub struct Xsave {
1074*bb4ee6a4SAndroid Build Coastguard Worker     data: Vec<u32>,
1075*bb4ee6a4SAndroid Build Coastguard Worker 
1076*bb4ee6a4SAndroid Build Coastguard Worker     // Actual length in bytes. May be smaller than data if a non-u32 multiple of bytes is
1077*bb4ee6a4SAndroid Build Coastguard Worker     // requested.
1078*bb4ee6a4SAndroid Build Coastguard Worker     len: usize,
1079*bb4ee6a4SAndroid Build Coastguard Worker }
1080*bb4ee6a4SAndroid Build Coastguard Worker 
1081*bb4ee6a4SAndroid Build Coastguard Worker impl Xsave {
1082*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a new buffer to store Xsave data.
1083*bb4ee6a4SAndroid Build Coastguard Worker     ///
1084*bb4ee6a4SAndroid Build Coastguard Worker     /// # Argments
1085*bb4ee6a4SAndroid Build Coastguard Worker     /// * `len` size in bytes.
new(len: usize) -> Self1086*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(len: usize) -> Self {
1087*bb4ee6a4SAndroid Build Coastguard Worker         Xsave {
1088*bb4ee6a4SAndroid Build Coastguard Worker             data: vec![0; (len + 3) / 4],
1089*bb4ee6a4SAndroid Build Coastguard Worker             len,
1090*bb4ee6a4SAndroid Build Coastguard Worker         }
1091*bb4ee6a4SAndroid Build Coastguard Worker     }
1092*bb4ee6a4SAndroid Build Coastguard Worker 
as_ptr(&self) -> *const c_void1093*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_ptr(&self) -> *const c_void {
1094*bb4ee6a4SAndroid Build Coastguard Worker         self.data.as_ptr() as *const c_void
1095*bb4ee6a4SAndroid Build Coastguard Worker     }
1096*bb4ee6a4SAndroid Build Coastguard Worker 
as_mut_ptr(&mut self) -> *mut c_void1097*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_mut_ptr(&mut self) -> *mut c_void {
1098*bb4ee6a4SAndroid Build Coastguard Worker         self.data.as_mut_ptr() as *mut c_void
1099*bb4ee6a4SAndroid Build Coastguard Worker     }
1100*bb4ee6a4SAndroid Build Coastguard Worker 
1101*bb4ee6a4SAndroid Build Coastguard Worker     /// Length in bytes of the XSAVE data.
len(&self) -> usize1102*bb4ee6a4SAndroid Build Coastguard Worker     pub fn len(&self) -> usize {
1103*bb4ee6a4SAndroid Build Coastguard Worker         self.len
1104*bb4ee6a4SAndroid Build Coastguard Worker     }
1105*bb4ee6a4SAndroid Build Coastguard Worker 
1106*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns true is length of XSAVE data is zero
is_empty(&self) -> bool1107*bb4ee6a4SAndroid Build Coastguard Worker     pub fn is_empty(&self) -> bool {
1108*bb4ee6a4SAndroid Build Coastguard Worker         self.len() == 0
1109*bb4ee6a4SAndroid Build Coastguard Worker     }
1110*bb4ee6a4SAndroid Build Coastguard Worker }
1111