mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: hypervisor: simplify VM creation API
For MSHV customers don't want to make everything default during partition creation. For example nested support, some synthetic features could be controlled from CLI through platform argument. Create_vm API getting messy after adding more flags. This patch introduces common data struct to be passed from vmm crate to hypervisor crate during partition creation. Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
@@ -482,6 +482,7 @@ impl Vgic for KvmGicV3Its {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::HypervisorVmConfig;
|
||||
use crate::aarch64::gic::{
|
||||
get_dist_regs, get_icc_regs, get_redist_regs, set_dist_regs, set_icc_regs, set_redist_regs,
|
||||
};
|
||||
@@ -506,7 +507,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_create_gic() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
|
||||
KvmGicV3Its::new(&*vm, create_test_vgic_config()).unwrap();
|
||||
}
|
||||
@@ -514,7 +515,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_set_dist_regs() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
let _ = vm.create_vcpu(0, None).unwrap();
|
||||
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
|
||||
|
||||
@@ -527,7 +528,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_set_redist_regs() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
let _ = vm.create_vcpu(0, None).unwrap();
|
||||
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
|
||||
|
||||
@@ -542,7 +543,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_set_icc_regs() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
let _ = vm.create_vcpu(0, None).unwrap();
|
||||
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
|
||||
|
||||
@@ -557,7 +558,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_save_data_tables() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
let _ = vm.create_vcpu(0, None).unwrap();
|
||||
let gic = vm
|
||||
.create_vgic(create_test_vgic_config())
|
||||
|
||||
@@ -46,7 +46,7 @@ pub use crate::riscv64::{
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
use crate::riscv64_reg_id;
|
||||
use crate::vm::{self, InterruptSourceConfig, VmOps};
|
||||
use crate::{HypervisorType, cpu, hypervisor};
|
||||
use crate::{HypervisorType, HypervisorVmConfig, cpu, hypervisor};
|
||||
// x86_64 dependencies
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod x86_64;
|
||||
@@ -103,7 +103,7 @@ use kvm_bindings::{
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
use kvm_bindings::{KVM_REG_RISCV_CORE, kvm_riscv_core};
|
||||
#[cfg(feature = "tdx")]
|
||||
use kvm_bindings::{KVMIO, kvm_run__bindgen_ty_1};
|
||||
use kvm_bindings::{KVM_X86_DEFAULT_VM, KVM_X86_SW_PROTECTED_VM, KVMIO, kvm_run__bindgen_ty_1};
|
||||
pub use kvm_ioctls::{Cap, Kvm, VcpuExit};
|
||||
use thiserror::Error;
|
||||
use vfio_ioctls::VfioDeviceFd;
|
||||
@@ -539,10 +539,11 @@ impl KvmVm {
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// # use std::sync::Arc;
|
||||
/// let kvm = KvmHypervisor::new().unwrap();
|
||||
/// let hypervisor = Arc::new(kvm);
|
||||
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
|
||||
/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed");
|
||||
/// ```
|
||||
impl vm::Vm for KvmVm {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@@ -1161,10 +1162,11 @@ impl KvmHypervisor {
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// # use std::sync::Arc;
|
||||
/// let kvm = KvmHypervisor::new().unwrap();
|
||||
/// let hypervisor = Arc::new(kvm);
|
||||
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
|
||||
/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed");
|
||||
/// ```
|
||||
impl hypervisor::Hypervisor for KvmHypervisor {
|
||||
///
|
||||
@@ -1174,38 +1176,39 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
||||
HypervisorType::Kvm
|
||||
}
|
||||
|
||||
///
|
||||
/// Create a Vm of a specific type using the underlying hypervisor, passing memory size
|
||||
/// Return a hypervisor-agnostic Vm trait object
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// use hypervisor::kvm::KvmVm;
|
||||
/// let hypervisor = KvmHypervisor::new().unwrap();
|
||||
/// let vm = hypervisor.create_vm_with_type_and_memory(0).unwrap();
|
||||
/// ```
|
||||
fn create_vm_with_type_and_memory(
|
||||
&self,
|
||||
vm_type: u64,
|
||||
#[cfg(feature = "sev_snp")] _mem_size: u64,
|
||||
) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
||||
self.create_vm_with_type(vm_type)
|
||||
}
|
||||
|
||||
/// Create a KVM vm object of a specific VM type and return the object as Vm trait object
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// use hypervisor::kvm::KvmVm;
|
||||
/// # use hypervisor::kvm::KvmVm;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// let hypervisor = KvmHypervisor::new().unwrap();
|
||||
/// let vm = hypervisor.create_vm_with_type(0).unwrap();
|
||||
/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
/// ```
|
||||
fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
||||
fn create_vm(&self, _config: HypervisorVmConfig) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
||||
let fd: VmFd;
|
||||
|
||||
#[allow(unused_mut)]
|
||||
#[allow(unused_assignments)]
|
||||
let mut vm_type: u64 = 0; // Create with default platform type
|
||||
|
||||
// When KVM supports Cap::ArmVmIPASize, it is better to get the IPA
|
||||
// size from the host and use that when creating the VM, which may
|
||||
// avoid unnecessary VM creation failures.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
if self.kvm.check_extension(Cap::ArmVmIPASize) {
|
||||
vm_type = self.kvm.get_host_ipa_limit().try_into().unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
if _config.tdx_enabled {
|
||||
vm_type = KVM_X86_SW_PROTECTED_VM.into();
|
||||
} else {
|
||||
vm_type = KVM_X86_DEFAULT_VM.into();
|
||||
};
|
||||
|
||||
loop {
|
||||
match self.kvm.create_vm_with_type(vm_type) {
|
||||
Ok(res) => fd = res,
|
||||
@@ -1256,31 +1259,6 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a KVM vm object and return the object as Vm trait object
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// use hypervisor::kvm::KvmVm;
|
||||
/// let hypervisor = KvmHypervisor::new().unwrap();
|
||||
/// let vm = hypervisor.create_vm().unwrap();
|
||||
/// ```
|
||||
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
||||
#[allow(unused_mut)]
|
||||
let mut vm_type: u64 = 0; // Create with default platform type
|
||||
|
||||
// When KVM supports Cap::ArmVmIPASize, it is better to get the IPA
|
||||
// size from the host and use that when creating the VM, which may
|
||||
// avoid unnecessary VM creation failures.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
if self.kvm.check_extension(Cap::ArmVmIPASize) {
|
||||
vm_type = self.kvm.get_host_ipa_limit().try_into().unwrap();
|
||||
}
|
||||
|
||||
self.create_vm_with_type(vm_type)
|
||||
}
|
||||
|
||||
fn check_required_extensions(&self) -> hypervisor::Result<()> {
|
||||
check_required_kvm_extensions(&self.kvm)
|
||||
.map_err(|e| hypervisor::HypervisorError::CheckExtensions(e.into()))
|
||||
@@ -1367,10 +1345,11 @@ pub struct KvmVcpu {
|
||||
///
|
||||
/// ```
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// # use std::sync::Arc;
|
||||
/// let kvm = KvmHypervisor::new().unwrap();
|
||||
/// let hypervisor = Arc::new(kvm);
|
||||
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
|
||||
/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed");
|
||||
/// let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
/// ```
|
||||
impl cpu::Vcpu for KvmVcpu {
|
||||
@@ -2449,9 +2428,10 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
/// ```rust
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// # use std::sync::Arc;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// let kvm = KvmHypervisor::new().unwrap();
|
||||
/// let hv = Arc::new(kvm);
|
||||
/// let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||
/// let vm = hv.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed");
|
||||
/// vm.enable_split_irq().unwrap();
|
||||
/// let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
/// let state = vcpu.state().unwrap();
|
||||
@@ -2686,10 +2666,11 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
///
|
||||
/// ```rust
|
||||
/// # use hypervisor::kvm::KvmHypervisor;
|
||||
/// # use hypervisor::HypervisorVmConfig;
|
||||
/// # use std::sync::Arc;
|
||||
/// let kvm = KvmHypervisor::new().unwrap();
|
||||
/// let hv = Arc::new(kvm);
|
||||
/// let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||
/// let vm = hv.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed");
|
||||
/// vm.enable_split_irq().unwrap();
|
||||
/// let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
/// let state = vcpu.state().unwrap();
|
||||
@@ -3069,7 +3050,9 @@ mod tests {
|
||||
|
||||
let kvm = KvmHypervisor::new().unwrap();
|
||||
let hypervisor = Arc::new(kvm);
|
||||
let vm = hypervisor.create_vm().expect("new VM fd creation failed");
|
||||
let vm = hypervisor
|
||||
.create_vm(HypervisorVmConfig::default())
|
||||
.expect("new VM fd creation failed");
|
||||
let vcpu0 = vm.create_vcpu(0, None).unwrap();
|
||||
|
||||
let core_regs = StandardRegisters::from(kvm_riscv_core {
|
||||
|
||||
@@ -251,6 +251,7 @@ impl Vaia for KvmAiaImsics {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::HypervisorVmConfig;
|
||||
use crate::arch::riscv64::aia::VaiaConfig;
|
||||
use crate::kvm::KvmAiaImsics;
|
||||
|
||||
@@ -266,7 +267,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_create_aia() {
|
||||
let hv = crate::new().unwrap();
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap();
|
||||
let _vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
|
||||
assert!(KvmAiaImsics::new(&*vm, create_test_vaia_config()).is_ok());
|
||||
|
||||
Reference in New Issue
Block a user