Merge pull request #6243 from openanolis/chao/tdx_1_vm_type

CC |  Dragonball: add confidential_vm_type for TDX
This commit is contained in:
Fabiano Fidêncio 2023-02-14 08:42:31 +01:00 committed by GitHub
commit b74e84e123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 12 deletions

View File

@ -5,6 +5,15 @@
use serde_derive::{Deserialize, Serialize};
/// This struct represents the strongly typed equivalent of the json body
/// from confidential container related requests.
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub enum ConfidentialVmType {
/// Intel Trusted Domain
TDX = 2,
}
/// The microvm state.
///
/// When Dragonball starts, the instance state is Uninitialized. Once start_microvm method is
@ -56,10 +65,12 @@ pub struct InstanceInfo {
pub tids: Vec<(u8, u32)>,
/// Last instance downtime
pub last_instance_downtime: u64,
/// confidential vm type
pub confidential_vm_type: Option<ConfidentialVmType>,
}
impl InstanceInfo {
/// create instance info object with given id, version, and platform type
/// create instance info object with given id, version, platform type and confidential vm type.
pub fn new(id: String, vmm_version: String) -> Self {
InstanceInfo {
id,
@ -69,6 +80,7 @@ impl InstanceInfo {
async_state: AsyncState::Uninitialized,
tids: Vec::new(),
last_instance_downtime: 0,
confidential_vm_type: None,
}
}
}
@ -83,6 +95,7 @@ impl Default for InstanceInfo {
async_state: AsyncState::Uninitialized,
tids: Vec::new(),
last_instance_downtime: 0,
confidential_vm_type: None,
}
}
}

View File

