xref: /cloud-hypervisor/hypervisor/src/cpu.rs (revision 9af2968a7dc47b89bf07ea9dc5e735084efcfa3a)
1 // Copyright © 2019 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4 //
5 // Copyright © 2020, Microsoft Corporation
6 //
7 // Copyright 2018-2019 CrowdStrike, Inc.
8 //
9 //
10 
11 #[cfg(target_arch = "aarch64")]
12 use crate::aarch64::VcpuInit;
13 #[cfg(target_arch = "aarch64")]
14 use crate::aarch64::{RegList, Register, StandardRegisters};
15 #[cfg(target_arch = "x86_64")]
16 use crate::x86_64::{CpuId, LapicState};
17 #[cfg(target_arch = "x86_64")]
18 use crate::x86_64::{
19     ExtendedControlRegisters, FpuState, MsrEntries, SpecialRegisters, StandardRegisters, VcpuEvents,
20 };
21 use crate::CpuState;
22 #[cfg(feature = "kvm")]
23 use crate::MpState;
24 #[cfg(all(feature = "mshv", target_arch = "x86_64"))]
25 use crate::SuspendRegisters;
26 #[cfg(target_arch = "x86_64")]
27 use crate::Xsave;
28 #[cfg(feature = "mshv")]
29 use mshv_bindings::*;
30 use thiserror::Error;
31 
32 #[derive(Error, Debug)]
33 ///
34 /// Enum for CPU error
35 pub enum HypervisorCpuError {
36     ///
37     /// Setting standard registers error
38     ///
39     #[error("Failed to set standard register: {0}")]
40     SetStandardRegs(#[source] anyhow::Error),
41     ///
42     /// Setting standard registers error
43     ///
44     #[error("Failed to get standard registers: {0}")]
45     GetStandardRegs(#[source] anyhow::Error),
46     ///
47     /// Getting suspend registers error
48     ///
49     #[error("Failed to get suspend registers: {0}")]
50     GetSuspendRegs(#[source] anyhow::Error),
51     ///
52     /// Setting special register error
53     ///
54     #[error("Failed to set special registers: {0}")]
55     SetSpecialRegs(#[source] anyhow::Error),
56     ///
57     /// Getting standard register error
58     ///
59     #[error("Failed to get special registers: {0}")]
60     GetSpecialRegs(#[source] anyhow::Error),
61     ///
62     /// Setting floating point registers error
63     ///
64     #[error("Failed to set special register: {0}")]
65     SetFloatingPointRegs(#[source] anyhow::Error),
66     ///
67     /// Getting floating point register error
68     ///
69     #[error("Failed to get special register: {0}")]
70     GetFloatingPointRegs(#[source] anyhow::Error),
71     ///
72     /// Setting Cpuid error
73     ///
74     #[error("Failed to set Cpuid: {0}")]
75     SetCpuid(#[source] anyhow::Error),
76     ///
77     /// Getting Cpuid error
78     ///
79     #[error("Failed to get Cpuid: {0}")]
80     GetCpuid(#[source] anyhow::Error),
81     ///
82     /// Setting lapic state error
83     ///
84     #[error("Failed to set Lapic state: {0}")]
85     SetLapicState(#[source] anyhow::Error),
86     ///
87     /// Getting Lapic state error
88     ///
89     #[error("Failed to get Lapic state: {0}")]
90     GetlapicState(#[source] anyhow::Error),
91     ///
92     /// Setting MSR entries error
93     ///
94     #[error("Failed to set Msr entries: {0}")]
95     SetMsrEntries(#[source] anyhow::Error),
96     ///
97     /// Getting Msr entries error
98     ///
99     #[error("Failed to get Msr entries: {0}")]
100     GetMsrEntries(#[source] anyhow::Error),
101     ///
102     /// Setting MSR entries error
103     ///
104     #[error("Failed to set MP state: {0}")]
105     SetMpState(#[source] anyhow::Error),
106     ///
107     /// Getting Msr entries error
108     ///
109     #[error("Failed to get MP state: {0}")]
110     GetMpState(#[source] anyhow::Error),
111     ///
112     /// Setting Saved Processor Extended States error
113     ///
114     #[error("Failed to set Saved Processor Extended States: {0}")]
115     SetXsaveState(#[source] anyhow::Error),
116     ///
117     /// Getting Saved Processor Extended States error
118     ///
119     #[error("Failed to get Saved Processor Extended States: {0}")]
120     GetXsaveState(#[source] anyhow::Error),
121     ///
122     /// Setting Extended Control Registers error
123     ///
124     #[error("Failed to set Extended Control Registers: {0}")]
125     SetXcsr(#[source] anyhow::Error),
126     ///
127     /// Getting Extended Control Registers error
128     ///
129     #[error("Failed to get Extended Control Registers: {0}")]
130     GetXcsr(#[source] anyhow::Error),
131     ///
132     /// Running Vcpu error
133     ///
134     #[error("Failed to run vcpu: {0}")]
135     RunVcpu(#[source] anyhow::Error),
136     ///
137     /// Getting Vcpu events error
138     ///
139     #[error("Failed to get Vcpu events: {0}")]
140     GetVcpuEvents(#[source] anyhow::Error),
141     ///
142     /// Setting Vcpu events error
143     ///
144     #[error("Failed to set Vcpu events: {0}")]
145     SetVcpuEvents(#[source] anyhow::Error),
146     ///
147     /// Vcpu Init error
148     ///
149     #[error("Failed to init vcpu: {0}")]
150     VcpuInit(#[source] anyhow::Error),
151     ///
152     /// Setting one reg error
153     ///
154     #[error("Failed to init vcpu: {0}")]
155     SetRegister(#[source] anyhow::Error),
156     ///
157     /// Getting one reg error
158     ///
159     #[error("Failed to init vcpu: {0}")]
160     GetRegister(#[source] anyhow::Error),
161     ///
162     /// Getting guest clock paused error
163     ///
164     #[error("Failed to notify guest its clock was paused: {0}")]
165     NotifyGuestClockPaused(#[source] anyhow::Error),
166     ///
167     /// Setting debug register error
168     ///
169     #[error("Failed to set debug registers: {0}")]
170     SetDebugRegs(#[source] anyhow::Error),
171     ///
172     /// Getting debug register error
173     ///
174     #[error("Failed to get debug registers: {0}")]
175     GetDebugRegs(#[source] anyhow::Error),
176     ///
177     /// Write to Guest Mem
178     ///
179     #[error("Failed to write to Guest Mem at: {0}")]
180     GuestMemWrite(#[source] anyhow::Error),
181     /// Enabling HyperV SynIC error
182     ///
183     #[error("Failed to enable HyperV SynIC")]
184     EnableHyperVSyncIc(#[source] anyhow::Error),
185     ///
186     /// Getting AArch64 core register error
187     ///
188     #[error("Failed to get core register: {0}")]
189     GetCoreRegister(#[source] anyhow::Error),
190     ///
191     /// Setting AArch64 core register error
192     ///
193     #[error("Failed to set core register: {0}")]
194     SetCoreRegister(#[source] anyhow::Error),
195     ///
196     /// Getting AArch64 registers list error
197     ///
198     #[error("Failed to retrieve list of registers: {0}")]
199     GetRegList(#[source] anyhow::Error),
200     ///
201     /// Getting AArch64 system register error
202     ///
203     #[error("Failed to get system register: {0}")]
204     GetSysRegister(#[source] anyhow::Error),
205     ///
206     /// Setting AArch64 system register error
207     ///
208     #[error("Failed to set system register: {0}")]
209     SetSysRegister(#[source] anyhow::Error),
210     ///
211     /// GVA translation error
212     ///
213     #[error("Failed to translate GVA: {0}")]
214     TranslateVirtualAddress(#[source] anyhow::Error),
215     ///
216     /// Failed to initialize TDX on CPU
217     ///
218     #[cfg(feature = "tdx")]
219     #[error("Failed to initialize TDX: {0}")]
220     InitializeTdx(#[source] std::io::Error),
221 }
222 
223 #[derive(Debug)]
224 pub enum VmExit<'a> {
225     #[cfg(target_arch = "x86_64")]
226     IoOut(u16 /* port */, &'a [u8] /* data */),
227     #[cfg(target_arch = "x86_64")]
228     IoIn(u16 /* port */, &'a mut [u8] /* data */),
229     #[cfg(target_arch = "x86_64")]
230     IoapicEoi(u8 /* vector */),
231     MmioRead(u64 /* address */, &'a mut [u8]),
232     MmioWrite(u64 /* address */, &'a [u8]),
233     Ignore,
234     Reset,
235     Shutdown,
236     Hyperv,
237 }
238 
239 ///
240 /// Result type for returning from a function
241 ///
242 pub type Result<T> = anyhow::Result<T, HypervisorCpuError>;
243 ///
244 /// Trait to represent a generic Vcpu
245 ///
246 pub trait Vcpu: Send + Sync {
247     #[cfg(target_arch = "x86_64")]
248     ///
249     /// Returns the vCPU general purpose registers.
250     ///
251     fn get_regs(&self) -> Result<StandardRegisters>;
252 
253     #[cfg(target_arch = "x86_64")]
254     ///
255     /// Sets the vCPU general purpose registers.
256     ///
257     fn set_regs(&self, regs: &StandardRegisters) -> Result<()>;
258     #[cfg(target_arch = "x86_64")]
259     ///
260     /// Returns the vCPU special registers.
261     ///
262     fn get_sregs(&self) -> Result<SpecialRegisters>;
263     #[cfg(target_arch = "x86_64")]
264     ///
265     /// Sets the vCPU special registers
266     ///
267     fn set_sregs(&self, sregs: &SpecialRegisters) -> Result<()>;
268     #[cfg(target_arch = "x86_64")]
269     ///
270     /// Returns the floating point state (FPU) from the vCPU.
271     ///
272     fn get_fpu(&self) -> Result<FpuState>;
273     #[cfg(target_arch = "x86_64")]
274     ///
275     /// Set the floating point state (FPU) of a vCPU
276     ///
277     fn set_fpu(&self, fpu: &FpuState) -> Result<()>;
278     #[cfg(target_arch = "x86_64")]
279     ///
280     /// X86 specific call to setup the CPUID registers.
281     ///
282     fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()>;
283     #[cfg(target_arch = "x86_64")]
284     ///
285     /// X86 specific call to enable HyperV SynIC
286     ///
287     fn enable_hyperv_synic(&self) -> Result<()>;
288     #[cfg(target_arch = "x86_64")]
289     ///
290     /// X86 specific call to retrieve the CPUID registers.
291     ///
292     fn get_cpuid2(&self, num_entries: usize) -> Result<CpuId>;
293     #[cfg(target_arch = "x86_64")]
294     ///
295     /// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
296     ///
297     fn get_lapic(&self) -> Result<LapicState>;
298     #[cfg(target_arch = "x86_64")]
299     ///
300     /// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
301     ///
302     fn set_lapic(&self, lapic: &LapicState) -> Result<()>;
303     #[cfg(target_arch = "x86_64")]
304     ///
305     /// Returns the model-specific registers (MSR) for this vCPU.
306     ///
307     fn get_msrs(&self, msrs: &mut MsrEntries) -> Result<usize>;
308     #[cfg(target_arch = "x86_64")]
309     ///
310     /// Setup the model-specific registers (MSR) for this vCPU.
311     ///
312     fn set_msrs(&self, msrs: &MsrEntries) -> Result<usize>;
313     #[cfg(feature = "kvm")]
314     ///
315     /// Returns the vcpu's current "multiprocessing state".
316     ///
317     fn get_mp_state(&self) -> Result<MpState>;
318     #[cfg(feature = "kvm")]
319     ///
320     /// Sets the vcpu's current "multiprocessing state".
321     ///
322     fn set_mp_state(&self, mp_state: MpState) -> Result<()>;
323     #[cfg(target_arch = "x86_64")]
324     ///
325     /// X86 specific call that returns the vcpu's current "xsave struct".
326     ///
327     fn get_xsave(&self) -> Result<Xsave>;
328     #[cfg(target_arch = "x86_64")]
329     ///
330     /// X86 specific call that sets the vcpu's current "xsave struct".
331     ///
332     fn set_xsave(&self, xsave: &Xsave) -> Result<()>;
333     #[cfg(target_arch = "x86_64")]
334     ///
335     /// X86 specific call that returns the vcpu's current "xcrs".
336     ///
337     fn get_xcrs(&self) -> Result<ExtendedControlRegisters>;
338     #[cfg(target_arch = "x86_64")]
339     ///
340     /// X86 specific call that sets the vcpu's current "xcrs".
341     ///
342     fn set_xcrs(&self, xcrs: &ExtendedControlRegisters) -> Result<()>;
343     #[cfg(target_arch = "x86_64")]
344     ///
345     /// Returns currently pending exceptions, interrupts, and NMIs as well as related
346     /// states of the vcpu.
347     ///
348     fn get_vcpu_events(&self) -> Result<VcpuEvents>;
349     #[cfg(target_arch = "x86_64")]
350     ///
351     /// Sets pending exceptions, interrupts, and NMIs as well as related states
352     /// of the vcpu.
353     ///
354     fn set_vcpu_events(&self, events: &VcpuEvents) -> Result<()>;
355     #[cfg(all(feature = "kvm", target_arch = "x86_64"))]
356     ///
357     /// Let the guest know that it has been paused, which prevents from
358     /// potential soft lockups when being resumed.
359     ///
360     fn notify_guest_clock_paused(&self) -> Result<()>;
361     ///
362     /// Sets the type of CPU to be exposed to the guest and optional features.
363     ///
364     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
365     fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>;
366     ///
367     /// Sets the value of one register for this vCPU.
368     ///
369     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
370     fn set_reg(&self, reg_id: u64, data: u64) -> Result<()>;
371     ///
372     /// Sets the value of one register for this vCPU.
373     ///
374     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
375     fn get_reg(&self, reg_id: u64) -> Result<u64>;
376     ///
377     /// Gets a list of the guest registers that are supported for the
378     /// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
379     ///
380     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
381     fn get_reg_list(&self, reg_list: &mut RegList) -> Result<()>;
382     ///
383     /// Save the state of the core registers.
384     ///
385     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
386     fn core_registers(&self, state: &mut StandardRegisters) -> Result<()>;
387     ///
388     /// Restore the state of the core registers.
389     ///
390     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
391     fn set_core_registers(&self, state: &StandardRegisters) -> Result<()>;
392     ///
393     /// Save the state of the system registers.
394     ///
395     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
396     fn system_registers(&self, state: &mut Vec<Register>) -> Result<()>;
397     ///
398     /// Restore the state of the system registers.
399     ///
400     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
401     fn set_system_registers(&self, state: &[Register]) -> Result<()>;
402     ///
403     /// Read the MPIDR - Multiprocessor Affinity Register.
404     ///
405     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
406     fn read_mpidr(&self) -> Result<u64>;
407     ///
408     /// Retrieve the vCPU state.
409     /// This function is necessary to snapshot the VM
410     ///
411     fn state(&self) -> Result<CpuState>;
412     ///
413     /// Set the vCPU state.
414     /// This function is required when restoring the VM
415     ///
416     fn set_state(&self, state: &CpuState) -> Result<()>;
417     ///
418     /// Triggers the running of the current virtual CPU returning an exit reason.
419     ///
420     fn run(&self) -> std::result::Result<VmExit, HypervisorCpuError>;
421     #[cfg(all(feature = "mshv", target_arch = "x86_64"))]
422     ///
423     /// Translate guest virtual address to guest physical address
424     ///
425     fn translate_gva(&self, gva: u64, flags: u64) -> Result<(u64, hv_translate_gva_result)>;
426     ///
427     /// Initialize TDX support on the vCPU
428     ///
429     #[cfg(feature = "tdx")]
430     fn tdx_init(&self, hob_address: u64) -> Result<()>;
431     #[cfg(all(feature = "mshv", target_arch = "x86_64"))]
432     ///
433     /// Return suspend registers(explicit and intercept suspend registers)
434     ///
435     fn get_suspend_regs(&self) -> Result<SuspendRegisters>;
436 }
437