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