vmm: Refactor VM creation workflow

This refactoring is required to add support for creating SEV-SNP enabled
VM.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
Jinank Jain 2022-12-20 04:39:20 +00:00 committed by Rob Bradford
parent 5fd79571b7
commit 200cba0e20
6 changed files with 64 additions and 22 deletions

1
Cargo.lock generated
View File

@ -2340,6 +2340,7 @@ dependencies = [
"bitflags 2.3.3",
"block",
"blocking",
"cfg-if",
"devices",
"epoll",
"event_monitor",

View File

@ -84,6 +84,11 @@ pub enum HypervisorError {
///
#[error("Unsupported CPU:{0}")]
UnsupportedCpu(#[source] anyhow::Error),
///
/// Launching a VM with unsupported VM Type
///
#[error("Unsupported VmType")]
UnsupportedVmType(),
}
///

View File

@ -14,7 +14,7 @@ use crate::vec_with_array_field;
use crate::vm::{self, InterruptSourceConfig, VmOps};
use crate::HypervisorType;
pub use mshv_bindings::*;
use mshv_ioctls::{set_registers_64, Mshv, NoDatamatch, VcpuFd, VmFd};
use mshv_ioctls::{set_registers_64, Mshv, NoDatamatch, VcpuFd, VmFd, VmType};
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
@ -210,21 +210,15 @@ impl hypervisor::Hypervisor for MshvHypervisor {
fn hypervisor_type(&self) -> HypervisorType {
HypervisorType::Mshv
}
/// Create a mshv vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result<Arc<dyn crate::Vm>> {
let mshv_vm_type: VmType = match VmType::try_from(vm_type) {
Ok(vm_type) => vm_type,
Err(_) => return Err(hypervisor::HypervisorError::UnsupportedVmType()),
};
let fd: VmFd;
loop {
match self.mshv.create_vm() {
match self.mshv.create_vm_with_type(mshv_vm_type) {
Ok(res) => fd = res,
Err(e) => {
if e.errno() == libc::EINTR {
@ -271,6 +265,22 @@ impl hypervisor::Hypervisor for MshvHypervisor {
dirty_log_slots: Arc::new(RwLock::new(HashMap::new())),
}))
}
/// Create a mshv vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
let vm_type = 0;
self.create_vm_with_type(vm_type)
}
///
/// Get the supported CpuID
///

View File

@ -23,6 +23,7 @@ arch = { path = "../arch" }
bitflags = "2.3.3"
block = { path = "../block" }
blocking = { version = "1.3.0", optional = true }
cfg-if = "1.0.0"
devices = { path = "../devices" }
epoll = "4.3.3"
event_monitor = { path = "../event_monitor" }

View File

@ -1312,6 +1312,8 @@ impl Vmm {
&self.hypervisor,
#[cfg(feature = "tdx")]
false,
#[cfg(feature = "sev_snp")]
false,
)
.map_err(|e| {
MigratableError::MigrateReceive(anyhow!(

View File

@ -759,10 +759,19 @@ impl Vm {
vm_config.lock().unwrap().is_tdx_enabled()
};
#[cfg(feature = "sev_snp")]
let sev_snp_enabled = if snapshot.is_some() {
false
} else {
vm_config.lock().unwrap().is_sev_snp_enabled()
};
let vm = Self::create_hypervisor_vm(
&hypervisor,
#[cfg(feature = "tdx")]
tdx_enabled,
#[cfg(feature = "sev_snp")]
sev_snp_enabled,
)?;
let phys_bits = physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits);
@ -821,17 +830,31 @@ impl Vm {
pub fn create_hypervisor_vm(
hypervisor: &Arc<dyn hypervisor::Hypervisor>,
#[cfg(feature = "tdx")] tdx_enabled: bool,
#[cfg(feature = "sev_snp")] sev_snp_enabled: bool,
) -> Result<Arc<dyn hypervisor::Vm>> {
hypervisor.check_required_extensions().unwrap();
// 0 for KVM_X86_LEGACY_VM
// 1 for KVM_X86_TDX_VM
#[cfg(feature = "tdx")]
let vm = hypervisor
.create_vm_with_type(u64::from(tdx_enabled))
.unwrap();
#[cfg(not(feature = "tdx"))]
let vm = hypervisor.create_vm().unwrap();
cfg_if::cfg_if! {
if #[cfg(feature = "tdx")] {
let vm = hypervisor
.create_vm_with_type(if tdx_enabled {
1 // KVM_X86_TDX_VM
} else {
0 // KVM_X86_LEGACY_VM
})
.unwrap();
} else if #[cfg(feature = "sev_snp")] {
let vm = hypervisor
.create_vm_with_type(if sev_snp_enabled {
1 // SEV_SNP_ENABLED
} else {
0 // SEV_SNP_DISABLED
})
.unwrap();
} else {
let vm = hypervisor.create_vm().unwrap();
}
}
#[cfg(target_arch = "x86_64")]
{