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 /// 46f9b51a41SMuminul Islam #[error("Failed to set standard register: {0}")] 47f9b51a41SMuminul Islam SetStandardRegs(#[source] anyhow::Error), 48f9b51a41SMuminul Islam /// 49f9b51a41SMuminul Islam /// Setting standard registers error 50f9b51a41SMuminul Islam /// 51f9b51a41SMuminul Islam #[error("Failed to get standard registers: {0}")] 52f9b51a41SMuminul Islam GetStandardRegs(#[source] anyhow::Error), 53f9b51a41SMuminul Islam /// 54f9b51a41SMuminul Islam /// Setting special register error 55f9b51a41SMuminul Islam /// 56f9b51a41SMuminul Islam #[error("Failed to set special registers: {0}")] 57f9b51a41SMuminul Islam SetSpecialRegs(#[source] anyhow::Error), 58f9b51a41SMuminul Islam /// 59f9b51a41SMuminul Islam /// Getting standard register error 60f9b51a41SMuminul Islam /// 61f9b51a41SMuminul Islam #[error("Failed to get special registers: {0}")] 62f9b51a41SMuminul Islam GetSpecialRegs(#[source] anyhow::Error), 63f9b51a41SMuminul Islam /// 64f9b51a41SMuminul Islam /// Setting floating point registers error 65f9b51a41SMuminul Islam /// 667a686897SJinank Jain #[error("Failed to set floating point registers: {0}")] 67f9b51a41SMuminul Islam SetFloatingPointRegs(#[source] anyhow::Error), 68f9b51a41SMuminul Islam /// 69f9b51a41SMuminul Islam /// Getting floating point register error 70f9b51a41SMuminul Islam /// 717a686897SJinank Jain #[error("Failed to get floating points registers: {0}")] 72f9b51a41SMuminul Islam GetFloatingPointRegs(#[source] anyhow::Error), 73f9b51a41SMuminul Islam /// 74f9b51a41SMuminul Islam /// Setting Cpuid error 75f9b51a41SMuminul Islam /// 76f9b51a41SMuminul Islam #[error("Failed to set Cpuid: {0}")] 77f9b51a41SMuminul Islam SetCpuid(#[source] anyhow::Error), 78f9b51a41SMuminul Islam /// 79f9b51a41SMuminul Islam /// Getting Cpuid error 80f9b51a41SMuminul Islam /// 81f9b51a41SMuminul Islam #[error("Failed to get Cpuid: {0}")] 82f9b51a41SMuminul Islam GetCpuid(#[source] anyhow::Error), 83f9b51a41SMuminul Islam /// 84f9b51a41SMuminul Islam /// Setting lapic state error 85f9b51a41SMuminul Islam /// 86f9b51a41SMuminul Islam #[error("Failed to set Lapic state: {0}")] 87f9b51a41SMuminul Islam SetLapicState(#[source] anyhow::Error), 88f9b51a41SMuminul Islam /// 89f9b51a41SMuminul Islam /// Getting Lapic state error 90f9b51a41SMuminul Islam /// 91f9b51a41SMuminul Islam #[error("Failed to get Lapic state: {0}")] 92f9b51a41SMuminul Islam GetlapicState(#[source] anyhow::Error), 93f9b51a41SMuminul Islam /// 94f9b51a41SMuminul Islam /// Setting MSR entries error 95f9b51a41SMuminul Islam /// 96f9b51a41SMuminul Islam #[error("Failed to set Msr entries: {0}")] 97f9b51a41SMuminul Islam SetMsrEntries(#[source] anyhow::Error), 98f9b51a41SMuminul Islam /// 99f9b51a41SMuminul Islam /// Getting Msr entries error 100f9b51a41SMuminul Islam /// 101f9b51a41SMuminul Islam #[error("Failed to get Msr entries: {0}")] 102f9b51a41SMuminul Islam GetMsrEntries(#[source] anyhow::Error), 103f9b51a41SMuminul Islam /// 1047d5ea5caSMuminul Islam /// Setting multi-processing state error 105f9b51a41SMuminul Islam /// 106f9b51a41SMuminul Islam #[error("Failed to set MP state: {0}")] 107f9b51a41SMuminul Islam SetMpState(#[source] anyhow::Error), 108f9b51a41SMuminul Islam /// 1097d5ea5caSMuminul Islam /// Getting multi-processing state error 110f9b51a41SMuminul Islam /// 111f9b51a41SMuminul Islam #[error("Failed to get MP state: {0}")] 112f9b51a41SMuminul Islam GetMpState(#[source] anyhow::Error), 113f9b51a41SMuminul Islam /// 114f9b51a41SMuminul Islam /// Setting Saved Processor Extended States error 115f9b51a41SMuminul Islam /// 116512591baSMuminul Islam #[cfg(feature = "kvm")] 117f9b51a41SMuminul Islam #[error("Failed to set Saved Processor Extended States: {0}")] 118f9b51a41SMuminul Islam SetXsaveState(#[source] anyhow::Error), 119f9b51a41SMuminul Islam /// 120f9b51a41SMuminul Islam /// Getting Saved Processor Extended States error 121f9b51a41SMuminul Islam /// 122512591baSMuminul Islam #[cfg(feature = "kvm")] 123f9b51a41SMuminul Islam #[error("Failed to get Saved Processor Extended States: {0}")] 124f9b51a41SMuminul Islam GetXsaveState(#[source] anyhow::Error), 125f9b51a41SMuminul Islam /// 126512591baSMuminul Islam /// Getting the VP state components error 127512591baSMuminul Islam /// 128512591baSMuminul Islam #[cfg(feature = "mshv")] 129512591baSMuminul Islam #[error("Failed to get VP State Components: {0}")] 130512591baSMuminul Islam GetAllVpStateComponents(#[source] anyhow::Error), 131512591baSMuminul Islam /// 132512591baSMuminul Islam /// Setting the VP state components error 133512591baSMuminul Islam /// 134512591baSMuminul Islam #[cfg(feature = "mshv")] 135512591baSMuminul Islam #[error("Failed to set VP State Components: {0}")] 136512591baSMuminul Islam SetAllVpStateComponents(#[source] anyhow::Error), 137512591baSMuminul Islam /// 138f9b51a41SMuminul Islam /// Setting Extended Control Registers error 139f9b51a41SMuminul Islam /// 140f9b51a41SMuminul Islam #[error("Failed to set Extended Control Registers: {0}")] 141f9b51a41SMuminul Islam SetXcsr(#[source] anyhow::Error), 142f9b51a41SMuminul Islam /// 143f9b51a41SMuminul Islam /// Getting Extended Control Registers error 144f9b51a41SMuminul Islam /// 145f9b51a41SMuminul Islam #[error("Failed to get Extended Control Registers: {0}")] 146f9b51a41SMuminul Islam GetXcsr(#[source] anyhow::Error), 147f9b51a41SMuminul Islam /// 148f9b51a41SMuminul Islam /// Running Vcpu error 149f9b51a41SMuminul Islam /// 150f9b51a41SMuminul Islam #[error("Failed to run vcpu: {0}")] 151f9b51a41SMuminul Islam RunVcpu(#[source] anyhow::Error), 152f9b51a41SMuminul Islam /// 153f9b51a41SMuminul Islam /// Getting Vcpu events error 154f9b51a41SMuminul Islam /// 155f9b51a41SMuminul Islam #[error("Failed to get Vcpu events: {0}")] 156f9b51a41SMuminul Islam GetVcpuEvents(#[source] anyhow::Error), 157f9b51a41SMuminul Islam /// 158e2b5c78dSSebastien Boeuf /// Setting Vcpu events error 159e2b5c78dSSebastien Boeuf /// 160e2b5c78dSSebastien Boeuf #[error("Failed to set Vcpu events: {0}")] 161e2b5c78dSSebastien Boeuf SetVcpuEvents(#[source] anyhow::Error), 162e2b5c78dSSebastien Boeuf /// 163f9b51a41SMuminul Islam /// Vcpu Init error 164f9b51a41SMuminul Islam /// 165f9b51a41SMuminul Islam #[error("Failed to init vcpu: {0}")] 166f9b51a41SMuminul Islam VcpuInit(#[source] anyhow::Error), 167f9b51a41SMuminul Islam /// 168d2a364c5SWenyu Huang /// Vcpu Finalize error 169d2a364c5SWenyu Huang /// 170d2a364c5SWenyu Huang #[error("Failed to finalize vcpu: {0}")] 171d2a364c5SWenyu Huang VcpuFinalize(#[source] anyhow::Error), 172d2a364c5SWenyu Huang /// 173f9b51a41SMuminul Islam /// Setting one reg error 174f9b51a41SMuminul Islam /// 175e9f137dcSRuoqing He #[error("Failed to set one reg: {0}")] 176ed1fdd1fSWei Liu SetRegister(#[source] anyhow::Error), 177f9b51a41SMuminul Islam /// 178f9b51a41SMuminul Islam /// Getting one reg error 179f9b51a41SMuminul Islam /// 180e9f137dcSRuoqing He #[error("Failed to get one reg: {0}")] 181ed1fdd1fSWei Liu GetRegister(#[source] anyhow::Error), 182309924ecSSebastien Boeuf /// 183309924ecSSebastien Boeuf /// Getting guest clock paused error 184309924ecSSebastien Boeuf /// 185309924ecSSebastien Boeuf #[error("Failed to notify guest its clock was paused: {0}")] 186309924ecSSebastien Boeuf NotifyGuestClockPaused(#[source] anyhow::Error), 1879b48ee38SRob Bradford /// 18823c46b16SMuminul Islam /// Setting debug register error 18923c46b16SMuminul Islam /// 19023c46b16SMuminul Islam #[error("Failed to set debug registers: {0}")] 19123c46b16SMuminul Islam SetDebugRegs(#[source] anyhow::Error), 19223c46b16SMuminul Islam /// 19323c46b16SMuminul Islam /// Getting debug register error 19423c46b16SMuminul Islam /// 19523c46b16SMuminul Islam #[error("Failed to get debug registers: {0}")] 19623c46b16SMuminul Islam GetDebugRegs(#[source] anyhow::Error), 19723c46b16SMuminul Islam /// 198c3d6aceeSMuminul Islam /// Setting misc register error 199c3d6aceeSMuminul Islam /// 200c3d6aceeSMuminul Islam #[error("Failed to set misc registers: {0}")] 201c3d6aceeSMuminul Islam SetMiscRegs(#[source] anyhow::Error), 202c3d6aceeSMuminul Islam /// 203c3d6aceeSMuminul Islam /// Getting misc register error 204c3d6aceeSMuminul Islam /// 205c3d6aceeSMuminul Islam #[error("Failed to get misc registers: {0}")] 206c3d6aceeSMuminul Islam GetMiscRegs(#[source] anyhow::Error), 207c3d6aceeSMuminul Islam /// 20823c46b16SMuminul Islam /// Write to Guest Mem 20923c46b16SMuminul Islam /// 21023c46b16SMuminul Islam #[error("Failed to write to Guest Mem at: {0}")] 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 /// 2192668dbbdSRuoqing He #[error("Failed to get aarch64 core register: {0}")] 2202668dbbdSRuoqing He GetAarchCoreRegister(#[source] anyhow::Error), 221ffafeda4SHenry Wang /// 222ffafeda4SHenry Wang /// Setting AArch64 core register error 223ffafeda4SHenry Wang /// 2242668dbbdSRuoqing He #[error("Failed to set aarch64 core register: {0}")] 2252668dbbdSRuoqing He SetAarchCoreRegister(#[source] anyhow::Error), 226ffafeda4SHenry Wang /// 227c13019d5SRuoqing He /// Getting RISC-V 64-bit core register error 228c13019d5SRuoqing He /// 229c13019d5SRuoqing He #[error("Failed to get riscv64 core register: {0}")] 230c13019d5SRuoqing He GetRiscvCoreRegister(#[source] anyhow::Error), 231c13019d5SRuoqing He /// 232c13019d5SRuoqing He /// Setting RISC-V 64-bit core register error 233c13019d5SRuoqing He /// 234c13019d5SRuoqing He #[error("Failed to set riscv64 core register: {0}")] 235c13019d5SRuoqing He SetRiscvCoreRegister(#[source] anyhow::Error), 236c13019d5SRuoqing He /// 237e8697735SRuoqing He /// Getting registers list error 238ffafeda4SHenry Wang /// 239ffafeda4SHenry Wang #[error("Failed to retrieve list of registers: {0}")] 240ffafeda4SHenry Wang GetRegList(#[source] anyhow::Error), 241ffafeda4SHenry Wang /// 242e3d45be6SHenry Wang /// Getting AArch64 system register error 243e3d45be6SHenry Wang /// 244e3d45be6SHenry Wang #[error("Failed to get system register: {0}")] 245e3d45be6SHenry Wang GetSysRegister(#[source] anyhow::Error), 246ffafeda4SHenry Wang /// 247ffafeda4SHenry Wang /// Setting AArch64 system register error 248ffafeda4SHenry Wang /// 249ffafeda4SHenry Wang #[error("Failed to set system register: {0}")] 250ffafeda4SHenry Wang SetSysRegister(#[source] anyhow::Error), 25174565538SWei Liu /// 252c13019d5SRuoqing He /// Getting RISC-V 64-bit non-core register error 253c13019d5SRuoqing He /// 254c13019d5SRuoqing He #[error("Failed to get non-core register: {0}")] 255c13019d5SRuoqing He GetNonCoreRegister(#[source] anyhow::Error), 256c13019d5SRuoqing He /// 257c13019d5SRuoqing He /// Setting RISC-V 64-bit non-core register error 258c13019d5SRuoqing He /// 259c13019d5SRuoqing He #[error("Failed to set non-core register: {0}")] 260c13019d5SRuoqing He SetNonCoreRegister(#[source] anyhow::Error), 261c13019d5SRuoqing He /// 26274565538SWei Liu /// GVA translation error 26374565538SWei Liu /// 26474565538SWei Liu #[error("Failed to translate GVA: {0}")] 2650c27f69fSRob Bradford TranslateVirtualAddress(#[source] anyhow::Error), 266f282cc00SRob Bradford /// 2679bcb9849SJianyong Wu /// Set cpu attribute error 2689bcb9849SJianyong Wu /// 2699bcb9849SJianyong Wu #[error("Failed to set vcpu attribute: {0}")] 2709bcb9849SJianyong Wu SetVcpuAttribute(#[source] anyhow::Error), 2719bcb9849SJianyong Wu /// 2729bcb9849SJianyong Wu /// Check if cpu has a certain attribute error 2739bcb9849SJianyong Wu /// 2749bcb9849SJianyong Wu #[error("Failed to check if vcpu has attribute: {0}")] 2759bcb9849SJianyong Wu HasVcpuAttribute(#[source] anyhow::Error), 2769bcb9849SJianyong Wu /// 277f282cc00SRob Bradford /// Failed to initialize TDX on CPU 278f282cc00SRob Bradford /// 279f282cc00SRob Bradford #[cfg(feature = "tdx")] 280f282cc00SRob Bradford #[error("Failed to initialize TDX: {0}")] 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 /// 298c22c4675SRob Bradford #[error("Failed to get TSC frequency: {0}")] 299c22c4675SRob Bradford GetTscKhz(#[source] anyhow::Error), 30044f200d6SRob Bradford /// 30144f200d6SRob Bradford /// Error setting TSC frequency 30244f200d6SRob Bradford /// 30344f200d6SRob Bradford #[error("Failed to set TSC frequency: {0}")] 30444f200d6SRob Bradford SetTscKhz(#[source] anyhow::Error), 305cb5ea059SJinank Jain /// 306cb5ea059SJinank Jain /// Error reading value at given GPA 307cb5ea059SJinank Jain /// 308cb5ea059SJinank Jain #[error("Failed to read from GPA: {0}")] 309cb5ea059SJinank Jain GpaRead(#[source] anyhow::Error), 310cb5ea059SJinank Jain /// 311cb5ea059SJinank Jain /// Error writing value at given GPA 312cb5ea059SJinank Jain /// 313cb5ea059SJinank Jain #[error("Failed to write to GPA: {0}")] 314cb5ea059SJinank Jain GpaWrite(#[source] anyhow::Error), 315ec79820bSMuminul Islam /// 316ec79820bSMuminul Islam /// Error getting CPUID leaf 317ec79820bSMuminul Islam /// 318ec79820bSMuminul Islam #[error("Failed to get CPUID entries: {0}")] 319ec79820bSMuminul Islam GetCpuidVales(#[source] anyhow::Error), 3205368ff28SMuminul Islam /// 3215368ff28SMuminul Islam /// Setting SEV control register error 3225368ff28SMuminul Islam /// 3235368ff28SMuminul Islam #[cfg(feature = "sev_snp")] 3245368ff28SMuminul Islam #[error("Failed to set sev control register: {0}")] 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 /// 3643645654cSJinank Jain fn create_standard_regs(&self) -> StandardRegisters { 3653645654cSJinank Jain unimplemented!(); 3663645654cSJinank Jain } 3673645654cSJinank Jain /// 368f9b51a41SMuminul Islam /// Returns the vCPU general purpose registers. 369f9b51a41SMuminul Islam /// 370f9b51a41SMuminul Islam fn get_regs(&self) -> Result<StandardRegisters>; 371f9b51a41SMuminul Islam /// 372f9b51a41SMuminul Islam /// Sets the vCPU general purpose registers. 373f9b51a41SMuminul Islam /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 4294d2cc377SWei Liu fn set_msrs(&self, msrs: &[MsrEntry]) -> Result<usize>; 430f9b51a41SMuminul Islam /// 431f9b51a41SMuminul Islam /// Returns the vcpu's current "multiprocessing state". 432f9b51a41SMuminul Islam /// 433f9b51a41SMuminul Islam fn get_mp_state(&self) -> Result<MpState>; 434f9b51a41SMuminul Islam /// 435f9b51a41SMuminul Islam /// Sets the vcpu's current "multiprocessing state". 436f9b51a41SMuminul Islam /// 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 /// 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"))] 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")] 457f9b51a41SMuminul Islam fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>; 458d2a364c5SWenyu Huang 459d2a364c5SWenyu Huang #[cfg(target_arch = "aarch64")] 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")] 465171b28ceSJinank 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")] 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")] 480171b28ceSJinank 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"))] 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")] 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")] 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"))] 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")] 506f84ddedbSWei Liu fn has_pmu_support(&self) -> bool; 507f84ddedbSWei Liu /// 508f84ddedbSWei Liu /// Initialize PMU 509f84ddedbSWei Liu /// 510f84ddedbSWei Liu #[cfg(target_arch = "aarch64")] 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 /// 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 /// 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 /// 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 /// 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")] 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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")] 5905368ff28SMuminul Islam fn set_sev_control_register(&self, _reg: u64) -> Result<()> { 5915368ff28SMuminul Islam unimplemented!() 5925368ff28SMuminul Islam } 593*fa2b5ca1SJinank Jain /// 594*fa2b5ca1SJinank Jain /// Sets the value of GIC redistributor address 595*fa2b5ca1SJinank Jain /// 596*fa2b5ca1SJinank Jain #[cfg(target_arch = "aarch64")] 597*fa2b5ca1SJinank Jain fn set_gic_redistributor_addr(&self, _gicr_base_addr: u64) -> Result<()> { 598*fa2b5ca1SJinank Jain Ok(()) 599*fa2b5ca1SJinank Jain } 600c72bf0b3SYi Wang #[cfg(target_arch = "x86_64")] 601c72bf0b3SYi Wang /// 602c72bf0b3SYi Wang /// Trigger NMI interrupt 603c72bf0b3SYi Wang /// 604cd116cb2SJinank Jain fn nmi(&self) -> Result<()>; 605f9b51a41SMuminul Islam } 606