xref: /cloud-hypervisor/hypervisor/src/vm.rs (revision 1757d83db38a74db5bfba4f658ab14a25b51fb3f)
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")]
26f5afc288SMuminul Islam use crate::aarch64::VcpuInit;
27c2862b69SMichael Zhao #[cfg(target_arch = "aarch64")]
28784a3aafSNuno Das Neves use crate::arch::aarch64::gic::{Vgic, VgicConfig};
295e937c8bSRuoqing He #[cfg(target_arch = "riscv64")]
305e937c8bSRuoqing He use crate::arch::riscv64::aia::{Vaia, VaiaConfig};
3108135fa0SWei Liu #[cfg(feature = "tdx")]
3208135fa0SWei Liu use crate::arch::x86::CpuIdEntry;
33f5afc288SMuminul Islam use crate::cpu::Vcpu;
344201bf40SWei Liu #[cfg(target_arch = "x86_64")]
3568ec0eb7SSebastien Boeuf use crate::ClockData;
3661e57e1cSRuoqing He use crate::{IoEventAddress, IrqRoutingEntry, UserMemoryRegion};
37f5afc288SMuminul Islam 
38f5afc288SMuminul Islam ///
39f5afc288SMuminul Islam /// I/O events data matches (32 or 64 bits).
40f5afc288SMuminul Islam ///
4123c46b16SMuminul Islam #[derive(Debug)]
42f5afc288SMuminul Islam pub enum DataMatch {
43f5afc288SMuminul Islam     DataMatch32(u32),
44f5afc288SMuminul Islam     DataMatch64(u64),
45f5afc288SMuminul Islam }
46f5afc288SMuminul Islam 
47e2946889SRob Bradford impl From<DataMatch> for u64 {
48e2946889SRob Bradford     fn from(dm: DataMatch) -> u64 {
49e2946889SRob Bradford         match dm {
50f5afc288SMuminul Islam             DataMatch::DataMatch32(dm) => dm.into(),
51f5afc288SMuminul Islam             DataMatch::DataMatch64(dm) => dm,
52f5afc288SMuminul Islam         }
53f5afc288SMuminul Islam     }
54f5afc288SMuminul Islam }
55f5afc288SMuminul Islam 
56f5afc288SMuminul Islam #[derive(Error, Debug)]
57f5afc288SMuminul Islam ///
58f5afc288SMuminul Islam /// Enum for VM error
59f5afc288SMuminul Islam pub enum HypervisorVmError {
60f5afc288SMuminul Islam     ///
61f5afc288SMuminul Islam     /// Create Vcpu error
62f5afc288SMuminul Islam     ///
63f5afc288SMuminul Islam     #[error("Failed to create Vcpu: {0}")]
64f5afc288SMuminul Islam     CreateVcpu(#[source] anyhow::Error),
65f5afc288SMuminul Islam     ///
66c452471cSSebastien Boeuf     /// Identity map address error
67c452471cSSebastien Boeuf     ///
68c452471cSSebastien Boeuf     #[error("Failed to set identity map address: {0}")]
69c452471cSSebastien Boeuf     SetIdentityMapAddress(#[source] anyhow::Error),
70c452471cSSebastien Boeuf     ///
71f5afc288SMuminul Islam     /// TSS address error
72f5afc288SMuminul Islam     ///
73f5afc288SMuminul Islam     #[error("Failed to set TSS address: {0}")]
74f5afc288SMuminul Islam     SetTssAddress(#[source] anyhow::Error),
75f5afc288SMuminul Islam     ///
76f5afc288SMuminul Islam     /// Create interrupt controller error
77f5afc288SMuminul Islam     ///
78f5afc288SMuminul Islam     #[error("Failed to create interrupt controller: {0}")]
79f5afc288SMuminul Islam     CreateIrq(#[source] anyhow::Error),
80f5afc288SMuminul Islam     ///
81f5afc288SMuminul Islam     /// Register interrupt event error
82f5afc288SMuminul Islam     ///
83f5afc288SMuminul Islam     #[error("Failed to register interrupt event: {0}")]
84f5afc288SMuminul Islam     RegisterIrqFd(#[source] anyhow::Error),
85f5afc288SMuminul Islam     ///
86f5afc288SMuminul Islam     /// Un register interrupt event error
87f5afc288SMuminul Islam     ///
88f5afc288SMuminul Islam     #[error("Failed to unregister interrupt event: {0}")]
89f5afc288SMuminul Islam     UnregisterIrqFd(#[source] anyhow::Error),
90f5afc288SMuminul Islam     ///
91f5afc288SMuminul Islam     /// Register IO event error
92f5afc288SMuminul Islam     ///
93f5afc288SMuminul Islam     #[error("Failed to register IO event: {0}")]
94f5afc288SMuminul Islam     RegisterIoEvent(#[source] anyhow::Error),
95f5afc288SMuminul Islam     ///
96f5afc288SMuminul Islam     /// Unregister IO event error
97f5afc288SMuminul Islam     ///
98f5afc288SMuminul Islam     #[error("Failed to unregister IO event: {0}")]
99f5afc288SMuminul Islam     UnregisterIoEvent(#[source] anyhow::Error),
100f5afc288SMuminul Islam     ///
101f5afc288SMuminul Islam     /// Set GSI routing error
102f5afc288SMuminul Islam     ///
103f5afc288SMuminul Islam     #[error("Failed to set GSI routing: {0}")]
104f5afc288SMuminul Islam     SetGsiRouting(#[source] anyhow::Error),
105f5afc288SMuminul Islam     ///
1061f2915bfSWei Liu     /// Create user memory error
107f5afc288SMuminul Islam     ///
1081f2915bfSWei Liu     #[error("Failed to create user memory: {0}")]
1091f2915bfSWei Liu     CreateUserMemory(#[source] anyhow::Error),
1101f2915bfSWei Liu     ///
1111f2915bfSWei Liu     /// Remove user memory region error
1121f2915bfSWei Liu     ///
1131f2915bfSWei Liu     #[error("Failed to remove user memory: {0}")]
1141f2915bfSWei Liu     RemoveUserMemory(#[source] anyhow::Error),
115f5afc288SMuminul Islam     ///
116f5afc288SMuminul Islam     /// Create device error
117f5afc288SMuminul Islam     ///
118f5afc288SMuminul Islam     #[error("Failed to set GSI routing: {0}")]
119f5afc288SMuminul Islam     CreateDevice(#[source] anyhow::Error),
120f5afc288SMuminul Islam     ///
121f5afc288SMuminul Islam     /// Get preferred target error
122f5afc288SMuminul Islam     ///
123f5afc288SMuminul Islam     #[error("Failed to get preferred target: {0}")]
124f5afc288SMuminul Islam     GetPreferredTarget(#[source] anyhow::Error),
125f5afc288SMuminul Islam     ///
126f5afc288SMuminul Islam     /// Enable split Irq error
127f5afc288SMuminul Islam     ///
128f5afc288SMuminul Islam     #[error("Failed to enable split Irq: {0}")]
129f5afc288SMuminul Islam     EnableSplitIrq(#[source] anyhow::Error),
13068ec0eb7SSebastien Boeuf     ///
1319ec0c981SSebastien Boeuf     /// Enable SGX attribute error
1329ec0c981SSebastien Boeuf     ///
1339ec0c981SSebastien Boeuf     #[error("Failed to enable SGX attribute: {0}")]
1349ec0c981SSebastien Boeuf     EnableSgxAttribute(#[source] anyhow::Error),
1359ec0c981SSebastien Boeuf     ///
13668ec0eb7SSebastien Boeuf     /// Get clock error
13768ec0eb7SSebastien Boeuf     ///
13868ec0eb7SSebastien Boeuf     #[error("Failed to get clock: {0}")]
13968ec0eb7SSebastien Boeuf     GetClock(#[source] anyhow::Error),
14068ec0eb7SSebastien Boeuf     ///
14168ec0eb7SSebastien Boeuf     /// Set clock error
14268ec0eb7SSebastien Boeuf     ///
14368ec0eb7SSebastien Boeuf     #[error("Failed to set clock: {0}")]
14468ec0eb7SSebastien Boeuf     SetClock(#[source] anyhow::Error),
145ff8d7bfeSWei Liu     ///
146ff8d7bfeSWei Liu     /// Create passthrough device
147ff8d7bfeSWei Liu     ///
148ff8d7bfeSWei Liu     #[error("Failed to create passthrough device: {0}")]
149ff8d7bfeSWei Liu     CreatePassthroughDevice(#[source] anyhow::Error),
15071c435ceSPraveen Paladugu     /// Write to Guest memory
15171c435ceSPraveen Paladugu     ///
15271c435ceSPraveen Paladugu     #[error("Failed to write to guest memory: {0}")]
15371c435ceSPraveen Paladugu     GuestMemWrite(#[source] anyhow::Error),
15471c435ceSPraveen Paladugu     ///
15571c435ceSPraveen Paladugu     /// Read Guest memory
15671c435ceSPraveen Paladugu     ///
15771c435ceSPraveen Paladugu     #[error("Failed to read guest memory: {0}")]
15871c435ceSPraveen Paladugu     GuestMemRead(#[source] anyhow::Error),
15971c435ceSPraveen Paladugu     ///
16071c435ceSPraveen Paladugu     /// Read from MMIO Bus
16171c435ceSPraveen Paladugu     ///
16271c435ceSPraveen Paladugu     #[error("Failed to read from MMIO Bus: {0}")]
16371c435ceSPraveen Paladugu     MmioBusRead(#[source] anyhow::Error),
16471c435ceSPraveen Paladugu     ///
16571c435ceSPraveen Paladugu     /// Write to MMIO Bus
16671c435ceSPraveen Paladugu     ///
16771c435ceSPraveen Paladugu     #[error("Failed to write to MMIO Bus: {0}")]
16871c435ceSPraveen Paladugu     MmioBusWrite(#[source] anyhow::Error),
16971c435ceSPraveen Paladugu     ///
17071c435ceSPraveen Paladugu     /// Read from IO Bus
17171c435ceSPraveen Paladugu     ///
17271c435ceSPraveen Paladugu     #[error("Failed to read from IO Bus: {0}")]
17371c435ceSPraveen Paladugu     IoBusRead(#[source] anyhow::Error),
17471c435ceSPraveen Paladugu     ///
17571c435ceSPraveen Paladugu     /// Write to IO Bus
17671c435ceSPraveen Paladugu     ///
17771c435ceSPraveen Paladugu     #[error("Failed to write to IO Bus: {0}")]
17871c435ceSPraveen Paladugu     IoBusWrite(#[source] anyhow::Error),
179041724a7SRob Bradford     ///
1805e0d4985SBo Chen     /// Start dirty log error
1815e0d4985SBo Chen     ///
1825e0d4985SBo Chen     #[error("Failed to get dirty log: {0}")]
1835e0d4985SBo Chen     StartDirtyLog(#[source] anyhow::Error),
1845e0d4985SBo Chen     ///
1855e0d4985SBo Chen     /// Stop dirty log error
1865e0d4985SBo Chen     ///
1875e0d4985SBo Chen     #[error("Failed to get dirty log: {0}")]
1885e0d4985SBo Chen     StopDirtyLog(#[source] anyhow::Error),
1895e0d4985SBo Chen     ///
190041724a7SRob Bradford     /// Get dirty log error
191041724a7SRob Bradford     ///
192041724a7SRob Bradford     #[error("Failed to get dirty log: {0}")]
193041724a7SRob Bradford     GetDirtyLog(#[source] anyhow::Error),
194fd0ef6cfSMuminul Islam     ///
195fd0ef6cfSMuminul Islam     /// Assert virtual interrupt error
196fd0ef6cfSMuminul Islam     ///
197fd0ef6cfSMuminul Islam     #[error("Failed to assert virtual Interrupt: {0}")]
19842e9632cSJosh Soref     AssertVirtualInterrupt(#[source] anyhow::Error),
199f282cc00SRob Bradford 
2001b59ab3dSJinank Jain     #[cfg(feature = "sev_snp")]
2011b59ab3dSJinank Jain     ///
2021b59ab3dSJinank Jain     /// Error initializing SEV-SNP on the VM
2031b59ab3dSJinank Jain     ///
2041b59ab3dSJinank Jain     #[error("Failed to initialize SEV-SNP: {0}")]
2051b59ab3dSJinank Jain     InitializeSevSnp(#[source] std::io::Error),
2061b59ab3dSJinank Jain 
207f282cc00SRob Bradford     #[cfg(feature = "tdx")]
208f282cc00SRob Bradford     ///
209f282cc00SRob Bradford     /// Error initializing TDX on the VM
210f282cc00SRob Bradford     ///
211f282cc00SRob Bradford     #[error("Failed to initialize TDX: {0}")]
212f282cc00SRob Bradford     InitializeTdx(#[source] std::io::Error),
213f282cc00SRob Bradford     #[cfg(feature = "tdx")]
214f282cc00SRob Bradford     ///
215f282cc00SRob Bradford     /// Error finalizing the TDX configuration on the VM
216f282cc00SRob Bradford     ///
217f282cc00SRob Bradford     #[error("Failed to finalize TDX: {0}")]
218f282cc00SRob Bradford     FinalizeTdx(#[source] std::io::Error),
219f282cc00SRob Bradford     #[cfg(feature = "tdx")]
220f282cc00SRob Bradford     ///
221f282cc00SRob Bradford     /// Error initializing the TDX memory region
222f282cc00SRob Bradford     ///
223f282cc00SRob Bradford     #[error("Failed to initialize memory region TDX: {0}")]
224f282cc00SRob Bradford     InitMemRegionTdx(#[source] std::io::Error),
225c2862b69SMichael Zhao     ///
226c2862b69SMichael Zhao     /// Create Vgic error
227c2862b69SMichael Zhao     ///
228c2862b69SMichael Zhao     #[error("Failed to create Vgic: {0}")]
229c2862b69SMichael Zhao     CreateVgic(#[source] anyhow::Error),
230dc390301SMuminul Islam     ///
2315e937c8bSRuoqing He     /// Create Vaia error
2325e937c8bSRuoqing He     ///
2335e937c8bSRuoqing He     #[error("Failed to create Vaia: {0}")]
2345e937c8bSRuoqing He     CreateVaia(#[source] anyhow::Error),
2355e937c8bSRuoqing He     ///
236dc390301SMuminul Islam     /// Import isolated pages error
237dc390301SMuminul Islam     ///
238dc390301SMuminul Islam     #[error("Failed to import isolated pages: {0}")]
239dc390301SMuminul Islam     ImportIsolatedPages(#[source] anyhow::Error),
2405bd113e6SMuminul Islam     /// Failed to complete isolated import
2415bd113e6SMuminul Islam     ///
2425bd113e6SMuminul Islam     #[error("Failed to complete isolated import: {0}")]
2435bd113e6SMuminul Islam     CompleteIsolatedImport(#[source] anyhow::Error),
244aabfc951SMuminul Islam     /// Failed to set VM property
245aabfc951SMuminul Islam     ///
246aabfc951SMuminul Islam     #[error("Failed to set VM property: {0}")]
247aabfc951SMuminul Islam     SetVmProperty(#[source] anyhow::Error),
2485c4b5c0eSMuminul Islam     ///
2495c4b5c0eSMuminul Islam     /// Modify GPA host access error
2505c4b5c0eSMuminul Islam     ///
2515c4b5c0eSMuminul Islam     #[cfg(feature = "sev_snp")]
2525c4b5c0eSMuminul Islam     #[error("Failed to modify GPA host access: {0}")]
2535c4b5c0eSMuminul Islam     ModifyGpaHostAccess(#[source] anyhow::Error),
254*1757d83dSMuminul Islam     ///
255*1757d83dSMuminul Islam     /// Failed to mmap
256*1757d83dSMuminul Islam     ///
257*1757d83dSMuminul Islam     #[cfg(feature = "sev_snp")]
258*1757d83dSMuminul Islam     #[error("Failed to mmap:")]
259*1757d83dSMuminul Islam     MmapToRoot,
260f5afc288SMuminul Islam }
261f5afc288SMuminul Islam ///
262f5afc288SMuminul Islam /// Result type for returning from a function
263f5afc288SMuminul Islam ///
264f5afc288SMuminul Islam pub type Result<T> = std::result::Result<T, HypervisorVmError>;
265f5afc288SMuminul Islam 
2663ffc105fSRob Bradford /// Configuration data for legacy interrupts.
2673ffc105fSRob Bradford ///
2683ffc105fSRob Bradford /// On x86 platforms, legacy interrupts means those interrupts routed through PICs or IOAPICs.
2693ffc105fSRob Bradford #[derive(Copy, Clone, Debug)]
2703ffc105fSRob Bradford pub struct LegacyIrqSourceConfig {
2713ffc105fSRob Bradford     pub irqchip: u32,
2723ffc105fSRob Bradford     pub pin: u32,
2733ffc105fSRob Bradford }
2743ffc105fSRob Bradford 
2753ffc105fSRob Bradford /// Configuration data for MSI/MSI-X interrupts.
2763ffc105fSRob Bradford ///
2773ffc105fSRob Bradford /// On x86 platforms, these interrupts are vectors delivered directly to the LAPIC.
2783ffc105fSRob Bradford #[derive(Copy, Clone, Debug, Default)]
2793ffc105fSRob Bradford pub struct MsiIrqSourceConfig {
2803ffc105fSRob Bradford     /// High address to delivery message signaled interrupt.
2813ffc105fSRob Bradford     pub high_addr: u32,
2823ffc105fSRob Bradford     /// Low address to delivery message signaled interrupt.
2833ffc105fSRob Bradford     pub low_addr: u32,
2843ffc105fSRob Bradford     /// Data to write to delivery message signaled interrupt.
2853ffc105fSRob Bradford     pub data: u32,
2863ffc105fSRob Bradford     /// Unique ID of the device to delivery message signaled interrupt.
2873ffc105fSRob Bradford     pub devid: u32,
2883ffc105fSRob Bradford }
2893ffc105fSRob Bradford 
2903ffc105fSRob Bradford /// Configuration data for an interrupt source.
2913ffc105fSRob Bradford #[derive(Copy, Clone, Debug)]
2923ffc105fSRob Bradford pub enum InterruptSourceConfig {
2933ffc105fSRob Bradford     /// Configuration data for Legacy interrupts.
2943ffc105fSRob Bradford     LegacyIrq(LegacyIrqSourceConfig),
2953ffc105fSRob Bradford     /// Configuration data for PciMsi, PciMsix and generic MSI interrupts.
2963ffc105fSRob Bradford     MsiIrq(MsiIrqSourceConfig),
2973ffc105fSRob Bradford }
2983ffc105fSRob Bradford 
299f5afc288SMuminul Islam ///
300f5afc288SMuminul Islam /// Trait to represent a Vm
301f5afc288SMuminul Islam ///
302f5afc288SMuminul Islam /// This crate provides a hypervisor-agnostic interfaces for Vm
303f5afc288SMuminul Islam ///
304b5270e0bSWei Liu pub trait Vm: Send + Sync + Any {
305f5afc288SMuminul Islam     #[cfg(target_arch = "x86_64")]
306c452471cSSebastien Boeuf     /// Sets the address of the one-page region in the VM's address space.
307c452471cSSebastien Boeuf     fn set_identity_map_address(&self, address: u64) -> Result<()>;
308c452471cSSebastien Boeuf     #[cfg(target_arch = "x86_64")]
309f5afc288SMuminul Islam     /// Sets the address of the three-page region in the VM's address space.
310f5afc288SMuminul Islam     fn set_tss_address(&self, offset: usize) -> Result<()>;
3115e937c8bSRuoqing He     #[cfg(not(target_arch = "riscv64"))]
312f5afc288SMuminul Islam     /// Creates an in-kernel interrupt controller.
313f5afc288SMuminul Islam     fn create_irq_chip(&self) -> Result<()>;
314f5afc288SMuminul Islam     /// Registers an event that will, when signaled, trigger the `gsi` IRQ.
315f5afc288SMuminul Islam     fn register_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
316f5afc288SMuminul Islam     /// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
317f5afc288SMuminul Islam     fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
318f5afc288SMuminul Islam     /// Creates a new KVM vCPU file descriptor and maps the memory corresponding
319387d5687SRob Bradford     fn create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>;
320c2862b69SMichael Zhao     #[cfg(target_arch = "aarch64")]
321784a3aafSNuno Das Neves     fn create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>;
3225e937c8bSRuoqing He     #[cfg(target_arch = "riscv64")]
3235e937c8bSRuoqing He     fn create_vaia(&self, config: VaiaConfig) -> Result<Arc<Mutex<dyn Vaia>>>;
324c2862b69SMichael Zhao 
325f5afc288SMuminul Islam     /// Registers an event to be signaled whenever a certain address is written to.
326f5afc288SMuminul Islam     fn register_ioevent(
327f5afc288SMuminul Islam         &self,
328f5afc288SMuminul Islam         fd: &EventFd,
329f5afc288SMuminul Islam         addr: &IoEventAddress,
330f5afc288SMuminul Islam         datamatch: Option<DataMatch>,
331f5afc288SMuminul Islam     ) -> Result<()>;
332f5afc288SMuminul Islam     /// Unregister an event from a certain address it has been previously registered to.
333f5afc288SMuminul Islam     fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>;
3343f9e8d67SRob Bradford     // Construct a routing entry
3353f9e8d67SRob Bradford     fn make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry;
336f5afc288SMuminul Islam     /// Sets the GSI routing table entries, overwriting any previously set
337e1af251cSWei Liu     fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> Result<()>;
3381f2915bfSWei Liu     /// Creates a memory region structure that can be used with {create/remove}_user_memory_region
339cfa758fbSWei Liu     fn make_user_memory_region(
340cfa758fbSWei Liu         &self,
341cfa758fbSWei Liu         slot: u32,
342cfa758fbSWei Liu         guest_phys_addr: u64,
343cfa758fbSWei Liu         memory_size: u64,
344cfa758fbSWei Liu         userspace_addr: u64,
345cfa758fbSWei Liu         readonly: bool,
3468baa244eSRob Bradford         log_dirty_pages: bool,
347e1cf889dSWei Liu     ) -> UserMemoryRegion;
3481f2915bfSWei Liu     /// Creates a guest physical memory slot.
349e1cf889dSWei Liu     fn create_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>;
3501f2915bfSWei Liu     /// Removes a guest physical memory slot.
351e1cf889dSWei Liu     fn remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>;
352f5afc288SMuminul Islam     /// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
353f0ad7fc7SMichael Zhao     #[cfg(target_arch = "aarch64")]
354f5afc288SMuminul Islam     fn get_preferred_target(&self, kvi: &mut VcpuInit) -> Result<()>;
355f5afc288SMuminul Islam     /// Enable split Irq capability
356f5afc288SMuminul Islam     #[cfg(target_arch = "x86_64")]
357f5afc288SMuminul Islam     fn enable_split_irq(&self) -> Result<()>;
3589ec0c981SSebastien Boeuf     #[cfg(target_arch = "x86_64")]
3599ec0c981SSebastien Boeuf     fn enable_sgx_attribute(&self, file: File) -> Result<()>;
36068ec0eb7SSebastien Boeuf     /// Retrieve guest clock.
3614201bf40SWei Liu     #[cfg(target_arch = "x86_64")]
36268ec0eb7SSebastien Boeuf     fn get_clock(&self) -> Result<ClockData>;
36368ec0eb7SSebastien Boeuf     /// Set guest clock.
3644201bf40SWei Liu     #[cfg(target_arch = "x86_64")]
36568ec0eb7SSebastien Boeuf     fn set_clock(&self, data: &ClockData) -> Result<()>;
366ff8d7bfeSWei Liu     /// Create a device that is used for passthrough
367a96a5d78SWei Liu     fn create_passthrough_device(&self) -> Result<vfio_ioctls::VfioDeviceFd>;
3685e0d4985SBo Chen     /// Start logging dirty pages
369e7c9954dSBo Chen     fn start_dirty_log(&self) -> Result<()>;
3705e0d4985SBo Chen     /// Stop logging dirty pages
371e7c9954dSBo Chen     fn stop_dirty_log(&self) -> Result<()>;
372041724a7SRob Bradford     /// Get dirty pages bitmap
373fdecba69SMuminul Islam     fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>;
3741b59ab3dSJinank Jain     #[cfg(feature = "sev_snp")]
3751b59ab3dSJinank Jain     /// Initialize SEV-SNP on this VM
3761b59ab3dSJinank Jain     fn sev_snp_init(&self) -> Result<()> {
3771b59ab3dSJinank Jain         unimplemented!()
3781b59ab3dSJinank Jain     }
379f282cc00SRob Bradford     #[cfg(feature = "tdx")]
3807bf0cc1eSPhilipp Schuster     /// Initialize TDX on this VM
381b8503b5fSRob Bradford     fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> {
382b8503b5fSRob Bradford         unimplemented!()
383b8503b5fSRob Bradford     }
384f282cc00SRob Bradford     #[cfg(feature = "tdx")]
385f282cc00SRob Bradford     /// Finalize the configuration of TDX on this VM
386b8503b5fSRob Bradford     fn tdx_finalize(&self) -> Result<()> {
387b8503b5fSRob Bradford         unimplemented!()
388b8503b5fSRob Bradford     }
389f282cc00SRob Bradford     #[cfg(feature = "tdx")]
3907bf0cc1eSPhilipp Schuster     /// Initialize a TDX memory region for this VM
391f282cc00SRob Bradford     fn tdx_init_memory_region(
392f282cc00SRob Bradford         &self,
393b8503b5fSRob Bradford         _host_address: u64,
394b8503b5fSRob Bradford         _guest_address: u64,
395b8503b5fSRob Bradford         _size: u64,
396b8503b5fSRob Bradford         _measure: bool,
397b8503b5fSRob Bradford     ) -> Result<()> {
398b8503b5fSRob Bradford         unimplemented!()
399b8503b5fSRob Bradford     }
400b5270e0bSWei Liu     /// Downcast to the underlying hypervisor VM type
401b5270e0bSWei Liu     fn as_any(&self) -> &dyn Any;
402dc390301SMuminul Islam     /// Import the isolated pages
403dc390301SMuminul Islam     #[cfg(feature = "sev_snp")]
404dc390301SMuminul Islam     fn import_isolated_pages(
405dc390301SMuminul Islam         &self,
406dc390301SMuminul Islam         _page_type: u32,
407dc390301SMuminul Islam         _page_size: u32,
408dc390301SMuminul Islam         _pages: &[u64],
409dc390301SMuminul Islam     ) -> Result<()> {
410dc390301SMuminul Islam         unimplemented!()
411dc390301SMuminul Islam     }
4125bd113e6SMuminul Islam     /// Complete the isolated import
4135bd113e6SMuminul Islam     #[cfg(feature = "sev_snp")]
4145bd113e6SMuminul Islam     fn complete_isolated_import(
4155bd113e6SMuminul Islam         &self,
4165bd113e6SMuminul Islam         _snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
417cbcbf635SMuminul Islam         _host_data: [u8; 32],
4185bd113e6SMuminul Islam         _id_block_enabled: u8,
4195bd113e6SMuminul Islam     ) -> Result<()> {
4205bd113e6SMuminul Islam         unimplemented!()
4215bd113e6SMuminul Islam     }
4223fe9b877SMuminul Islam 
4233fe9b877SMuminul Islam     /// Pause the VM
4243fe9b877SMuminul Islam     fn pause(&self) -> Result<()> {
4253fe9b877SMuminul Islam         Ok(())
4263fe9b877SMuminul Islam     }
4273fe9b877SMuminul Islam 
4283fe9b877SMuminul Islam     /// Resume the VM
4293fe9b877SMuminul Islam     fn resume(&self) -> Result<()> {
4303fe9b877SMuminul Islam         Ok(())
4313fe9b877SMuminul Islam     }
4325c4b5c0eSMuminul Islam 
4335c4b5c0eSMuminul Islam     #[cfg(feature = "sev_snp")]
4345c4b5c0eSMuminul Islam     fn gain_page_access(&self, _gpa: u64, _size: u32) -> Result<()> {
4355c4b5c0eSMuminul Islam         Ok(())
4365c4b5c0eSMuminul Islam     }
43771c435ceSPraveen Paladugu }
43871c435ceSPraveen Paladugu 
439387d5687SRob Bradford pub trait VmOps: Send + Sync {
4405fc12862SWei Liu     fn guest_mem_write(&self, gpa: u64, buf: &[u8]) -> Result<usize>;
4415fc12862SWei Liu     fn guest_mem_read(&self, gpa: u64, buf: &mut [u8]) -> Result<usize>;
4425fc12862SWei Liu     fn mmio_read(&self, gpa: u64, data: &mut [u8]) -> Result<()>;
4435fc12862SWei Liu     fn mmio_write(&self, gpa: u64, data: &[u8]) -> Result<()>;
44471c435ceSPraveen Paladugu     #[cfg(target_arch = "x86_64")]
4455fc12862SWei Liu     fn pio_read(&self, port: u64, data: &mut [u8]) -> Result<()>;
44671c435ceSPraveen Paladugu     #[cfg(target_arch = "x86_64")]
4475fc12862SWei Liu     fn pio_write(&self, port: u64, data: &[u8]) -> Result<()>;
448f5afc288SMuminul Islam }
449