From b0077f0b5efa01d53942b86b62454b6001ed9925 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 30 Mar 2022 12:06:52 +0200 Subject: [PATCH] hypervisor: Implement retrieval of TDX capabilities Extend the Hypervisor API in order to retrieve the TDX capabilities from the underlying hypervisor. Signed-off-by: Sebastien Boeuf --- hypervisor/src/hypervisor.rs | 12 +++++++++ hypervisor/src/kvm/mod.rs | 50 +++++++++++++++++++++++++++++++++++- hypervisor/src/lib.rs | 2 ++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/hypervisor/src/hypervisor.rs b/hypervisor/src/hypervisor.rs index 6fe5e8e79..9612836b8 100644 --- a/hypervisor/src/hypervisor.rs +++ b/hypervisor/src/hypervisor.rs @@ -12,6 +12,8 @@ use crate::vm::Vm; use crate::x86_64::CpuId; #[cfg(target_arch = "x86_64")] use crate::x86_64::MsrList; +#[cfg(feature = "tdx")] +use crate::TdxCapabilities; use std::sync::Arc; use thiserror::Error; @@ -59,6 +61,11 @@ pub enum HypervisorError { /// #[error("Checking extensions:{0}")] CheckExtensions(#[source] anyhow::Error), + /// + /// Failed to retrieve TDX capabilities + /// + #[error("Failed to retrieve TDX capabilities:{0}")] + TdxCapabilities(#[source] anyhow::Error), } /// @@ -105,4 +112,9 @@ pub trait Hypervisor: Send + Sync { /// Retrieve AArch64 host maximum IPA size supported by KVM. /// fn get_host_ipa_limit(&self) -> i32; + /// + /// Retrieve TDX capabilities + /// + #[cfg(feature = "tdx")] + fn tdx_capabilities(&self) -> Result; } diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 8636dc7f6..658bef4ef 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -107,7 +107,6 @@ ioctl_iowr_nr!(KVM_MEMORY_ENCRYPT_OP, KVMIO, 0xba, std::os::raw::c_ulong); #[cfg(feature = "tdx")] #[repr(u32)] enum TdxCommand { - #[allow(dead_code)] Capabilities = 0, InitVm, InitVcpu, @@ -127,6 +126,34 @@ pub enum TdxExitStatus { InvalidOperand, } +#[cfg(feature = "tdx")] +const TDX_MAX_NR_CPUID_CONFIGS: usize = 6; + +#[cfg(feature = "tdx")] +#[repr(C)] +#[derive(Debug, Default)] +pub struct TdxCpuidConfig { + pub leaf: u32, + pub sub_leaf: u32, + pub eax: u32, + pub ebx: u32, + pub ecx: u32, + pub edx: u32, +} + +#[cfg(feature = "tdx")] +#[repr(C)] +#[derive(Debug, Default)] +pub struct TdxCapabilities { + pub attrs_fixed0: u64, + pub attrs_fixed1: u64, + pub xfam_fixed0: u64, + pub xfam_fixed1: u64, + pub nr_cpuid_configs: u32, + pub padding: u32, + pub cpuid_configs: [TdxCpuidConfig; TDX_MAX_NR_CPUID_CONFIGS], +} + #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] pub struct KvmVmState {} @@ -762,6 +789,27 @@ impl hypervisor::Hypervisor for KvmHypervisor { fn get_host_ipa_limit(&self) -> i32 { self.kvm.get_host_ipa_limit() } + + /// + /// Retrieve TDX capabilities + /// + #[cfg(feature = "tdx")] + fn tdx_capabilities(&self) -> hypervisor::Result { + let data = TdxCapabilities { + nr_cpuid_configs: TDX_MAX_NR_CPUID_CONFIGS as u32, + ..Default::default() + }; + + tdx_command( + &self.kvm.as_raw_fd(), + TdxCommand::Capabilities, + 0, + &data as *const _ as u64, + ) + .map_err(|e| hypervisor::HypervisorError::TdxCapabilities(e.into()))?; + + Ok(data) + } } /// Vcpu struct for KVM pub struct KvmVcpu { diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index a64c68c44..4e7b32f44 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -51,6 +51,8 @@ mod device; pub use crate::hypervisor::{Hypervisor, HypervisorError}; pub use cpu::{HypervisorCpuError, Vcpu, VmExit}; pub use device::{Device, HypervisorDeviceError}; +#[cfg(feature = "tdx")] +pub use kvm::TdxCapabilities; #[cfg(feature = "kvm")] pub use kvm::*; #[cfg(all(feature = "mshv", target_arch = "x86_64"))]