xref: /cloud-hypervisor/hypervisor/src/hypervisor.rs (revision 72c81783358b641709a16112a45a7ffd52f58f3f)
1683210d6SMuminul Islam // Copyright © 2019 Intel Corporation
2683210d6SMuminul Islam //
372ae1577SMuminul Islam // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4683210d6SMuminul Islam //
5683210d6SMuminul Islam // Copyright © 2020, Microsoft Corporation
6683210d6SMuminul Islam //
7683210d6SMuminul Islam // Copyright 2018-2019 CrowdStrike, Inc.
8683210d6SMuminul Islam //
9683210d6SMuminul Islam //
1008135fa0SWei Liu #[cfg(target_arch = "x86_64")]
1188a9f799SRob Bradford use std::arch::x86_64;
1288a9f799SRob Bradford use std::sync::Arc;
1388a9f799SRob Bradford 
1488a9f799SRob Bradford use thiserror::Error;
1588a9f799SRob Bradford 
1688a9f799SRob Bradford #[cfg(target_arch = "x86_64")]
1708135fa0SWei Liu use crate::arch::x86::CpuIdEntry;
187df80220SAnatol Belski #[cfg(target_arch = "x86_64")]
197df80220SAnatol Belski use crate::cpu::CpuVendor;
20218be264SRob Bradford #[cfg(feature = "tdx")]
21218be264SRob Bradford use crate::kvm::TdxCapabilities;
22683210d6SMuminul Islam use crate::vm::Vm;
239fc3379eSWei Liu use crate::HypervisorType;
24683210d6SMuminul Islam 
25683210d6SMuminul Islam #[derive(Error, Debug)]
26683210d6SMuminul Islam pub enum HypervisorError {
27683210d6SMuminul Islam     ///
28aa66526eSWei Liu     /// Hypervisor availability check error
29aa66526eSWei Liu     ///
30*72c81783SPhilipp Schuster     #[error("Failed to check availability of the hypervisor")]
31aa66526eSWei Liu     HypervisorAvailableCheck(#[source] anyhow::Error),
32aa66526eSWei Liu     ///
3323c46b16SMuminul Islam     /// hypervisor creation error
3423c46b16SMuminul Islam     ///
35*72c81783SPhilipp Schuster     #[error("Failed to create the hypervisor")]
3623c46b16SMuminul Islam     HypervisorCreate(#[source] anyhow::Error),
3723c46b16SMuminul Islam     ///
38683210d6SMuminul Islam     /// Vm creation failure
39683210d6SMuminul Islam     ///
40*72c81783SPhilipp Schuster     #[error("Failed to create Vm")]
41683210d6SMuminul Islam     VmCreate(#[source] anyhow::Error),
42683210d6SMuminul Islam     ///
43683210d6SMuminul Islam     /// Vm setup failure
44683210d6SMuminul Islam     ///
45*72c81783SPhilipp Schuster     #[error("Failed to setup Vm")]
46683210d6SMuminul Islam     VmSetup(#[source] anyhow::Error),
47683210d6SMuminul Islam     ///
48683210d6SMuminul Islam     /// API version error
49683210d6SMuminul Islam     ///
50*72c81783SPhilipp Schuster     #[error("Failed to get API Version")]
51683210d6SMuminul Islam     GetApiVersion(#[source] anyhow::Error),
52683210d6SMuminul Islam     ///
53683210d6SMuminul Islam     /// CpuId error
54683210d6SMuminul Islam     ///
55*72c81783SPhilipp Schuster     #[error("Failed to get cpuid")]
56683210d6SMuminul Islam     GetCpuId(#[source] anyhow::Error),
5749b4fba2SSebastien Boeuf     ///
5849b4fba2SSebastien Boeuf     /// Failed to retrieve list of MSRs.
5949b4fba2SSebastien Boeuf     ///
60*72c81783SPhilipp Schuster     #[error("Failed to get the list of supported MSRs")]
6149b4fba2SSebastien Boeuf     GetMsrList(#[source] anyhow::Error),
62d73971e4SWei Liu     ///
63d73971e4SWei Liu     /// API version is not compatible
64d73971e4SWei Liu     ///
65d73971e4SWei Liu     #[error("Incompatible API version")]
66d73971e4SWei Liu     IncompatibleApiVersion,
6784454f14SRob Bradford     ///
6884454f14SRob Bradford     /// Checking extensions failed
6984454f14SRob Bradford     ///
70*72c81783SPhilipp Schuster     #[error("Checking extensions")]
7184454f14SRob Bradford     CheckExtensions(#[source] anyhow::Error),
72b0077f0bSSebastien Boeuf     ///
73b0077f0bSSebastien Boeuf     /// Failed to retrieve TDX capabilities
74b0077f0bSSebastien Boeuf     ///
75*72c81783SPhilipp Schuster     #[error("Failed to retrieve TDX capabilities")]
76b0077f0bSSebastien Boeuf     TdxCapabilities(#[source] anyhow::Error),
77ada85f68SJinank Jain     ///
78ada85f68SJinank Jain     /// Failed to set partition property
79ada85f68SJinank Jain     ///
80*72c81783SPhilipp Schuster     #[error("Failed to set partition property")]
81ada85f68SJinank Jain     SetPartitionProperty(#[source] anyhow::Error),
827df80220SAnatol Belski     ///
837df80220SAnatol Belski     /// Running on an unsupported CPU
847df80220SAnatol Belski     ///
85*72c81783SPhilipp Schuster     #[error("Unsupported CPU")]
867df80220SAnatol Belski     UnsupportedCpu(#[source] anyhow::Error),
87200cba0eSJinank Jain     ///
88200cba0eSJinank Jain     /// Launching a VM with unsupported VM Type
89200cba0eSJinank Jain     ///
90200cba0eSJinank Jain     #[error("Unsupported VmType")]
91200cba0eSJinank Jain     UnsupportedVmType(),
92683210d6SMuminul Islam }
93683210d6SMuminul Islam 
94683210d6SMuminul Islam ///
95683210d6SMuminul Islam /// Result type for returning from a function
96683210d6SMuminul Islam ///
97683210d6SMuminul Islam pub type Result<T> = std::result::Result<T, HypervisorError>;
98683210d6SMuminul Islam 
99683210d6SMuminul Islam ///
100683210d6SMuminul Islam /// Trait to represent a Hypervisor
101683210d6SMuminul Islam ///
102683210d6SMuminul Islam /// This crate provides a hypervisor-agnostic interfaces
103683210d6SMuminul Islam ///
104683210d6SMuminul Islam pub trait Hypervisor: Send + Sync {
105683210d6SMuminul Islam     ///
1069fc3379eSWei Liu     /// Returns the type of the hypervisor
1079fc3379eSWei Liu     ///
hypervisor_type(&self) -> HypervisorType1089fc3379eSWei Liu     fn hypervisor_type(&self) -> HypervisorType;
1099fc3379eSWei Liu     ///
110683210d6SMuminul Islam     /// Create a Vm using the underlying hypervisor
111683210d6SMuminul Islam     /// Return a hypervisor-agnostic Vm trait object
112683210d6SMuminul Islam     ///
create_vm(&self) -> Result<Arc<dyn Vm>>113683210d6SMuminul Islam     fn create_vm(&self) -> Result<Arc<dyn Vm>>;
114683210d6SMuminul Islam     ///
1151c54fc3aSRob Bradford     /// Create a Vm of a specific type using the underlying hypervisor
1161c54fc3aSRob Bradford     /// Return a hypervisor-agnostic Vm trait object
1171c54fc3aSRob Bradford     ///
create_vm_with_type(&self, _vm_type: u64) -> Result<Arc<dyn Vm>>118a335cbb8SRob Bradford     fn create_vm_with_type(&self, _vm_type: u64) -> Result<Arc<dyn Vm>> {
119a335cbb8SRob Bradford         unreachable!()
120a335cbb8SRob Bradford     }
1214054a49eSMuminul Islam     ///
1224054a49eSMuminul Islam     /// Create a Vm of a specific type using the underlying hypervisor, passing memory size
1234054a49eSMuminul Islam     /// Return a hypervisor-agnostic Vm trait object
1244054a49eSMuminul Islam     ///
create_vm_with_type_and_memory( &self, _vm_type: u64, #[cfg(feature = "sev_snp")] _mem_size: u64, ) -> Result<Arc<dyn Vm>>1254054a49eSMuminul Islam     fn create_vm_with_type_and_memory(
1264054a49eSMuminul Islam         &self,
1274054a49eSMuminul Islam         _vm_type: u64,
1284054a49eSMuminul Islam         #[cfg(feature = "sev_snp")] _mem_size: u64,
1294054a49eSMuminul Islam     ) -> Result<Arc<dyn Vm>> {
1304054a49eSMuminul Islam         unreachable!()
1314054a49eSMuminul Islam     }
132683210d6SMuminul Islam     #[cfg(target_arch = "x86_64")]
133683210d6SMuminul Islam     ///
134683210d6SMuminul Islam     /// Get the supported CpuID
135683210d6SMuminul Islam     ///
get_supported_cpuid(&self) -> Result<Vec<CpuIdEntry>>136de3ca970SWei Liu     fn get_supported_cpuid(&self) -> Result<Vec<CpuIdEntry>>;
137683210d6SMuminul Islam     ///
138683210d6SMuminul Islam     /// Check particular extensions if any
139683210d6SMuminul Islam     ///
check_required_extensions(&self) -> Result<()>1400cf9218dSRob Bradford     fn check_required_extensions(&self) -> Result<()> {
1410cf9218dSRob Bradford         Ok(())
1420cf9218dSRob Bradford     }
143805cb303SHenry Wang     #[cfg(target_arch = "aarch64")]
144805cb303SHenry Wang     ///
145223b1f6cSMichael Zhao     /// Retrieve AArch64 host maximum IPA size supported by KVM
146805cb303SHenry Wang     ///
get_host_ipa_limit(&self) -> i32147805cb303SHenry Wang     fn get_host_ipa_limit(&self) -> i32;
148b0077f0bSSebastien Boeuf     ///
149b0077f0bSSebastien Boeuf     /// Retrieve TDX capabilities
150b0077f0bSSebastien Boeuf     ///
151b0077f0bSSebastien Boeuf     #[cfg(feature = "tdx")]
tdx_capabilities(&self) -> Result<TdxCapabilities>152b8503b5fSRob Bradford     fn tdx_capabilities(&self) -> Result<TdxCapabilities> {
153b8503b5fSRob Bradford         unimplemented!()
154b8503b5fSRob Bradford     }
155223b1f6cSMichael Zhao     ///
156223b1f6cSMichael Zhao     /// Get the number of supported hardware breakpoints
157223b1f6cSMichael Zhao     ///
get_guest_debug_hw_bps(&self) -> usize158223b1f6cSMichael Zhao     fn get_guest_debug_hw_bps(&self) -> usize {
159223b1f6cSMichael Zhao         unimplemented!()
160223b1f6cSMichael Zhao     }
161ceb81517SRob Bradford 
162ceb81517SRob Bradford     /// Get maximum number of vCPUs
get_max_vcpus(&self) -> u32163ceb81517SRob Bradford     fn get_max_vcpus(&self) -> u32;
1647df80220SAnatol Belski     #[cfg(target_arch = "x86_64")]
1657df80220SAnatol Belski     ///
1667df80220SAnatol Belski     /// Determine CPU vendor
1677df80220SAnatol Belski     ///
get_cpu_vendor(&self) -> CpuVendor1687df80220SAnatol Belski     fn get_cpu_vendor(&self) -> CpuVendor {
1697df80220SAnatol Belski         // SAFETY: call cpuid with valid leaves
1707df80220SAnatol Belski         unsafe {
1717df80220SAnatol Belski             let leaf = x86_64::__cpuid(0x0);
1727df80220SAnatol Belski 
1737df80220SAnatol Belski             if leaf.ebx == 0x756e_6547 && leaf.ecx == 0x6c65_746e && leaf.edx == 0x4965_6e69 {
1747df80220SAnatol Belski                 // Vendor string GenuineIntel
1757df80220SAnatol Belski                 CpuVendor::Intel
1767df80220SAnatol Belski             } else if leaf.ebx == 0x6874_7541 && leaf.ecx == 0x444d_4163 && leaf.edx == 0x6974_6e65
1777df80220SAnatol Belski             {
1787df80220SAnatol Belski                 // Vendor string AuthenticAMD
1797df80220SAnatol Belski                 CpuVendor::AMD
1807df80220SAnatol Belski             } else {
1817df80220SAnatol Belski                 // Not known yet, the corresponding manufacturer manual should contain the
18242e9632cSJosh Soref                 // necessary info. See also https://wiki.osdev.org/CPUID#CPU_Vendor_ID_String
1837df80220SAnatol Belski                 CpuVendor::default()
1847df80220SAnatol Belski             }
1857df80220SAnatol Belski         }
1867df80220SAnatol Belski     }
187683210d6SMuminul Islam }
188