1 // Copyright © 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 // Copyright © 2020, Microsoft Corporation 6 // 7 // Copyright 2018-2019 CrowdStrike, Inc. 8 // 9 // SPDX-License-Identifier: Apache-2.0 OR MIT 10 11 #[cfg(target_arch = "aarch64")] 12 use crate::aarch64::VcpuInit; 13 #[cfg(target_arch = "x86_64")] 14 pub use crate::x86_64::{CpuId, ExtendedControlRegisters, LapicState, MsrEntries, Xsave}; 15 use crate::{FpuState, MpState, SpecialRegisters, StandardRegisters, VcpuEvents, VcpuExit}; 16 use thiserror::Error; 17 use vmm_sys_util::errno::Error as RunError; 18 19 pub struct CpuState {} 20 21 #[derive(Error, Debug)] 22 /// 23 /// Enum for CPU error 24 pub enum HypervisorCpuError { 25 /// 26 /// Setting standard registers error 27 /// 28 #[error("Failed to set standard register: {0}")] 29 SetStandardRegs(#[source] anyhow::Error), 30 /// 31 /// Setting standard registers error 32 /// 33 #[error("Failed to get standard registers: {0}")] 34 GetStandardRegs(#[source] anyhow::Error), 35 /// 36 /// Setting special register error 37 /// 38 #[error("Failed to set special registers: {0}")] 39 SetSpecialRegs(#[source] anyhow::Error), 40 /// 41 /// Getting standard register error 42 /// 43 #[error("Failed to get special registers: {0}")] 44 GetSpecialRegs(#[source] anyhow::Error), 45 /// 46 /// Setting floating point registers error 47 /// 48 #[error("Failed to set special register: {0}")] 49 SetFloatingPointRegs(#[source] anyhow::Error), 50 /// 51 /// Getting floating point register error 52 /// 53 #[error("Failed to get special register: {0}")] 54 GetFloatingPointRegs(#[source] anyhow::Error), 55 /// 56 /// Setting Cpuid error 57 /// 58 #[error("Failed to set Cpuid: {0}")] 59 SetCpuid(#[source] anyhow::Error), 60 /// 61 /// Getting Cpuid error 62 /// 63 #[error("Failed to get Cpuid: {0}")] 64 GetCpuid(#[source] anyhow::Error), 65 /// 66 /// Setting lapic state error 67 /// 68 #[error("Failed to set Lapic state: {0}")] 69 SetLapicState(#[source] anyhow::Error), 70 /// 71 /// Getting Lapic state error 72 /// 73 #[error("Failed to get Lapic state: {0}")] 74 GetlapicState(#[source] anyhow::Error), 75 /// 76 /// Setting MSR entries error 77 /// 78 #[error("Failed to set Msr entries: {0}")] 79 SetMsrEntries(#[source] anyhow::Error), 80 /// 81 /// Getting Msr entries error 82 /// 83 #[error("Failed to get Msr entries: {0}")] 84 GetMsrEntries(#[source] anyhow::Error), 85 /// 86 /// Setting MSR entries error 87 /// 88 #[error("Failed to set MP state: {0}")] 89 SetMpState(#[source] anyhow::Error), 90 /// 91 /// Getting Msr entries error 92 /// 93 #[error("Failed to get MP state: {0}")] 94 GetMpState(#[source] anyhow::Error), 95 /// 96 /// Setting Saved Processor Extended States error 97 /// 98 #[error("Failed to set Saved Processor Extended States: {0}")] 99 SetXsaveState(#[source] anyhow::Error), 100 /// 101 /// Getting Saved Processor Extended States error 102 /// 103 #[error("Failed to get Saved Processor Extended States: {0}")] 104 GetXsaveState(#[source] anyhow::Error), 105 /// 106 /// Setting Extended Control Registers error 107 /// 108 #[error("Failed to set Extended Control Registers: {0}")] 109 SetXcsr(#[source] anyhow::Error), 110 /// 111 /// Getting Extended Control Registers error 112 /// 113 #[error("Failed to get Extended Control Registers: {0}")] 114 GetXcsr(#[source] anyhow::Error), 115 /// 116 /// Running Vcpu error 117 /// 118 #[error("Failed to run vcpu: {0}")] 119 RunVcpu(#[source] anyhow::Error), 120 /// 121 /// Getting Vcpu events error 122 /// 123 #[error("Failed to get Vcpu events: {0}")] 124 GetVcpuEvents(#[source] anyhow::Error), 125 /// 126 /// Vcpu Init error 127 /// 128 #[error("Failed to init vcpu: {0}")] 129 VcpuInit(#[source] anyhow::Error), 130 /// 131 /// Setting one reg error 132 /// 133 #[error("Failed to init vcpu: {0}")] 134 SetOneReg(#[source] anyhow::Error), 135 /// 136 /// Getting one reg error 137 /// 138 #[error("Failed to init vcpu: {0}")] 139 GetOneReg(#[source] anyhow::Error), 140 } 141 142 /// 143 /// Result type for returning from a function 144 /// 145 pub type Result<T> = anyhow::Result<T, HypervisorCpuError>; 146 /// 147 /// Trait to represent a generic Vcpu 148 /// 149 pub trait Vcpu: Send + Sync { 150 #[cfg(target_arch = "x86_64")] 151 /// 152 /// Returns the vCPU general purpose registers. 153 /// 154 fn get_regs(&self) -> Result<StandardRegisters>; 155 156 #[cfg(target_arch = "x86_64")] 157 /// 158 /// Sets the vCPU general purpose registers. 159 /// 160 fn set_regs(&self, regs: &StandardRegisters) -> Result<()>; 161 #[cfg(target_arch = "x86_64")] 162 /// 163 /// Returns the vCPU special registers. 164 /// 165 fn get_sregs(&self) -> Result<SpecialRegisters>; 166 #[cfg(target_arch = "x86_64")] 167 /// 168 /// Sets the vCPU special registers 169 /// 170 fn set_sregs(&self, sregs: &SpecialRegisters) -> Result<()>; 171 #[cfg(target_arch = "x86_64")] 172 /// 173 /// Returns the floating point state (FPU) from the vCPU. 174 /// 175 fn get_fpu(&self) -> Result<FpuState>; 176 #[cfg(target_arch = "x86_64")] 177 /// 178 /// Set the floating point state (FPU) of a vCPU 179 /// 180 fn set_fpu(&self, fpu: &FpuState) -> Result<()>; 181 #[cfg(target_arch = "x86_64")] 182 /// 183 /// X86 specific call to setup the CPUID registers. 184 /// 185 fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()>; 186 #[cfg(target_arch = "x86_64")] 187 /// 188 /// X86 specific call to retrieve the CPUID registers. 189 /// 190 fn get_cpuid2(&self, num_entries: usize) -> Result<CpuId>; 191 #[cfg(target_arch = "x86_64")] 192 /// 193 /// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller). 194 /// 195 fn get_lapic(&self) -> Result<LapicState>; 196 #[cfg(target_arch = "x86_64")] 197 /// 198 /// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller). 199 /// 200 fn set_lapic(&self, lapic: &LapicState) -> Result<()>; 201 #[cfg(target_arch = "x86_64")] 202 /// 203 /// Returns the model-specific registers (MSR) for this vCPU. 204 /// 205 fn get_msrs(&self, msrs: &mut MsrEntries) -> Result<usize>; 206 #[cfg(target_arch = "x86_64")] 207 /// 208 /// Setup the model-specific registers (MSR) for this vCPU. 209 /// 210 fn set_msrs(&self, msrs: &MsrEntries) -> Result<usize>; 211 /// 212 /// Returns the vcpu's current "multiprocessing state". 213 /// 214 fn get_mp_state(&self) -> Result<MpState>; 215 /// 216 /// Sets the vcpu's current "multiprocessing state". 217 /// 218 fn set_mp_state(&self, mp_state: MpState) -> Result<()>; 219 #[cfg(target_arch = "x86_64")] 220 /// 221 /// X86 specific call that returns the vcpu's current "xsave struct". 222 /// 223 fn get_xsave(&self) -> Result<Xsave>; 224 #[cfg(target_arch = "x86_64")] 225 /// 226 /// X86 specific call that sets the vcpu's current "xsave struct". 227 /// 228 fn set_xsave(&self, xsave: &Xsave) -> Result<()>; 229 #[cfg(target_arch = "x86_64")] 230 /// 231 /// X86 specific call that returns the vcpu's current "xcrs". 232 /// 233 fn get_xcrs(&self) -> Result<ExtendedControlRegisters>; 234 #[cfg(target_arch = "x86_64")] 235 /// 236 /// X86 specific call that sets the vcpu's current "xcrs". 237 /// 238 fn set_xcrs(&self, xcrs: &ExtendedControlRegisters) -> Result<()>; 239 /// 240 /// Triggers the running of the current virtual CPU returning an exit reason. 241 /// 242 fn run(&self) -> std::result::Result<VcpuExit, RunError>; 243 #[cfg(target_arch = "x86_64")] 244 /// 245 /// Returns currently pending exceptions, interrupts, and NMIs as well as related 246 /// states of the vcpu. 247 /// 248 fn get_vcpu_events(&self) -> Result<VcpuEvents>; 249 /// 250 /// Sets the type of CPU to be exposed to the guest and optional features. 251 /// 252 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 253 fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>; 254 /// 255 /// Sets the value of one register for this vCPU. 256 /// 257 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 258 fn set_one_reg(&self, reg_id: u64, data: u64) -> Result<()>; 259 /// 260 /// Sets the value of one register for this vCPU. 261 /// 262 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 263 fn get_one_reg(&self, reg_id: u64) -> Result<u64>; 264 /// 265 /// Retrieve the current cpu states. This function is necessary to snapshot the VM 266 /// 267 fn cpu_state(&self) -> Result<CpuState>; 268 /// 269 /// Setting the FPU state this. 270 /// This function is required when restoring the VM 271 /// 272 fn set_cpu_state(&self, state: &CpuState) -> Result<()>; 273 } 274