@ -12,7 +12,7 @@ pub use self::boot_source::{BootSourceConfig, BootSourceConfigError, DEFAULT_KER
/// Wrapper over the microVM general information.
mod instance_info;
pub use self::instance_info::{InstanceInfo, InstanceState};
pub use self::instance_info::{ConfidentialVmType, InstanceInfo, InstanceState};
/// Wrapper for configuring the memory and CPU of the microVM.
mod machine_config;

View File

@ -68,6 +68,10 @@ pub enum Error {
/// Cannot open the VM file descriptor.
#[error(transparent)]
Vm(vm::VmError),
/// confidential vm type Error
#[error("confidential-vm-type can only be used in x86_64 now")]
ConfidentialVmType,
}
/// Errors associated with starting the instance.

View File

@ -10,7 +10,7 @@ use kvm_bindings::KVM_API_VERSION;
use kvm_ioctls::{Cap, Kvm, VmFd};
use std::os::unix::io::{FromRawFd, RawFd};
use crate::error::{Error, Result};
use crate::error::{Error as VmError, Result};
/// Describes a KVM context that gets attached to the micro VM instance.
/// It gives access to the functionality of the KVM wrapper as long as every required
@ -29,11 +29,11 @@ impl KvmContext {
// Safe because we expect kvm_fd to contain a valid fd number when is_some() == true.
unsafe { Kvm::from_raw_fd(fd) }
} else {
Kvm::new().map_err(Error::Kvm)?
Kvm::new().map_err(VmError::Kvm)?
};
if kvm.get_api_version() != KVM_API_VERSION as i32 {
return Err(Error::KvmApiVersion(kvm.get_api_version()));
return Err(VmError::KvmApiVersion(kvm.get_api_version()));
}
Self::check_cap(&kvm, Cap::Irqchip)?;
@ -44,7 +44,8 @@ impl KvmContext {
Self::check_cap(&kvm, Cap::SetTssAddr)?;
#[cfg(target_arch = "x86_64")]
let supported_msrs = dbs_arch::msr::supported_guest_msrs(&kvm).map_err(Error::GuestMSRs)?;
let supported_msrs =
dbs_arch::msr::supported_guest_msrs(&kvm).map_err(VmError::GuestMSRs)?;
let max_memslots = kvm.get_nr_memslots();
Ok(KvmContext {
@ -67,7 +68,7 @@ impl KvmContext {
/// Create a virtual machine object.
pub fn create_vm(&self) -> Result<VmFd> {
self.kvm.create_vm().map_err(Error::Kvm)
self.kvm.create_vm().map_err(VmError::Kvm)
}
/// Get the max vcpu count supported by kvm
@ -75,9 +76,9 @@ impl KvmContext {
self.kvm.get_max_vcpus()
}
fn check_cap(kvm: &Kvm, cap: Cap) -> std::result::Result<(), Error> {
fn check_cap(kvm: &Kvm, cap: Cap) -> std::result::Result<(), VmError> {
if !kvm.check_extension(cap) {
return Err(Error::KvmCap(cap));
return Err(VmError::KvmCap(cap));
}
Ok(())
}
@ -91,6 +92,18 @@ mod x86_64 {
use std::collections::HashSet;
impl KvmContext {
/// Create a virtual machine object with specific type.
/// vm_type: u64
/// 0: legacy vm
/// 2: tdx vm
pub fn create_vm_with_type(&self, vm_type: u64) -> Result<VmFd> {
let fd = self
.kvm
.create_vm_with_type(vm_type)
.map_err(VmError::Kvm)?;
Ok(fd)
}
/// Get information about supported CPUID of x86 processor.
pub fn supported_cpuid(
&self,
@ -110,7 +123,7 @@ mod x86_64 {
// It's very sensible to manipulate MSRs, so please be careful to change code below.
fn build_msrs_list(kvm: &Kvm) -> Result<Msrs> {
let mut mset: HashSet<u32> = HashSet::new();
let supported_msr_list = kvm.get_msr_index_list().map_err(super::Error::Kvm)?;
let supported_msr_list = kvm.get_msr_index_list().map_err(VmError::Kvm)?;
for msr in supported_msr_list.as_slice() {
mset.insert(*msr);
}
@ -203,7 +216,7 @@ mod x86_64 {
})
.collect();
Msrs::from_entries(&msrs).map_err(super::Error::Msr)
Msrs::from_entries(&msrs).map_err(VmError::Msr)
}
}
}
@ -257,4 +270,20 @@ mod tests {
let _ = c.create_vm().unwrap();
}
#[test]
fn test_create_vm_with_type() {
let c = KvmContext::new(None).unwrap();
#[cfg(not(target_arch = "aarch64"))]
let _ = c.create_vm_with_type(0_u64).unwrap();
#[cfg(target_arch = "aarch64")]
{
/// aarch64 is using ipa_size to create vm
let mut ipa_size = 0; // Create using default VM type
if c.check_extension(kvm_ioctls::Cap::ArmVmIPASize) {
ipa_size = c.kvm.get_host_ipa_limit();
}
let _ = c.create_vm_with_type(ipa_size as u64).unwrap();
}
}
}

View File

@ -203,7 +203,26 @@ impl Vm {
let id = api_shared_info.read().unwrap().id.clone();
let logger = slog_scope::logger().new(slog::o!("id" => id));
let kvm = KvmContext::new(kvm_fd)?;
let vm_fd = Arc::new(kvm.create_vm()?);
let vm_fd = match api_shared_info
.as_ref()
.read()
.unwrap()
.confidential_vm_type
{
None => Arc::new(kvm.create_vm()?),
Some(confidential_vm_type) => {
#[cfg(not(any(target_arch = "x86_64")))]
{
error!(
"confidential-vm-type {} only can be used in x86_64",
confidential_vm_type as u64
);
return Err(Error::ConfidentialVmType);
}
#[cfg(target_arch = "x86_64")]
Arc::new(kvm.create_vm_with_type(confidential_vm_type as u64)?)
}
};
let resource_manager = Arc::new(ResourceManager::new(Some(kvm.max_memslots())));
let device_manager = DeviceManager::new(
vm_fd.clone(),