xref: /cloud-hypervisor/hypervisor/src/cpu.rs (revision 72c81783358b641709a16112a45a7ffd52f58f3f)
171053534SRuoqing He // Copyright © 2024 Institute of Software, CAS. All rights reserved.
271053534SRuoqing He //
3f9b51a41SMuminul Islam // Copyright © 2019 Intel Corporation
4f9b51a41SMuminul Islam //
572ae1577SMuminul Islam // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
6f9b51a41SMuminul Islam //
7f9b51a41SMuminul Islam // Copyright © 2020, Microsoft Corporation
8f9b51a41SMuminul Islam //
9f9b51a41SMuminul Islam // Copyright 2018-2019 CrowdStrike, Inc.
10f9b51a41SMuminul Islam //
1172ae1577SMuminul Islam //
12f9b51a41SMuminul Islam 
13171b28ceSJinank Jain #[cfg(target_arch = "aarch64")]
14171b28ceSJinank Jain use std::sync::Arc;
15171b28ceSJinank Jain 
1688a9f799SRob Bradford use thiserror::Error;
1771053534SRuoqing He #[cfg(not(target_arch = "riscv64"))]
1888a9f799SRob Bradford use vm_memory::GuestAddress;
1988a9f799SRob Bradford 
208b7781e2SWei Liu #[cfg(target_arch = "x86_64")]
214c99aea6SJinank Jain use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
22218be264SRob Bradford #[cfg(feature = "tdx")]
23218be264SRob Bradford use crate::kvm::{TdxExitDetails, TdxExitStatus};
24ee0b0d43SJinank Jain #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
25ee0b0d43SJinank Jain use crate::RegList;
265b929cb2SJinank Jain #[cfg(target_arch = "aarch64")]
275b929cb2SJinank Jain use crate::VcpuInit;
2861e57e1cSRuoqing He use crate::{CpuState, MpState, StandardRegisters};
29f9b51a41SMuminul Islam 
307df80220SAnatol Belski #[cfg(target_arch = "x86_64")]
317df80220SAnatol Belski #[derive(Copy, Clone, Default)]
327df80220SAnatol Belski pub enum CpuVendor {
337df80220SAnatol Belski     #[default]
347df80220SAnatol Belski     Unknown,
357df80220SAnatol Belski     Intel,
367df80220SAnatol Belski     AMD,
377df80220SAnatol Belski }
387df80220SAnatol Belski 
39f9b51a41SMuminul Islam #[derive(Error, Debug)]
40f9b51a41SMuminul Islam ///
41f9b51a41SMuminul Islam /// Enum for CPU error
42f9b51a41SMuminul Islam pub enum HypervisorCpuError {
43f9b51a41SMuminul Islam     ///
44f9b51a41SMuminul Islam     /// Setting standard registers error
45f9b51a41SMuminul Islam     ///
46*72c81783SPhilipp Schuster     #[error("Failed to set standard register")]
47f9b51a41SMuminul Islam     SetStandardRegs(#[source] anyhow::Error),
48f9b51a41SMuminul Islam     ///
49f9b51a41SMuminul Islam     /// Setting standard registers error
50f9b51a41SMuminul Islam     ///
51*72c81783SPhilipp Schuster     #[error("Failed to get standard registers")]
52f9b51a41SMuminul Islam     GetStandardRegs(#[source] anyhow::Error),
53f9b51a41SMuminul Islam     ///
54f9b51a41SMuminul Islam     /// Setting special register error
55f9b51a41SMuminul Islam     ///
56*72c81783SPhilipp Schuster     #[error("Failed to set special registers")]
57f9b51a41SMuminul Islam     SetSpecialRegs(#[source] anyhow::Error),
58f9b51a41SMuminul Islam     ///
59f9b51a41SMuminul Islam     /// Getting standard register error
60f9b51a41SMuminul Islam     ///
61*72c81783SPhilipp Schuster     #[error("Failed to get special registers")]
62f9b51a41SMuminul Islam     GetSpecialRegs(#[source] anyhow::Error),
63f9b51a41SMuminul Islam     ///
64f9b51a41SMuminul Islam     /// Setting floating point registers error
65f9b51a41SMuminul Islam     ///
66*72c81783SPhilipp Schuster     #[error("Failed to set floating point registers")]
67f9b51a41SMuminul Islam     SetFloatingPointRegs(#[source] anyhow::Error),
68f9b51a41SMuminul Islam     ///
69f9b51a41SMuminul Islam     /// Getting floating point register error
70f9b51a41SMuminul Islam     ///
71*72c81783SPhilipp Schuster     #[error("Failed to get floating points registers")]
72f9b51a41SMuminul Islam     GetFloatingPointRegs(#[source] anyhow::Error),
73f9b51a41SMuminul Islam     ///
74f9b51a41SMuminul Islam     /// Setting Cpuid error
75f9b51a41SMuminul Islam     ///
76*72c81783SPhilipp Schuster     #[error("Failed to set Cpuid")]
77f9b51a41SMuminul Islam     SetCpuid(#[source] anyhow::Error),
78f9b51a41SMuminul Islam     ///
79f9b51a41SMuminul Islam     /// Getting Cpuid error
80f9b51a41SMuminul Islam     ///
81*72c81783SPhilipp Schuster     #[error("Failed to get Cpuid")]
82f9b51a41SMuminul Islam     GetCpuid(#[source] anyhow::Error),
83f9b51a41SMuminul Islam     ///
84f9b51a41SMuminul Islam     /// Setting lapic state error
85f9b51a41SMuminul Islam     ///
86*72c81783SPhilipp Schuster     #[error("Failed to set Lapic state")]
87f9b51a41SMuminul Islam     SetLapicState(#[source] anyhow::Error),
88f9b51a41SMuminul Islam     ///
89f9b51a41SMuminul Islam     /// Getting Lapic state error
90f9b51a41SMuminul Islam     ///
91*72c81783SPhilipp Schuster     #[error("Failed to get Lapic state")]
92f9b51a41SMuminul Islam     GetlapicState(#[source] anyhow::Error),
93f9b51a41SMuminul Islam     ///
94f9b51a41SMuminul Islam     /// Setting MSR entries error
95f9b51a41SMuminul Islam     ///
96*72c81783SPhilipp Schuster     #[error("Failed to set Msr entries")]
97f9b51a41SMuminul Islam     SetMsrEntries(#[source] anyhow::Error),
98f9b51a41SMuminul Islam     ///
99f9b51a41SMuminul Islam     /// Getting Msr entries error
100f9b51a41SMuminul Islam     ///
101*72c81783SPhilipp Schuster     #[error("Failed to get Msr entries")]
102f9b51a41SMuminul Islam     GetMsrEntries(#[source] anyhow::Error),
103f9b51a41SMuminul Islam     ///
1047d5ea5caSMuminul Islam     /// Setting multi-processing  state error
105f9b51a41SMuminul Islam     ///
106*72c81783SPhilipp Schuster     #[error("Failed to set MP state")]
107f9b51a41SMuminul Islam     SetMpState(#[source] anyhow::Error),
108f9b51a41SMuminul Islam     ///
1097d5ea5caSMuminul Islam     /// Getting multi-processing  state error
110f9b51a41SMuminul Islam     ///
111*72c81783SPhilipp Schuster     #[error("Failed to get MP state")]
112f9b51a41SMuminul Islam     GetMpState(#[source] anyhow::Error),
113f9b51a41SMuminul Islam     ///
114f9b51a41SMuminul Islam     /// Setting Saved Processor Extended States error
115f9b51a41SMuminul Islam     ///
116512591baSMuminul Islam     #[cfg(feature = "kvm")]
117*72c81783SPhilipp Schuster     #[error("Failed to set Saved Processor Extended States")]
118f9b51a41SMuminul Islam     SetXsaveState(#[source] anyhow::Error),
119f9b51a41SMuminul Islam     ///
120f9b51a41SMuminul Islam     /// Getting Saved Processor Extended States error
121f9b51a41SMuminul Islam     ///
122512591baSMuminul Islam     #[cfg(feature = "kvm")]
123*72c81783SPhilipp Schuster     #[error("Failed to get Saved Processor Extended States")]
124f9b51a41SMuminul Islam     GetXsaveState(#[source] anyhow::Error),
125f9b51a41SMuminul Islam     ///
126512591baSMuminul Islam     /// Getting the VP state components error
127512591baSMuminul Islam     ///
128512591baSMuminul Islam     #[cfg(feature = "mshv")]
129*72c81783SPhilipp Schuster     #[error("Failed to get VP State Components")]
130512591baSMuminul Islam     GetAllVpStateComponents(#[source] anyhow::Error),
131512591baSMuminul Islam     ///
132512591baSMuminul Islam     /// Setting the VP state components error
133512591baSMuminul Islam     ///
134512591baSMuminul Islam     #[cfg(feature = "mshv")]
135*72c81783SPhilipp Schuster     #[error("Failed to set VP State Components")]
136512591baSMuminul Islam     SetAllVpStateComponents(#[source] anyhow::Error),
137512591baSMuminul Islam     ///
138f9b51a41SMuminul Islam     /// Setting Extended Control Registers error
139f9b51a41SMuminul Islam     ///
140*72c81783SPhilipp Schuster     #[error("Failed to set Extended Control Registers")]
141f9b51a41SMuminul Islam     SetXcsr(#[source] anyhow::Error),
142f9b51a41SMuminul Islam     ///
143f9b51a41SMuminul Islam     /// Getting Extended Control Registers error
144f9b51a41SMuminul Islam     ///
145*72c81783SPhilipp Schuster     #[error("Failed to get Extended Control Registers")]
146f9b51a41SMuminul Islam     GetXcsr(#[source] anyhow::Error),
147f9b51a41SMuminul Islam     ///
148f9b51a41SMuminul Islam     /// Running Vcpu error
149f9b51a41SMuminul Islam     ///
150*72c81783SPhilipp Schuster     #[error("Failed to run vcpu")]
151f9b51a41SMuminul Islam     RunVcpu(#[source] anyhow::Error),
152f9b51a41SMuminul Islam     ///
153f9b51a41SMuminul Islam     /// Getting Vcpu events error
154f9b51a41SMuminul Islam     ///
155*72c81783SPhilipp Schuster     #[error("Failed to get Vcpu events")]
156f9b51a41SMuminul Islam     GetVcpuEvents(#[source] anyhow::Error),
157f9b51a41SMuminul Islam     ///
158e2b5c78dSSebastien Boeuf     /// Setting Vcpu events error
159e2b5c78dSSebastien Boeuf     ///
160*72c81783SPhilipp Schuster     #[error("Failed to set Vcpu events")]
161e2b5c78dSSebastien Boeuf     SetVcpuEvents(#[source] anyhow::Error),
162e2b5c78dSSebastien Boeuf     ///
163f9b51a41SMuminul Islam     /// Vcpu Init error
164f9b51a41SMuminul Islam     ///
165*72c81783SPhilipp Schuster     #[error("Failed to init vcpu")]
166f9b51a41SMuminul Islam     VcpuInit(#[source] anyhow::Error),
167f9b51a41SMuminul Islam     ///
168d2a364c5SWenyu Huang     /// Vcpu Finalize error
169d2a364c5SWenyu Huang     ///
170*72c81783SPhilipp Schuster     #[error("Failed to finalize vcpu")]
171d2a364c5SWenyu Huang     VcpuFinalize(#[source] anyhow::Error),
172d2a364c5SWenyu Huang     ///
173f9b51a41SMuminul Islam     /// Setting one reg error
174f9b51a41SMuminul Islam     ///
175*72c81783SPhilipp Schuster     #[error("Failed to set one reg")]
176ed1fdd1fSWei Liu     SetRegister(#[source] anyhow::Error),
177f9b51a41SMuminul Islam     ///
178f9b51a41SMuminul Islam     /// Getting one reg error
179f9b51a41SMuminul Islam     ///
180*72c81783SPhilipp Schuster     #[error("Failed to get one reg")]
181ed1fdd1fSWei Liu     GetRegister(#[source] anyhow::Error),
182309924ecSSebastien Boeuf     ///
183309924ecSSebastien Boeuf     /// Getting guest clock paused error
184309924ecSSebastien Boeuf     ///
185*72c81783SPhilipp Schuster     #[error("Failed to notify guest its clock was paused")]
186309924ecSSebastien Boeuf     NotifyGuestClockPaused(#[source] anyhow::Error),
1879b48ee38SRob Bradford     ///
18823c46b16SMuminul Islam     /// Setting debug register error
18923c46b16SMuminul Islam     ///
190*72c81783SPhilipp Schuster     #[error("Failed to set debug registers")]
19123c46b16SMuminul Islam     SetDebugRegs(#[source] anyhow::Error),
19223c46b16SMuminul Islam     ///
19323c46b16SMuminul Islam     /// Getting debug register error
19423c46b16SMuminul Islam     ///
195*72c81783SPhilipp Schuster     #[error("Failed to get debug registers")]
19623c46b16SMuminul Islam     GetDebugRegs(#[source] anyhow::Error),
19723c46b16SMuminul Islam     ///
198c3d6aceeSMuminul Islam     /// Setting misc register error
199c3d6aceeSMuminul Islam     ///
200*72c81783SPhilipp Schuster     #[error("Failed to set misc registers")]
201c3d6aceeSMuminul Islam     SetMiscRegs(#[source] anyhow::Error),
202c3d6aceeSMuminul Islam     ///
203c3d6aceeSMuminul Islam     /// Getting misc register error
204c3d6aceeSMuminul Islam     ///
205*72c81783SPhilipp Schuster     #[error("Failed to get misc registers")]
206c3d6aceeSMuminul Islam     GetMiscRegs(#[source] anyhow::Error),
207c3d6aceeSMuminul Islam     ///
20823c46b16SMuminul Islam     /// Write to Guest Mem
20923c46b16SMuminul Islam     ///
210*72c81783SPhilipp Schuster     #[error("Failed to write to Guest Mem at")]
21123c46b16SMuminul Islam     GuestMemWrite(#[source] anyhow::Error),
2129b48ee38SRob Bradford     /// Enabling HyperV SynIC error
2139b48ee38SRob Bradford     ///
2149b48ee38SRob Bradford     #[error("Failed to enable HyperV SynIC")]
2150c27f69fSRob Bradford     EnableHyperVSyncIc(#[source] anyhow::Error),
216e3d45be6SHenry Wang     ///
217ffafeda4SHenry Wang     /// Getting AArch64 core register error
218ffafeda4SHenry Wang     ///
219*72c81783SPhilipp Schuster     #[error("Failed to get aarch64 core register")]
2202668dbbdSRuoqing He     GetAarchCoreRegister(#[source] anyhow::Error),
221ffafeda4SHenry Wang     ///
222ffafeda4SHenry Wang     /// Setting AArch64 core register error
223ffafeda4SHenry Wang     ///
224*72c81783SPhilipp Schuster     #[error("Failed to set aarch64 core register")]
2252668dbbdSRuoqing He     SetAarchCoreRegister(#[source] anyhow::Error),
226ffafeda4SHenry Wang     ///
227c13019d5SRuoqing He     /// Getting RISC-V 64-bit core register error
228c13019d5SRuoqing He     ///
229*72c81783SPhilipp Schuster     #[error("Failed to get riscv64 core register")]
230c13019d5SRuoqing He     GetRiscvCoreRegister(#[source] anyhow::Error),
231c13019d5SRuoqing He     ///
232c13019d5SRuoqing He     /// Setting RISC-V 64-bit core register error
233c13019d5SRuoqing He     ///
234*72c81783SPhilipp Schuster     #[error("Failed to set riscv64 core register")]
235c13019d5SRuoqing He     SetRiscvCoreRegister(#[source] anyhow::Error),
236c13019d5SRuoqing He     ///
237e8697735SRuoqing He     /// Getting registers list error
238ffafeda4SHenry Wang     ///
239*72c81783SPhilipp Schuster     #[error("Failed to retrieve list of registers")]
240ffafeda4SHenry Wang     GetRegList(#[source] anyhow::Error),
241ffafeda4SHenry Wang     ///
242e3d45be6SHenry Wang     /// Getting AArch64 system register error
243e3d45be6SHenry Wang     ///
244*72c81783SPhilipp Schuster     #[error("Failed to get system register")]
245e3d45be6SHenry Wang     GetSysRegister(#[source] anyhow::Error),
246ffafeda4SHenry Wang     ///
247ffafeda4SHenry Wang     /// Setting AArch64 system register error
248ffafeda4SHenry Wang     ///
249*72c81783SPhilipp Schuster     #[error("Failed to set system register")]
250ffafeda4SHenry Wang     SetSysRegister(#[source] anyhow::Error),
25174565538SWei Liu     ///
252c13019d5SRuoqing He     /// Getting RISC-V 64-bit non-core register error
253c13019d5SRuoqing He     ///
254*72c81783SPhilipp Schuster     #[error("Failed to get non-core register")]
255c13019d5SRuoqing He     GetNonCoreRegister(#[source] anyhow::Error),
256c13019d5SRuoqing He     ///
257c13019d5SRuoqing He     /// Setting RISC-V 64-bit non-core register error
258c13019d5SRuoqing He     ///
259*72c81783SPhilipp Schuster     #[error("Failed to set non-core register")]
260c13019d5SRuoqing He     SetNonCoreRegister(#[source] anyhow::Error),
261c13019d5SRuoqing He     ///
26274565538SWei Liu     /// GVA translation error
26374565538SWei Liu     ///
264*72c81783SPhilipp Schuster     #[error("Failed to translate GVA")]
2650c27f69fSRob Bradford     TranslateVirtualAddress(#[source] anyhow::Error),
266f282cc00SRob Bradford     ///
2679bcb9849SJianyong Wu     /// Set cpu attribute error
2689bcb9849SJianyong Wu     ///
269*72c81783SPhilipp Schuster     #[error("Failed to set vcpu attribute")]
2709bcb9849SJianyong Wu     SetVcpuAttribute(#[source] anyhow::Error),
2719bcb9849SJianyong Wu     ///
2729bcb9849SJianyong Wu     /// Check if cpu has a certain attribute error
2739bcb9849SJianyong Wu     ///
274*72c81783SPhilipp Schuster     #[error("Failed to check if vcpu has attribute")]
2759bcb9849SJianyong Wu     HasVcpuAttribute(#[source] anyhow::Error),
2769bcb9849SJianyong Wu     ///
277f282cc00SRob Bradford     /// Failed to initialize TDX on CPU
278f282cc00SRob Bradford     ///
279f282cc00SRob Bradford     #[cfg(feature = "tdx")]
280*72c81783SPhilipp Schuster     #[error("Failed to initialize TDX")]
281f282cc00SRob Bradford     InitializeTdx(#[source] std::io::Error),
282cb844ecdSSebastien Boeuf     ///
283cb844ecdSSebastien Boeuf     /// Unknown TDX VM call
284cb844ecdSSebastien Boeuf     ///
285cb844ecdSSebastien Boeuf     #[cfg(feature = "tdx")]
286cb844ecdSSebastien Boeuf     #[error("Unknown TDX VM call")]
287cb844ecdSSebastien Boeuf     UnknownTdxVmCall,
288f84ddedbSWei Liu     #[cfg(target_arch = "aarch64")]
289f84ddedbSWei Liu     ///
2907bf0cc1eSPhilipp Schuster     /// Failed to initialize PMU
291f84ddedbSWei Liu     ///
292f84ddedbSWei Liu     #[error("Failed to initialize PMU")]
293f84ddedbSWei Liu     InitializePmu,
294c22c4675SRob Bradford     #[cfg(target_arch = "x86_64")]
295c22c4675SRob Bradford     ///
296c22c4675SRob Bradford     /// Error getting TSC frequency
297c22c4675SRob Bradford     ///
298*72c81783SPhilipp Schuster     #[error("Failed to get TSC frequency")]
299c22c4675SRob Bradford     GetTscKhz(#[source] anyhow::Error),
30044f200d6SRob Bradford     ///
30144f200d6SRob Bradford     /// Error setting TSC frequency
30244f200d6SRob Bradford     ///
303*72c81783SPhilipp Schuster     #[error("Failed to set TSC frequency")]
30444f200d6SRob Bradford     SetTscKhz(#[source] anyhow::Error),
305cb5ea059SJinank Jain     ///
306cb5ea059SJinank Jain     /// Error reading value at given GPA
307cb5ea059SJinank Jain     ///
308*72c81783SPhilipp Schuster     #[error("Failed to read from GPA")]
309cb5ea059SJinank Jain     GpaRead(#[source] anyhow::Error),
310cb5ea059SJinank Jain     ///
311cb5ea059SJinank Jain     /// Error writing value at given GPA
312cb5ea059SJinank Jain     ///
313*72c81783SPhilipp Schuster     #[error("Failed to write to GPA")]
314cb5ea059SJinank Jain     GpaWrite(#[source] anyhow::Error),
315ec79820bSMuminul Islam     ///
316ec79820bSMuminul Islam     /// Error getting CPUID leaf
317ec79820bSMuminul Islam     ///
318*72c81783SPhilipp Schuster     #[error("Failed to get CPUID entries")]
319ec79820bSMuminul Islam     GetCpuidVales(#[source] anyhow::Error),
3205368ff28SMuminul Islam     ///
3215368ff28SMuminul Islam     /// Setting SEV control register error
3225368ff28SMuminul Islam     ///
3235368ff28SMuminul Islam     #[cfg(feature = "sev_snp")]
324*72c81783SPhilipp Schuster     #[error("Failed to set sev control register")]
3255368ff28SMuminul Islam     SetSevControlRegister(#[source] anyhow::Error),
326f1f68147SJinank Jain     ///
327f1f68147SJinank Jain     /// Unsupported SysReg registers
328f1f68147SJinank Jain     ///
329f1f68147SJinank Jain     #[cfg(target_arch = "aarch64")]
330f1f68147SJinank Jain     #[error("Unsupported SysReg registers: {0}")]
331f1f68147SJinank Jain     UnsupportedSysReg(u32),
332f1f68147SJinank Jain     ///
333c72bf0b3SYi Wang     /// Error injecting NMI
334c72bf0b3SYi Wang     ///
335c72bf0b3SYi Wang     #[error("Failed to inject NMI")]
336c72bf0b3SYi Wang     Nmi(#[source] anyhow::Error),
337f9b51a41SMuminul Islam }
338f9b51a41SMuminul Islam 
339a4f484bcSWei Liu #[derive(Debug)]
340c022063aSRob Bradford pub enum VmExit {
341a4f484bcSWei Liu     #[cfg(target_arch = "x86_64")]
342a4f484bcSWei Liu     IoapicEoi(u8 /* vector */),
343a4f484bcSWei Liu     Ignore,
344a4f484bcSWei Liu     Reset,
345093a581eSMichael Zhao     Shutdown,
346da642fcfSRob Bradford     Hyperv,
347cb844ecdSSebastien Boeuf     #[cfg(feature = "tdx")]
348cb844ecdSSebastien Boeuf     Tdx,
3499f111388SAkira Moroo     #[cfg(feature = "kvm")]
3509f111388SAkira Moroo     Debug,
351a4f484bcSWei Liu }
352a4f484bcSWei Liu 
353f9b51a41SMuminul Islam ///
354f9b51a41SMuminul Islam /// Result type for returning from a function
355f9b51a41SMuminul Islam ///
356f9b51a41SMuminul Islam pub type Result<T> = anyhow::Result<T, HypervisorCpuError>;
357f9b51a41SMuminul Islam ///
358f9b51a41SMuminul Islam /// Trait to represent a generic Vcpu
359f9b51a41SMuminul Islam ///
360f9b51a41SMuminul Islam pub trait Vcpu: Send + Sync {
361f9b51a41SMuminul Islam     ///
3623645654cSJinank Jain     /// Returns StandardRegisters with default value set
3633645654cSJinank Jain     ///
create_standard_regs(&self) -> StandardRegisters3643645654cSJinank Jain     fn create_standard_regs(&self) -> StandardRegisters {
3653645654cSJinank Jain         unimplemented!();
3663645654cSJinank Jain     }
3673645654cSJinank Jain     ///
368f9b51a41SMuminul Islam     /// Returns the vCPU general purpose registers.
369f9b51a41SMuminul Islam     ///
get_regs(&self) -> Result<StandardRegisters>370f9b51a41SMuminul Islam     fn get_regs(&self) -> Result<StandardRegisters>;
371f9b51a41SMuminul Islam     ///
372f9b51a41SMuminul Islam     /// Sets the vCPU general purpose registers.
373f9b51a41SMuminul Islam     ///
set_regs(&self, regs: &StandardRegisters) -> Result<()>374f9b51a41SMuminul Islam     fn set_regs(&self, regs: &StandardRegisters) -> Result<()>;
375f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
376f9b51a41SMuminul Islam     ///
377f9b51a41SMuminul Islam     /// Returns the vCPU special registers.
378f9b51a41SMuminul Islam     ///
get_sregs(&self) -> Result<SpecialRegisters>379f9b51a41SMuminul Islam     fn get_sregs(&self) -> Result<SpecialRegisters>;
380f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
381f9b51a41SMuminul Islam     ///
382f9b51a41SMuminul Islam     /// Sets the vCPU special registers
383f9b51a41SMuminul Islam     ///
set_sregs(&self, sregs: &SpecialRegisters) -> Result<()>384f9b51a41SMuminul Islam     fn set_sregs(&self, sregs: &SpecialRegisters) -> Result<()>;
385f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
386f9b51a41SMuminul Islam     ///
387f9b51a41SMuminul Islam     /// Returns the floating point state (FPU) from the vCPU.
388f9b51a41SMuminul Islam     ///
get_fpu(&self) -> Result<FpuState>389f9b51a41SMuminul Islam     fn get_fpu(&self) -> Result<FpuState>;
390f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
391f9b51a41SMuminul Islam     ///
392f9b51a41SMuminul Islam     /// Set the floating point state (FPU) of a vCPU
393f9b51a41SMuminul Islam     ///
set_fpu(&self, fpu: &FpuState) -> Result<()>394f9b51a41SMuminul Islam     fn set_fpu(&self, fpu: &FpuState) -> Result<()>;
395f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
396f9b51a41SMuminul Islam     ///
397f9b51a41SMuminul Islam     /// X86 specific call to setup the CPUID registers.
398f9b51a41SMuminul Islam     ///
set_cpuid2(&self, cpuid: &[CpuIdEntry]) -> Result<()>39945fbf840SWei Liu     fn set_cpuid2(&self, cpuid: &[CpuIdEntry]) -> Result<()>;
400f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
401f9b51a41SMuminul Islam     ///
4029b48ee38SRob Bradford     /// X86 specific call to enable HyperV SynIC
4039b48ee38SRob Bradford     ///
enable_hyperv_synic(&self) -> Result<()>4049b48ee38SRob Bradford     fn enable_hyperv_synic(&self) -> Result<()>;
4059b48ee38SRob Bradford     #[cfg(target_arch = "x86_64")]
4069b48ee38SRob Bradford     ///
407f9b51a41SMuminul Islam     /// X86 specific call to retrieve the CPUID registers.
408f9b51a41SMuminul Islam     ///
get_cpuid2(&self, num_entries: usize) -> Result<Vec<CpuIdEntry>>40945fbf840SWei Liu     fn get_cpuid2(&self, num_entries: usize) -> Result<Vec<CpuIdEntry>>;
410f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
411f9b51a41SMuminul Islam     ///
412f9b51a41SMuminul Islam     /// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
413f9b51a41SMuminul Islam     ///
get_lapic(&self) -> Result<LapicState>414f9b51a41SMuminul Islam     fn get_lapic(&self) -> Result<LapicState>;
415f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
416f9b51a41SMuminul Islam     ///
417f9b51a41SMuminul Islam     /// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
418f9b51a41SMuminul Islam     ///
set_lapic(&self, lapic: &LapicState) -> Result<()>419f9b51a41SMuminul Islam     fn set_lapic(&self, lapic: &LapicState) -> Result<()>;
420f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
421f9b51a41SMuminul Islam     ///
422f9b51a41SMuminul Islam     /// Returns the model-specific registers (MSR) for this vCPU.
423f9b51a41SMuminul Islam     ///
get_msrs(&self, msrs: &mut Vec<MsrEntry>) -> Result<usize>4244d2cc377SWei Liu     fn get_msrs(&self, msrs: &mut Vec<MsrEntry>) -> Result<usize>;
425f9b51a41SMuminul Islam     #[cfg(target_arch = "x86_64")]
426f9b51a41SMuminul Islam     ///
427f9b51a41SMuminul Islam     /// Setup the model-specific registers (MSR) for this vCPU.
428f9b51a41SMuminul Islam     ///
set_msrs(&self, msrs: &[MsrEntry]) -> Result<usize>4294d2cc377SWei Liu     fn set_msrs(&self, msrs: &[MsrEntry]) -> Result<usize>;
430f9b51a41SMuminul Islam     ///
431f9b51a41SMuminul Islam     /// Returns the vcpu's current "multiprocessing state".
432f9b51a41SMuminul Islam     ///
get_mp_state(&self) -> Result<MpState>433f9b51a41SMuminul Islam     fn get_mp_state(&self) -> Result<MpState>;
434f9b51a41SMuminul Islam     ///
435f9b51a41SMuminul Islam     /// Sets the vcpu's current "multiprocessing state".
436f9b51a41SMuminul Islam     ///
set_mp_state(&self, mp_state: MpState) -> Result<()>437f9b51a41SMuminul Islam     fn set_mp_state(&self, mp_state: MpState) -> Result<()>;
438ae7f74d0SWei Liu     #[cfg(target_arch = "x86_64")]
439e2b5c78dSSebastien Boeuf     ///
440309924ecSSebastien Boeuf     /// Let the guest know that it has been paused, which prevents from
441309924ecSSebastien Boeuf     /// potential soft lockups when being resumed.
442309924ecSSebastien Boeuf     ///
notify_guest_clock_paused(&self) -> Result<()>443ae7f74d0SWei Liu     fn notify_guest_clock_paused(&self) -> Result<()> {
444ae7f74d0SWei Liu         Ok(())
445ae7f74d0SWei Liu     }
4469f27954fSAkira Moroo     ///
4479f27954fSAkira Moroo     /// Sets debug registers to set hardware breakpoints and/or enable single step.
4489f27954fSAkira Moroo     ///
44971053534SRuoqing He     #[cfg(not(target_arch = "riscv64"))]
set_guest_debug(&self, _addrs: &[GuestAddress], _singlestep: bool) -> Result<()>450ae7f74d0SWei Liu     fn set_guest_debug(&self, _addrs: &[GuestAddress], _singlestep: bool) -> Result<()> {
451ae7f74d0SWei Liu         Err(HypervisorCpuError::SetDebugRegs(anyhow!("unimplemented")))
452ae7f74d0SWei Liu     }
453f9b51a41SMuminul Islam     ///
454f9b51a41SMuminul Islam     /// Sets the type of CPU to be exposed to the guest and optional features.
455f9b51a41SMuminul Islam     ///
456f0ad7fc7SMichael Zhao     #[cfg(target_arch = "aarch64")]
vcpu_init(&self, kvi: &VcpuInit) -> Result<()>457f9b51a41SMuminul Islam     fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>;
458d2a364c5SWenyu Huang 
459d2a364c5SWenyu Huang     #[cfg(target_arch = "aarch64")]
vcpu_finalize(&self, feature: i32) -> Result<()>460d2a364c5SWenyu Huang     fn vcpu_finalize(&self, feature: i32) -> Result<()>;
461171b28ceSJinank Jain     ///
462171b28ceSJinank Jain     /// Gets the features that have been finalized for a given CPU.
463171b28ceSJinank Jain     ///
464171b28ceSJinank Jain     #[cfg(target_arch = "aarch64")]
vcpu_get_finalized_features(&self) -> i32465171b28ceSJinank Jain     fn vcpu_get_finalized_features(&self) -> i32;
466171b28ceSJinank Jain     ///
467171b28ceSJinank Jain     /// Sets processor features for a given CPU.
468171b28ceSJinank Jain     ///
469171b28ceSJinank Jain     #[cfg(target_arch = "aarch64")]
vcpu_set_processor_features( &self, vm: &Arc<dyn crate::Vm>, kvi: &mut VcpuInit, id: u8, ) -> Result<()>470171b28ceSJinank Jain     fn vcpu_set_processor_features(
471171b28ceSJinank Jain         &self,
472171b28ceSJinank Jain         vm: &Arc<dyn crate::Vm>,
473171b28ceSJinank Jain         kvi: &mut VcpuInit,
474171b28ceSJinank Jain         id: u8,
475171b28ceSJinank Jain     ) -> Result<()>;
476171b28ceSJinank Jain     ///
477171b28ceSJinank Jain     /// Returns VcpuInit with default value set
478171b28ceSJinank Jain     ///
479171b28ceSJinank Jain     #[cfg(target_arch = "aarch64")]
create_vcpu_init(&self) -> VcpuInit480171b28ceSJinank Jain     fn create_vcpu_init(&self) -> VcpuInit;
481f9b51a41SMuminul Islam     ///
482ffafeda4SHenry Wang     /// Gets a list of the guest registers that are supported for the
483ffafeda4SHenry Wang     /// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
484ffafeda4SHenry Wang     ///
48571053534SRuoqing He     #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
get_reg_list(&self, reg_list: &mut RegList) -> Result<()>486ffafeda4SHenry Wang     fn get_reg_list(&self, reg_list: &mut RegList) -> Result<()>;
487ffafeda4SHenry Wang     ///
4885b54dc60SMichael Zhao     /// Gets the value of a system register
4895b54dc60SMichael Zhao     ///
4905b54dc60SMichael Zhao     #[cfg(target_arch = "aarch64")]
get_sys_reg(&self, sys_reg: u32) -> Result<u64>4915b54dc60SMichael Zhao     fn get_sys_reg(&self, sys_reg: u32) -> Result<u64>;
4925b54dc60SMichael Zhao     ///
49371053534SRuoqing He     /// Gets the value of a non-core register on RISC-V 64-bit
49471053534SRuoqing He     ///
49571053534SRuoqing He     #[cfg(target_arch = "riscv64")]
get_non_core_reg(&self, non_core_reg: u32) -> Result<u64>49671053534SRuoqing He     fn get_non_core_reg(&self, non_core_reg: u32) -> Result<u64>;
49771053534SRuoqing He     ///
498a7a15d56SMichael Zhao     /// Configure core registers for a given CPU.
499a7a15d56SMichael Zhao     ///
50071053534SRuoqing He     #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> Result<()>501a7a15d56SMichael Zhao     fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> Result<()>;
502a7a15d56SMichael Zhao     ///
503f84ddedbSWei Liu     /// Check if the CPU supports PMU
504f84ddedbSWei Liu     ///
505f84ddedbSWei Liu     #[cfg(target_arch = "aarch64")]
has_pmu_support(&self) -> bool506f84ddedbSWei Liu     fn has_pmu_support(&self) -> bool;
507f84ddedbSWei Liu     ///
508f84ddedbSWei Liu     /// Initialize PMU
509f84ddedbSWei Liu     ///
510f84ddedbSWei Liu     #[cfg(target_arch = "aarch64")]
init_pmu(&self, irq: u32) -> Result<()>511f84ddedbSWei Liu     fn init_pmu(&self, irq: u32) -> Result<()>;
512f84ddedbSWei Liu     ///
513618722cdSSamuel Ortiz     /// Retrieve the vCPU state.
514618722cdSSamuel Ortiz     /// This function is necessary to snapshot the VM
515f9b51a41SMuminul Islam     ///
state(&self) -> Result<CpuState>516618722cdSSamuel Ortiz     fn state(&self) -> Result<CpuState>;
517f9b51a41SMuminul Islam     ///
518618722cdSSamuel Ortiz     /// Set the vCPU state.
519f9b51a41SMuminul Islam     /// This function is required when restoring the VM
520f9b51a41SMuminul Islam     ///
set_state(&self, state: &CpuState) -> Result<()>521618722cdSSamuel Ortiz     fn set_state(&self, state: &CpuState) -> Result<()>;
522a4f484bcSWei Liu     ///
523a4f484bcSWei Liu     /// Triggers the running of the current virtual CPU returning an exit reason.
524a4f484bcSWei Liu     ///
run(&self) -> std::result::Result<VmExit, HypervisorCpuError>525a4f484bcSWei Liu     fn run(&self) -> std::result::Result<VmExit, HypervisorCpuError>;
526603ca0e2SAkira Moroo     #[cfg(target_arch = "x86_64")]
52774565538SWei Liu     ///
52874565538SWei Liu     /// Translate guest virtual address to guest physical address
52974565538SWei Liu     ///
translate_gva(&self, gva: u64, flags: u64) -> Result<(u64, u32)>5307c6bdf88SAkira Moroo     fn translate_gva(&self, gva: u64, flags: u64) -> Result<(u64, u32)>;
531f282cc00SRob Bradford     ///
532f282cc00SRob Bradford     /// Initialize TDX support on the vCPU
533f282cc00SRob Bradford     ///
534f282cc00SRob Bradford     #[cfg(feature = "tdx")]
tdx_init(&self, _hob_address: u64) -> Result<()>535b8503b5fSRob Bradford     fn tdx_init(&self, _hob_address: u64) -> Result<()> {
536b8503b5fSRob Bradford         unimplemented!()
537b8503b5fSRob Bradford     }
53850791238SRob Bradford     ///
53950791238SRob Bradford     /// Set the "immediate_exit" state
54050791238SRob Bradford     ///
set_immediate_exit(&self, _exit: bool)541ae7f74d0SWei Liu     fn set_immediate_exit(&self, _exit: bool) {}
542cb844ecdSSebastien Boeuf     #[cfg(feature = "tdx")]
543cb844ecdSSebastien Boeuf     ///
544cb844ecdSSebastien Boeuf     /// Returns the details about TDX exit reason
545cb844ecdSSebastien Boeuf     ///
get_tdx_exit_details(&mut self) -> Result<TdxExitDetails>546b8503b5fSRob Bradford     fn get_tdx_exit_details(&mut self) -> Result<TdxExitDetails> {
547b8503b5fSRob Bradford         unimplemented!()
548b8503b5fSRob Bradford     }
549cb844ecdSSebastien Boeuf     #[cfg(feature = "tdx")]
550cb844ecdSSebastien Boeuf     ///
551cb844ecdSSebastien Boeuf     /// Set the status code for TDX exit
552cb844ecdSSebastien Boeuf     ///
set_tdx_status(&mut self, _status: TdxExitStatus)553b8503b5fSRob Bradford     fn set_tdx_status(&mut self, _status: TdxExitStatus) {
554b8503b5fSRob Bradford         unimplemented!()
555b8503b5fSRob Bradford     }
55684bbaf06SWei Liu     #[cfg(target_arch = "x86_64")]
55784bbaf06SWei Liu     ///
55884bbaf06SWei Liu     /// Return the list of initial MSR entries for a VCPU
55984bbaf06SWei Liu     ///
boot_msr_entries(&self) -> Vec<MsrEntry>5604d2cc377SWei Liu     fn boot_msr_entries(&self) -> Vec<MsrEntry>;
56144f200d6SRob Bradford 
562c22c4675SRob Bradford     #[cfg(target_arch = "x86_64")]
563c22c4675SRob Bradford     ///
564c22c4675SRob Bradford     /// Get the frequency of the TSC if available
565c22c4675SRob Bradford     ///
tsc_khz(&self) -> Result<Option<u32>>566c22c4675SRob Bradford     fn tsc_khz(&self) -> Result<Option<u32>> {
567c22c4675SRob Bradford         Ok(None)
568c22c4675SRob Bradford     }
56944f200d6SRob Bradford     #[cfg(target_arch = "x86_64")]
57044f200d6SRob Bradford     ///
57144f200d6SRob Bradford     /// Set the frequency of the TSC if available
57244f200d6SRob Bradford     ///
set_tsc_khz(&self, _freq: u32) -> Result<()>57344f200d6SRob Bradford     fn set_tsc_khz(&self, _freq: u32) -> Result<()> {
57444f200d6SRob Bradford         Ok(())
57544f200d6SRob Bradford     }
576ec79820bSMuminul Islam     #[cfg(target_arch = "x86_64")]
577ec79820bSMuminul Islam     ///
578ec79820bSMuminul Islam     /// X86 specific call to retrieve cpuid leaf
579ec79820bSMuminul Islam     ///
get_cpuid_values( &self, _function: u32, _index: u32, _xfem: u64, _xss: u64, ) -> Result<[u32; 4]>580ec79820bSMuminul Islam     fn get_cpuid_values(
581ec79820bSMuminul Islam         &self,
582ec79820bSMuminul Islam         _function: u32,
583ec79820bSMuminul Islam         _index: u32,
584ec79820bSMuminul Islam         _xfem: u64,
585ec79820bSMuminul Islam         _xss: u64,
586ec79820bSMuminul Islam     ) -> Result<[u32; 4]> {
587ec79820bSMuminul Islam         unimplemented!()
588ec79820bSMuminul Islam     }
5895368ff28SMuminul Islam     #[cfg(feature = "mshv")]
set_sev_control_register(&self, _reg: u64) -> Result<()>5905368ff28SMuminul Islam     fn set_sev_control_register(&self, _reg: u64) -> Result<()> {
5915368ff28SMuminul Islam         unimplemented!()
5925368ff28SMuminul Islam     }
593fa2b5ca1SJinank Jain     ///
594fa2b5ca1SJinank Jain     /// Sets the value of GIC redistributor address
595fa2b5ca1SJinank Jain     ///
596fa2b5ca1SJinank Jain     #[cfg(target_arch = "aarch64")]
set_gic_redistributor_addr(&self, _gicr_base_addr: u64) -> Result<()>597fa2b5ca1SJinank Jain     fn set_gic_redistributor_addr(&self, _gicr_base_addr: u64) -> Result<()> {
598fa2b5ca1SJinank Jain         Ok(())
599fa2b5ca1SJinank Jain     }
600c72bf0b3SYi Wang     #[cfg(target_arch = "x86_64")]
601c72bf0b3SYi Wang     ///
602c72bf0b3SYi Wang     /// Trigger NMI interrupt
603c72bf0b3SYi Wang     ///
nmi(&self) -> Result<()>604cd116cb2SJinank Jain     fn nmi(&self) -> Result<()>;
605f9b51a41SMuminul Islam }
606