xref: /cloud-hypervisor/hypervisor/src/vm.rs (revision 72c81783358b641709a16112a45a7ffd52f58f3f)
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