15e937c8bSRuoqing He // Copyright © 2024 Institute of Software, CAS. All rights reserved. 25e937c8bSRuoqing He // 3f5afc288SMuminul Islam // Copyright © 2019 Intel Corporation 4f5afc288SMuminul Islam // 572ae1577SMuminul Islam // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 6f5afc288SMuminul Islam // 7f5afc288SMuminul Islam // Copyright © 2020, Microsoft Corporation 8f5afc288SMuminul Islam // 9f5afc288SMuminul Islam // Copyright 2018-2019 CrowdStrike, Inc. 10f5afc288SMuminul Islam // 11f5afc288SMuminul Islam // 12f5afc288SMuminul Islam 1388a9f799SRob Bradford use std::any::Any; 1488a9f799SRob Bradford #[cfg(target_arch = "x86_64")] 1588a9f799SRob Bradford use std::fs::File; 1688a9f799SRob Bradford use std::sync::Arc; 175e937c8bSRuoqing He #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] 1888a9f799SRob Bradford use std::sync::Mutex; 1988a9f799SRob Bradford 2088a9f799SRob Bradford #[cfg(feature = "sev_snp")] 2188a9f799SRob Bradford use igvm_defs::IGVM_VHS_SNP_ID_BLOCK; 2288a9f799SRob Bradford use thiserror::Error; 2388a9f799SRob Bradford use vmm_sys_util::eventfd::EventFd; 2488a9f799SRob Bradford 25f5afc288SMuminul Islam #[cfg(target_arch = "aarch64")] 26784a3aafSNuno Das Neves use crate::arch::aarch64::gic::{Vgic, VgicConfig}; 275e937c8bSRuoqing He #[cfg(target_arch = "riscv64")] 285e937c8bSRuoqing He use crate::arch::riscv64::aia::{Vaia, VaiaConfig}; 2908135fa0SWei Liu #[cfg(feature = "tdx")] 3008135fa0SWei Liu use crate::arch::x86::CpuIdEntry; 31f5afc288SMuminul Islam use crate::cpu::Vcpu; 324201bf40SWei Liu #[cfg(target_arch = "x86_64")] 3368ec0eb7SSebastien Boeuf use crate::ClockData; 3461e57e1cSRuoqing He use crate::{IoEventAddress, IrqRoutingEntry, UserMemoryRegion}; 35f5afc288SMuminul Islam 36f5afc288SMuminul Islam /// 37f5afc288SMuminul Islam /// I/O events data matches (32 or 64 bits). 38f5afc288SMuminul Islam /// 3923c46b16SMuminul Islam #[derive(Debug)] 40f5afc288SMuminul Islam pub enum DataMatch { 41f5afc288SMuminul Islam DataMatch32(u32), 42f5afc288SMuminul Islam DataMatch64(u64), 43f5afc288SMuminul Islam } 44f5afc288SMuminul Islam 45e2946889SRob Bradford impl From<DataMatch> for u64 { from(dm: DataMatch) -> u6446e2946889SRob Bradford fn from(dm: DataMatch) -> u64 { 47e2946889SRob Bradford match dm { 48f5afc288SMuminul Islam DataMatch::DataMatch32(dm) => dm.into(), 49f5afc288SMuminul Islam DataMatch::DataMatch64(dm) => dm, 50f5afc288SMuminul Islam } 51f5afc288SMuminul Islam } 52f5afc288SMuminul Islam } 53f5afc288SMuminul Islam 54f5afc288SMuminul Islam #[derive(Error, Debug)] 55f5afc288SMuminul Islam /// 56f5afc288SMuminul Islam /// Enum for VM error 57f5afc288SMuminul Islam pub enum HypervisorVmError { 58f5afc288SMuminul Islam /// 59f5afc288SMuminul Islam /// Create Vcpu error 60f5afc288SMuminul Islam /// 61*72c81783SPhilipp Schuster #[error("Failed to create Vcpu")] 62f5afc288SMuminul Islam CreateVcpu(#[source] anyhow::Error), 63f5afc288SMuminul Islam /// 64c452471cSSebastien Boeuf /// Identity map address error 65c452471cSSebastien Boeuf /// 66*72c81783SPhilipp Schuster #[error("Failed to set identity map address")] 67c452471cSSebastien Boeuf SetIdentityMapAddress(#[source] anyhow::Error), 68c452471cSSebastien Boeuf /// 69f5afc288SMuminul Islam /// TSS address error 70f5afc288SMuminul Islam /// 71*72c81783SPhilipp Schuster #[error("Failed to set TSS address")] 72f5afc288SMuminul Islam SetTssAddress(#[source] anyhow::Error), 73f5afc288SMuminul Islam /// 74f5afc288SMuminul Islam /// Create interrupt controller error 75f5afc288SMuminul Islam /// 76*72c81783SPhilipp Schuster #[error("Failed to create interrupt controller")] 77f5afc288SMuminul Islam CreateIrq(#[source] anyhow::Error), 78f5afc288SMuminul Islam /// 79f5afc288SMuminul Islam /// Register interrupt event error 80f5afc288SMuminul Islam /// 81*72c81783SPhilipp Schuster #[error("Failed to register interrupt event")] 82f5afc288SMuminul Islam RegisterIrqFd(#[source] anyhow::Error), 83f5afc288SMuminul Islam /// 84f5afc288SMuminul Islam /// Un register interrupt event error 85f5afc288SMuminul Islam /// 86*72c81783SPhilipp Schuster #[error("Failed to unregister interrupt event")] 87f5afc288SMuminul Islam UnregisterIrqFd(#[source] anyhow::Error), 88f5afc288SMuminul Islam /// 89f5afc288SMuminul Islam /// Register IO event error 90f5afc288SMuminul Islam /// 91*72c81783SPhilipp Schuster #[error("Failed to register IO event")] 92f5afc288SMuminul Islam RegisterIoEvent(#[source] anyhow::Error), 93f5afc288SMuminul Islam /// 94f5afc288SMuminul Islam /// Unregister IO event error 95f5afc288SMuminul Islam /// 96*72c81783SPhilipp Schuster #[error("Failed to unregister IO event")] 97f5afc288SMuminul Islam UnregisterIoEvent(#[source] anyhow::Error), 98f5afc288SMuminul Islam /// 99f5afc288SMuminul Islam /// Set GSI routing error 100f5afc288SMuminul Islam /// 101*72c81783SPhilipp Schuster #[error("Failed to set GSI routing")] 102f5afc288SMuminul Islam SetGsiRouting(#[source] anyhow::Error), 103f5afc288SMuminul Islam /// 1041f2915bfSWei Liu /// Create user memory error 105f5afc288SMuminul Islam /// 106*72c81783SPhilipp Schuster #[error("Failed to create user memory")] 1071f2915bfSWei Liu CreateUserMemory(#[source] anyhow::Error), 1081f2915bfSWei Liu /// 1091f2915bfSWei Liu /// Remove user memory region error 1101f2915bfSWei Liu /// 111*72c81783SPhilipp Schuster #[error("Failed to remove user memory")] 1121f2915bfSWei Liu RemoveUserMemory(#[source] anyhow::Error), 113f5afc288SMuminul Islam /// 114f5afc288SMuminul Islam /// Create device error 115f5afc288SMuminul Islam /// 116*72c81783SPhilipp Schuster #[error("Failed to set GSI routing")] 117f5afc288SMuminul Islam CreateDevice(#[source] anyhow::Error), 118f5afc288SMuminul Islam /// 119f5afc288SMuminul Islam /// Get preferred target error 120f5afc288SMuminul Islam /// 121*72c81783SPhilipp Schuster #[error("Failed to get preferred target")] 122f5afc288SMuminul Islam GetPreferredTarget(#[source] anyhow::Error), 123f5afc288SMuminul Islam /// 124f5afc288SMuminul Islam /// Enable split Irq error 125f5afc288SMuminul Islam /// 126*72c81783SPhilipp Schuster #[error("Failed to enable split Irq")] 127f5afc288SMuminul Islam EnableSplitIrq(#[source] anyhow::Error), 12868ec0eb7SSebastien Boeuf /// 1299ec0c981SSebastien Boeuf /// Enable SGX attribute error 1309ec0c981SSebastien Boeuf /// 131*72c81783SPhilipp Schuster #[error("Failed to enable SGX attribute")] 1329ec0c981SSebastien Boeuf EnableSgxAttribute(#[source] anyhow::Error), 1339ec0c981SSebastien Boeuf /// 13468ec0eb7SSebastien Boeuf /// Get clock error 13568ec0eb7SSebastien Boeuf /// 136*72c81783SPhilipp Schuster #[error("Failed to get clock")] 13768ec0eb7SSebastien Boeuf GetClock(#[source] anyhow::Error), 13868ec0eb7SSebastien Boeuf /// 13968ec0eb7SSebastien Boeuf /// Set clock error 14068ec0eb7SSebastien Boeuf /// 141*72c81783SPhilipp Schuster #[error("Failed to set clock")] 14268ec0eb7SSebastien Boeuf SetClock(#[source] anyhow::Error), 143ff8d7bfeSWei Liu /// 144ff8d7bfeSWei Liu /// Create passthrough device 145ff8d7bfeSWei Liu /// 146*72c81783SPhilipp Schuster #[error("Failed to create passthrough device")] 147ff8d7bfeSWei Liu CreatePassthroughDevice(#[source] anyhow::Error), 14871c435ceSPraveen Paladugu /// Write to Guest memory 14971c435ceSPraveen Paladugu /// 150*72c81783SPhilipp Schuster #[error("Failed to write to guest memory")] 15171c435ceSPraveen Paladugu GuestMemWrite(#[source] anyhow::Error), 15271c435ceSPraveen Paladugu /// 15371c435ceSPraveen Paladugu /// Read Guest memory 15471c435ceSPraveen Paladugu /// 155*72c81783SPhilipp Schuster #[error("Failed to read guest memory")] 15671c435ceSPraveen Paladugu GuestMemRead(#[source] anyhow::Error), 15771c435ceSPraveen Paladugu /// 15871c435ceSPraveen Paladugu /// Read from MMIO Bus 15971c435ceSPraveen Paladugu /// 160*72c81783SPhilipp Schuster #[error("Failed to read from MMIO Bus")] 16171c435ceSPraveen Paladugu MmioBusRead(#[source] anyhow::Error), 16271c435ceSPraveen Paladugu /// 16371c435ceSPraveen Paladugu /// Write to MMIO Bus 16471c435ceSPraveen Paladugu /// 165*72c81783SPhilipp Schuster #[error("Failed to write to MMIO Bus")] 16671c435ceSPraveen Paladugu MmioBusWrite(#[source] anyhow::Error), 16771c435ceSPraveen Paladugu /// 16871c435ceSPraveen Paladugu /// Read from IO Bus 16971c435ceSPraveen Paladugu /// 170*72c81783SPhilipp Schuster #[error("Failed to read from IO Bus")] 17171c435ceSPraveen Paladugu IoBusRead(#[source] anyhow::Error), 17271c435ceSPraveen Paladugu /// 17371c435ceSPraveen Paladugu /// Write to IO Bus 17471c435ceSPraveen Paladugu /// 175*72c81783SPhilipp Schuster #[error("Failed to write to IO Bus")] 17671c435ceSPraveen Paladugu IoBusWrite(#[source] anyhow::Error), 177041724a7SRob Bradford /// 1785e0d4985SBo Chen /// Start dirty log error 1795e0d4985SBo Chen /// 180*72c81783SPhilipp Schuster #[error("Failed to get dirty log")] 1815e0d4985SBo Chen StartDirtyLog(#[source] anyhow::Error), 1825e0d4985SBo Chen /// 1835e0d4985SBo Chen /// Stop dirty log error 1845e0d4985SBo Chen /// 185*72c81783SPhilipp Schuster #[error("Failed to get dirty log")] 1865e0d4985SBo Chen StopDirtyLog(#[source] anyhow::Error), 1875e0d4985SBo Chen /// 188041724a7SRob Bradford /// Get dirty log error 189041724a7SRob Bradford /// 190*72c81783SPhilipp Schuster #[error("Failed to get dirty log")] 191041724a7SRob Bradford GetDirtyLog(#[source] anyhow::Error), 192fd0ef6cfSMuminul Islam /// 193fd0ef6cfSMuminul Islam /// Assert virtual interrupt error 194fd0ef6cfSMuminul Islam /// 195*72c81783SPhilipp Schuster #[error("Failed to assert virtual Interrupt")] 19642e9632cSJosh Soref AssertVirtualInterrupt(#[source] anyhow::Error), 197f282cc00SRob Bradford 1981b59ab3dSJinank Jain #[cfg(feature = "sev_snp")] 1991b59ab3dSJinank Jain /// 2001b59ab3dSJinank Jain /// Error initializing SEV-SNP on the VM 2011b59ab3dSJinank Jain /// 202*72c81783SPhilipp Schuster #[error("Failed to initialize SEV-SNP")] 2031b59ab3dSJinank Jain InitializeSevSnp(#[source] std::io::Error), 2041b59ab3dSJinank Jain 205f282cc00SRob Bradford #[cfg(feature = "tdx")] 206f282cc00SRob Bradford /// 207f282cc00SRob Bradford /// Error initializing TDX on the VM 208f282cc00SRob Bradford /// 209*72c81783SPhilipp Schuster #[error("Failed to initialize TDX")] 210f282cc00SRob Bradford InitializeTdx(#[source] std::io::Error), 211f282cc00SRob Bradford #[cfg(feature = "tdx")] 212f282cc00SRob Bradford /// 213f282cc00SRob Bradford /// Error finalizing the TDX configuration on the VM 214f282cc00SRob Bradford /// 215*72c81783SPhilipp Schuster #[error("Failed to finalize TDX")] 216f282cc00SRob Bradford FinalizeTdx(#[source] std::io::Error), 217f282cc00SRob Bradford #[cfg(feature = "tdx")] 218f282cc00SRob Bradford /// 219f282cc00SRob Bradford /// Error initializing the TDX memory region 220f282cc00SRob Bradford /// 221*72c81783SPhilipp Schuster #[error("Failed to initialize memory region TDX")] 222f282cc00SRob Bradford InitMemRegionTdx(#[source] std::io::Error), 223c2862b69SMichael Zhao /// 224c2862b69SMichael Zhao /// Create Vgic error 225c2862b69SMichael Zhao /// 226*72c81783SPhilipp Schuster #[error("Failed to create Vgic")] 227c2862b69SMichael Zhao CreateVgic(#[source] anyhow::Error), 228dc390301SMuminul Islam /// 2295e937c8bSRuoqing He /// Create Vaia error 2305e937c8bSRuoqing He /// 231*72c81783SPhilipp Schuster #[error("Failed to create Vaia")] 2325e937c8bSRuoqing He CreateVaia(#[source] anyhow::Error), 2335e937c8bSRuoqing He /// 234dc390301SMuminul Islam /// Import isolated pages error 235dc390301SMuminul Islam /// 236*72c81783SPhilipp Schuster #[error("Failed to import isolated pages")] 237dc390301SMuminul Islam ImportIsolatedPages(#[source] anyhow::Error), 2385bd113e6SMuminul Islam /// Failed to complete isolated import 2395bd113e6SMuminul Islam /// 240*72c81783SPhilipp Schuster #[error("Failed to complete isolated import")] 2415bd113e6SMuminul Islam CompleteIsolatedImport(#[source] anyhow::Error), 242aabfc951SMuminul Islam /// Failed to set VM property 243aabfc951SMuminul Islam /// 244*72c81783SPhilipp Schuster #[error("Failed to set VM property")] 245aabfc951SMuminul Islam SetVmProperty(#[source] anyhow::Error), 2465c4b5c0eSMuminul Islam /// 2475c4b5c0eSMuminul Islam /// Modify GPA host access error 2485c4b5c0eSMuminul Islam /// 2495c4b5c0eSMuminul Islam #[cfg(feature = "sev_snp")] 250*72c81783SPhilipp Schuster #[error("Failed to modify GPA host access")] 2515c4b5c0eSMuminul Islam ModifyGpaHostAccess(#[source] anyhow::Error), 2521757d83dSMuminul Islam /// 2531757d83dSMuminul Islam /// Failed to mmap 2541757d83dSMuminul Islam /// 2551757d83dSMuminul Islam #[cfg(feature = "sev_snp")] 2561757d83dSMuminul Islam #[error("Failed to mmap:")] 2571757d83dSMuminul Islam MmapToRoot, 258f16d45e8SJinank Jain /// 259f16d45e8SJinank Jain /// Failed to initialize VM 260f16d45e8SJinank Jain /// 261*72c81783SPhilipp Schuster #[error("Failed to initialize VM")] 262f16d45e8SJinank Jain InitializeVm(#[source] anyhow::Error), 263f5afc288SMuminul Islam } 264f5afc288SMuminul Islam /// 265f5afc288SMuminul Islam /// Result type for returning from a function 266f5afc288SMuminul Islam /// 267f5afc288SMuminul Islam pub type Result<T> = std::result::Result<T, HypervisorVmError>; 268f5afc288SMuminul Islam 2693ffc105fSRob Bradford /// Configuration data for legacy interrupts. 2703ffc105fSRob Bradford /// 2713ffc105fSRob Bradford /// On x86 platforms, legacy interrupts means those interrupts routed through PICs or IOAPICs. 2723ffc105fSRob Bradford #[derive(Copy, Clone, Debug)] 2733ffc105fSRob Bradford pub struct LegacyIrqSourceConfig { 2743ffc105fSRob Bradford pub irqchip: u32, 2753ffc105fSRob Bradford pub pin: u32, 2763ffc105fSRob Bradford } 2773ffc105fSRob Bradford 2783ffc105fSRob Bradford /// Configuration data for MSI/MSI-X interrupts. 2793ffc105fSRob Bradford /// 2803ffc105fSRob Bradford /// On x86 platforms, these interrupts are vectors delivered directly to the LAPIC. 2813ffc105fSRob Bradford #[derive(Copy, Clone, Debug, Default)] 2823ffc105fSRob Bradford pub struct MsiIrqSourceConfig { 2833ffc105fSRob Bradford /// High address to delivery message signaled interrupt. 2843ffc105fSRob Bradford pub high_addr: u32, 2853ffc105fSRob Bradford /// Low address to delivery message signaled interrupt. 2863ffc105fSRob Bradford pub low_addr: u32, 2873ffc105fSRob Bradford /// Data to write to delivery message signaled interrupt. 2883ffc105fSRob Bradford pub data: u32, 2893ffc105fSRob Bradford /// Unique ID of the device to delivery message signaled interrupt. 2903ffc105fSRob Bradford pub devid: u32, 2913ffc105fSRob Bradford } 2923ffc105fSRob Bradford 2933ffc105fSRob Bradford /// Configuration data for an interrupt source. 2943ffc105fSRob Bradford #[derive(Copy, Clone, Debug)] 2953ffc105fSRob Bradford pub enum InterruptSourceConfig { 2963ffc105fSRob Bradford /// Configuration data for Legacy interrupts. 2973ffc105fSRob Bradford LegacyIrq(LegacyIrqSourceConfig), 2983ffc105fSRob Bradford /// Configuration data for PciMsi, PciMsix and generic MSI interrupts. 2993ffc105fSRob Bradford MsiIrq(MsiIrqSourceConfig), 3003ffc105fSRob Bradford } 3013ffc105fSRob Bradford 302f5afc288SMuminul Islam /// 303f5afc288SMuminul Islam /// Trait to represent a Vm 304f5afc288SMuminul Islam /// 305f5afc288SMuminul Islam /// This crate provides a hypervisor-agnostic interfaces for Vm 306f5afc288SMuminul Islam /// 307b5270e0bSWei Liu pub trait Vm: Send + Sync + Any { 308f5afc288SMuminul Islam #[cfg(target_arch = "x86_64")] 309c452471cSSebastien Boeuf /// Sets the address of the one-page region in the VM's address space. set_identity_map_address(&self, address: u64) -> Result<()>310c452471cSSebastien Boeuf fn set_identity_map_address(&self, address: u64) -> Result<()>; 311c452471cSSebastien Boeuf #[cfg(target_arch = "x86_64")] 312f5afc288SMuminul Islam /// Sets the address of the three-page region in the VM's address space. set_tss_address(&self, offset: usize) -> Result<()>313f5afc288SMuminul Islam fn set_tss_address(&self, offset: usize) -> Result<()>; 3145e937c8bSRuoqing He #[cfg(not(target_arch = "riscv64"))] 315f5afc288SMuminul Islam /// Creates an in-kernel interrupt controller. create_irq_chip(&self) -> Result<()>316f5afc288SMuminul Islam fn create_irq_chip(&self) -> Result<()>; 317f5afc288SMuminul Islam /// Registers an event that will, when signaled, trigger the `gsi` IRQ. register_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>318f5afc288SMuminul Islam fn register_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>; 319f5afc288SMuminul Islam /// Unregister an event that will, when signaled, trigger the `gsi` IRQ. unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>320f5afc288SMuminul Islam fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>; 321f5afc288SMuminul Islam /// Creates a new KVM vCPU file descriptor and maps the memory corresponding create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>322387d5687SRob Bradford fn create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>; 323c2862b69SMichael Zhao #[cfg(target_arch = "aarch64")] create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>324784a3aafSNuno Das Neves fn create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>; 3255e937c8bSRuoqing He #[cfg(target_arch = "riscv64")] create_vaia(&self, config: VaiaConfig) -> Result<Arc<Mutex<dyn Vaia>>>3265e937c8bSRuoqing He fn create_vaia(&self, config: VaiaConfig) -> Result<Arc<Mutex<dyn Vaia>>>; 327c2862b69SMichael Zhao 328f5afc288SMuminul Islam /// Registers an event to be signaled whenever a certain address is written to. register_ioevent( &self, fd: &EventFd, addr: &IoEventAddress, datamatch: Option<DataMatch>, ) -> Result<()>329f5afc288SMuminul Islam fn register_ioevent( 330f5afc288SMuminul Islam &self, 331f5afc288SMuminul Islam fd: &EventFd, 332f5afc288SMuminul Islam addr: &IoEventAddress, 333f5afc288SMuminul Islam datamatch: Option<DataMatch>, 334f5afc288SMuminul Islam ) -> Result<()>; 335f5afc288SMuminul Islam /// Unregister an event from a certain address it has been previously registered to. unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>336f5afc288SMuminul Islam fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>; 3373f9e8d67SRob Bradford // Construct a routing entry make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry3383f9e8d67SRob Bradford fn make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry; 339f5afc288SMuminul Islam /// Sets the GSI routing table entries, overwriting any previously set set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> Result<()>340e1af251cSWei Liu fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> Result<()>; 3411f2915bfSWei Liu /// Creates a memory region structure that can be used with {create/remove}_user_memory_region make_user_memory_region( &self, slot: u32, guest_phys_addr: u64, memory_size: u64, userspace_addr: u64, readonly: bool, log_dirty_pages: bool, ) -> UserMemoryRegion342cfa758fbSWei Liu fn make_user_memory_region( 343cfa758fbSWei Liu &self, 344cfa758fbSWei Liu slot: u32, 345cfa758fbSWei Liu guest_phys_addr: u64, 346cfa758fbSWei Liu memory_size: u64, 347cfa758fbSWei Liu userspace_addr: u64, 348cfa758fbSWei Liu readonly: bool, 3498baa244eSRob Bradford log_dirty_pages: bool, 350e1cf889dSWei Liu ) -> UserMemoryRegion; 3511f2915bfSWei Liu /// Creates a guest physical memory slot. create_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>352e1cf889dSWei Liu fn create_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>; 3531f2915bfSWei Liu /// Removes a guest physical memory slot. remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>354e1cf889dSWei Liu fn remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>; 355f5afc288SMuminul Islam /// Returns the preferred CPU target type which can be emulated by KVM on underlying host. 356f0ad7fc7SMichael Zhao #[cfg(target_arch = "aarch64")] get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> Result<()>3575b929cb2SJinank Jain fn get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> Result<()>; 358f5afc288SMuminul Islam /// Enable split Irq capability 359f5afc288SMuminul Islam #[cfg(target_arch = "x86_64")] enable_split_irq(&self) -> Result<()>360f5afc288SMuminul Islam fn enable_split_irq(&self) -> Result<()>; 3619ec0c981SSebastien Boeuf #[cfg(target_arch = "x86_64")] enable_sgx_attribute(&self, file: File) -> Result<()>3629ec0c981SSebastien Boeuf fn enable_sgx_attribute(&self, file: File) -> Result<()>; 36368ec0eb7SSebastien Boeuf /// Retrieve guest clock. 3644201bf40SWei Liu #[cfg(target_arch = "x86_64")] get_clock(&self) -> Result<ClockData>36568ec0eb7SSebastien Boeuf fn get_clock(&self) -> Result<ClockData>; 36668ec0eb7SSebastien Boeuf /// Set guest clock. 3674201bf40SWei Liu #[cfg(target_arch = "x86_64")] set_clock(&self, data: &ClockData) -> Result<()>36868ec0eb7SSebastien Boeuf fn set_clock(&self, data: &ClockData) -> Result<()>; 369ff8d7bfeSWei Liu /// Create a device that is used for passthrough create_passthrough_device(&self) -> Result<vfio_ioctls::VfioDeviceFd>370a96a5d78SWei Liu fn create_passthrough_device(&self) -> Result<vfio_ioctls::VfioDeviceFd>; 3715e0d4985SBo Chen /// Start logging dirty pages start_dirty_log(&self) -> Result<()>372e7c9954dSBo Chen fn start_dirty_log(&self) -> Result<()>; 3735e0d4985SBo Chen /// Stop logging dirty pages stop_dirty_log(&self) -> Result<()>374e7c9954dSBo Chen fn stop_dirty_log(&self) -> Result<()>; 375041724a7SRob Bradford /// Get dirty pages bitmap get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>376fdecba69SMuminul Islam fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>; 3771b59ab3dSJinank Jain #[cfg(feature = "sev_snp")] 3781b59ab3dSJinank Jain /// Initialize SEV-SNP on this VM sev_snp_init(&self) -> Result<()>3791b59ab3dSJinank Jain fn sev_snp_init(&self) -> Result<()> { 3801b59ab3dSJinank Jain unimplemented!() 3811b59ab3dSJinank Jain } 382f282cc00SRob Bradford #[cfg(feature = "tdx")] 3837bf0cc1eSPhilipp Schuster /// Initialize TDX on this VM tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()>384b8503b5fSRob Bradford fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> { 385b8503b5fSRob Bradford unimplemented!() 386b8503b5fSRob Bradford } 387f282cc00SRob Bradford #[cfg(feature = "tdx")] 388f282cc00SRob Bradford /// Finalize the configuration of TDX on this VM tdx_finalize(&self) -> Result<()>389b8503b5fSRob Bradford fn tdx_finalize(&self) -> Result<()> { 390b8503b5fSRob Bradford unimplemented!() 391b8503b5fSRob Bradford } 392f282cc00SRob Bradford #[cfg(feature = "tdx")] 3937bf0cc1eSPhilipp Schuster /// Initialize a TDX memory region for this VM tdx_init_memory_region( &self, _host_address: u64, _guest_address: u64, _size: u64, _measure: bool, ) -> Result<()>394f282cc00SRob Bradford fn tdx_init_memory_region( 395f282cc00SRob Bradford &self, 396b8503b5fSRob Bradford _host_address: u64, 397b8503b5fSRob Bradford _guest_address: u64, 398b8503b5fSRob Bradford _size: u64, 399b8503b5fSRob Bradford _measure: bool, 400b8503b5fSRob Bradford ) -> Result<()> { 401b8503b5fSRob Bradford unimplemented!() 402b8503b5fSRob Bradford } 403b5270e0bSWei Liu /// Downcast to the underlying hypervisor VM type as_any(&self) -> &dyn Any404b5270e0bSWei Liu fn as_any(&self) -> &dyn Any; 405dc390301SMuminul Islam /// Import the isolated pages 406dc390301SMuminul Islam #[cfg(feature = "sev_snp")] import_isolated_pages( &self, _page_type: u32, _page_size: u32, _pages: &[u64], ) -> Result<()>407dc390301SMuminul Islam fn import_isolated_pages( 408dc390301SMuminul Islam &self, 409dc390301SMuminul Islam _page_type: u32, 410dc390301SMuminul Islam _page_size: u32, 411dc390301SMuminul Islam _pages: &[u64], 412dc390301SMuminul Islam ) -> Result<()> { 413dc390301SMuminul Islam unimplemented!() 414dc390301SMuminul Islam } 4155bd113e6SMuminul Islam /// Complete the isolated import 4165bd113e6SMuminul Islam #[cfg(feature = "sev_snp")] complete_isolated_import( &self, _snp_id_block: IGVM_VHS_SNP_ID_BLOCK, _host_data: [u8; 32], _id_block_enabled: u8, ) -> Result<()>4175bd113e6SMuminul Islam fn complete_isolated_import( 4185bd113e6SMuminul Islam &self, 4195bd113e6SMuminul Islam _snp_id_block: IGVM_VHS_SNP_ID_BLOCK, 420cbcbf635SMuminul Islam _host_data: [u8; 32], 4215bd113e6SMuminul Islam _id_block_enabled: u8, 4225bd113e6SMuminul Islam ) -> Result<()> { 4235bd113e6SMuminul Islam unimplemented!() 4245bd113e6SMuminul Islam } 425f16d45e8SJinank Jain /// Initialize the VM init(&self) -> Result<()>426f16d45e8SJinank Jain fn init(&self) -> Result<()> { 427f16d45e8SJinank Jain Ok(()) 428f16d45e8SJinank Jain } 4293fe9b877SMuminul Islam /// Pause the VM pause(&self) -> Result<()>4303fe9b877SMuminul Islam fn pause(&self) -> Result<()> { 4313fe9b877SMuminul Islam Ok(()) 4323fe9b877SMuminul Islam } 4333fe9b877SMuminul Islam 4343fe9b877SMuminul Islam /// Resume the VM resume(&self) -> Result<()>4353fe9b877SMuminul Islam fn resume(&self) -> Result<()> { 4363fe9b877SMuminul Islam Ok(()) 4373fe9b877SMuminul Islam } 4385c4b5c0eSMuminul Islam 4395c4b5c0eSMuminul Islam #[cfg(feature = "sev_snp")] gain_page_access(&self, _gpa: u64, _size: u32) -> Result<()>4405c4b5c0eSMuminul Islam fn gain_page_access(&self, _gpa: u64, _size: u32) -> Result<()> { 4415c4b5c0eSMuminul Islam Ok(()) 4425c4b5c0eSMuminul Islam } 44371c435ceSPraveen Paladugu } 44471c435ceSPraveen Paladugu 445387d5687SRob Bradford pub trait VmOps: Send + Sync { guest_mem_write(&self, gpa: u64, buf: &[u8]) -> Result<usize>4465fc12862SWei Liu fn guest_mem_write(&self, gpa: u64, buf: &[u8]) -> Result<usize>; guest_mem_read(&self, gpa: u64, buf: &mut [u8]) -> Result<usize>4475fc12862SWei Liu fn guest_mem_read(&self, gpa: u64, buf: &mut [u8]) -> Result<usize>; mmio_read(&self, gpa: u64, data: &mut [u8]) -> Result<()>4485fc12862SWei Liu fn mmio_read(&self, gpa: u64, data: &mut [u8]) -> Result<()>; mmio_write(&self, gpa: u64, data: &[u8]) -> Result<()>4495fc12862SWei Liu fn mmio_write(&self, gpa: u64, data: &[u8]) -> Result<()>; 45071c435ceSPraveen Paladugu #[cfg(target_arch = "x86_64")] pio_read(&self, port: u64, data: &mut [u8]) -> Result<()>4515fc12862SWei Liu fn pio_read(&self, port: u64, data: &mut [u8]) -> Result<()>; 45271c435ceSPraveen Paladugu #[cfg(target_arch = "x86_64")] pio_write(&self, port: u64, data: &[u8]) -> Result<()>4535fc12862SWei Liu fn pio_write(&self, port: u64, data: &[u8]) -> Result<()>; 454f5afc288SMuminul Islam } 455