-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements the API for running the KVM_TDX_CAPABILITIES sub-ioctl() for the Intel TDX architecture. The documentation for the structures implemented comes from the Intel TDX Module 1.5 ABI spec. Signed-off-by: Jake Correnti <[email protected]>
- Loading branch information
1 parent
7b8614c
commit 91abb5b
Showing
6 changed files
with
323 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,41 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use crate::vm::linux::types::Capabilities; | ||
|
||
/// Trust Domain eXtensions sub-ioctl() commands | ||
#[repr(u32)] | ||
pub enum CmdId { | ||
GetCapabilities = 0, | ||
} | ||
|
||
/// Contains information for the sub-ioctl() command to be run. This is | ||
/// equivalent to `struct kvm_tdx_cmd` in the kernel. | ||
#[derive(Default)] | ||
#[repr(C)] | ||
pub struct Cmd { | ||
/// TDX command identifier | ||
pub id: u32, | ||
/// Flags for sub-command. If sub-command doesn't use it, set to zero. | ||
pub flags: u32, | ||
/// A u64 representing a generic pointer to the respective ioctl input. | ||
/// This data is read differently according to the TDX ioctl identifier. | ||
pub data: u64, | ||
/// Auxiliary error code. The sub-command may return TDX SEAMCALL status | ||
/// code in addition to -Exxx. | ||
/// Defined for consistency with `struct kvm_sev_cmd` | ||
pub error: u64, | ||
/// Reserved. | ||
pub unused: u64, | ||
} | ||
|
||
impl From<&Capabilities> for Cmd { | ||
fn from(caps: &Capabilities) -> Self { | ||
Self { | ||
id: CmdId::GetCapabilities as u32, | ||
flags: 0, | ||
data: caps as *const Capabilities as _, | ||
error: 0, | ||
unused: 0, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
pub mod ioctl; | ||
pub mod types; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,86 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
pub const NR_CPUID_CONFIGS: usize = 12; | ||
|
||
/// CPUID_CONFIG is designed to enumerate how the host VMM may configure the | ||
/// virtualization done by the Intel TDX module for a single CPUID leaf and | ||
/// sub-leaf. This is equivalent to `struct kvm_tdx_cpuid_config` in the kernel. | ||
#[derive(Debug, Default, Clone, Copy)] | ||
#[repr(C)] | ||
pub struct CpuidConfig { | ||
/// EAX input value to CPUID | ||
pub leaf: u32, | ||
/// ECX input value to CPUID. A value of -1 indicates a CPUID leaf with | ||
/// no sub-leaves. | ||
pub sub_leaf: u32, | ||
/// CPUID configuration information for the EAX register. | ||
pub eax: u32, | ||
/// CPUID configuration information for the EBX register. | ||
pub ebx: u32, | ||
/// CPUID configuration information for the ECX register. | ||
pub ecx: u32, | ||
/// CPUID configuration information for the EDX register. | ||
pub edx: u32, | ||
} | ||
|
||
/// Provides information about the Intel TDX module. This is equivalent to | ||
/// `struct kvm_tdx_capabilities` in the kernel. | ||
#[derive(Debug)] | ||
#[repr(C)] | ||
pub struct Capabilities { | ||
/// Bitmap where if any certain bit is 0, it must be 0 in any TD's | ||
/// ATTRIBUTES, which specifies various guest TD attributes. The value of | ||
/// this field reflects the Intel TDX module capabilities and configuration | ||
/// and CPU capabilities. | ||
pub attrs_fixed0: u64, | ||
/// Bitmap where if any certain bit is 1, it must be 1 in any TD's | ||
/// ATTRIBUTES, which specifies various guest TD attributes. The value of | ||
/// this field reflects the Intel TDX module capabilities and configuration | ||
/// and CPU capabilities. | ||
pub attrs_fixed1: u64, | ||
/// Bitmap where if any certain bit is 0, it must be 0 in any TD's XFAM. | ||
/// XFAM (eXtended Features Available Mask) determines the set of extended | ||
/// features available for use by the guest TD. | ||
pub xfam_fixed0: u64, | ||
/// Bitmap where if any certain bit is 1, it must be 1 in any TD's XFAM. | ||
/// XFAM (eXtended Features Available Mask) determines the set of extended | ||
/// features available for use by the guest TD. | ||
pub xfam_fixed1: u64, | ||
/// Supported Guest Physical Address Width | ||
pub supported_gpaw: u32, | ||
/// Padding space. Ignored | ||
_padding: u32, | ||
/// Reserved space. Ignored. | ||
_reserved: [u64; 251], | ||
|
||
/// Number of CPUID_CONFIG entries | ||
pub nr_cpuid_configs: u32, | ||
/// Enumeration of the CPUID leaves/sub-leaves that contain bit fields whose | ||
/// virtualization by the Intel TDX module is either: | ||
/// | ||
/// - Directly configurable (CONFIG_DIRECT) by the host VMM | ||
/// - Bits that the host VMM may allow to be 1 (ALLOW_DIRECT) and their | ||
/// native value, as returned by the CPU, is 1 | ||
/// | ||
/// Note that the virtualization of many CPUID bit fields not enumerated in | ||
/// this list is configurable indirectly via the XFAM and ATTRIBUTES assigned | ||
/// to a TD by the host VMM. | ||
pub cpuid_configs: [CpuidConfig; NR_CPUID_CONFIGS], | ||
} | ||
|
||
impl Default for Capabilities { | ||
fn default() -> Self { | ||
Self { | ||
attrs_fixed0: 0, | ||
attrs_fixed1: 0, | ||
xfam_fixed0: 0, | ||
xfam_fixed1: 0, | ||
supported_gpaw: 0, | ||
_padding: 0, | ||
_reserved: [0; 251], | ||
|
||
nr_cpuid_configs: NR_CPUID_CONFIGS as u32, | ||
cpuid_configs: [Default::default(); NR_CPUID_CONFIGS], | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,194 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
mod linux; | ||
|
||
use crate::vm::linux::{ | ||
ioctl::Cmd, | ||
types::{Capabilities, CpuidConfig}, | ||
}; | ||
use bitflags::bitflags; | ||
use kvm_ioctls::{Kvm, VmFd}; | ||
|
||
// Defined in linux/arch/x86/include/uapi/asm/kvm.h | ||
const KVM_X86_TDX_VM: u64 = 2; | ||
|
||
/// Handle to the TDX VM file descriptor | ||
pub struct TdxVm(VmFd); | ||
|
||
impl TdxVm { | ||
/// Create a new TDX VM with KVM | ||
pub fn new(kvm_fd: Kvm) -> Result<Self, TdxError> { | ||
let vm_fd = kvm_fd.create_vm_with_type(KVM_X86_TDX_VM)?; | ||
Ok(Self(vm_fd)) | ||
} | ||
|
||
/// Retrieve information about the Intel TDX module | ||
pub fn get_capabilities(&self) -> Result<TdxCapabilities, TdxError> { | ||
let caps = Capabilities::default(); | ||
let mut cmd: Cmd = Cmd::from(&caps); | ||
|
||
unsafe { | ||
if let Err(e) = self.0.encrypt_op(&mut cmd) { | ||
return Err(TdxError::from(e)); | ||
} | ||
} | ||
|
||
Ok(TdxCapabilities { | ||
attributes: Attributes { | ||
fixed0: AttributesFlags::from_bits_truncate(caps.attrs_fixed0), | ||
fixed1: AttributesFlags::from_bits_truncate(caps.attrs_fixed1), | ||
}, | ||
xfam: Xfam { | ||
fixed0: XFAMFlags::from_bits_truncate(caps.xfam_fixed0), | ||
fixed1: XFAMFlags::from_bits_truncate(caps.xfam_fixed1), | ||
}, | ||
supported_gpaw: caps.supported_gpaw, | ||
cpuid_configs: Vec::from(caps.cpuid_configs), | ||
}) | ||
} | ||
} | ||
|
||
bitflags! { | ||
#[derive(Debug)] | ||
pub struct AttributesFlags: u64 { | ||
/// TD Under Debug (TUD) group | ||
|
||
/// Bit 0. Guest TD runs in off-TD debug mode | ||
const DEBUG = 1; | ||
/// Bits 3:1. Reserved for future TUD flags | ||
const TUD_RESERVED = 0x7 << 1; | ||
|
||
/// TD Under Profiling (TUP) group | ||
|
||
/// Bit 4. The TD participates in HGS+ operation | ||
const HGS_PLUS_PROF = 1 << 4; | ||
/// Bit 5. The TD participates in system profiling using performance monitoring | ||
/// counters | ||
const PERF_PROF = 1 << 5; | ||
/// Bit 6. The TD participates in system profiling using core out-of-band | ||
/// telemetry | ||
const PMT_PROF = 1 << 6; | ||
/// Bits 15:7. Reserved for future TUP flags | ||
const TUP_RESERVED = 0x1FF << 7; | ||
|
||
/// Security (SEC) group | ||
|
||
/// Bits 22:16. Reserved for future SEC flags that will indicate positive impact on | ||
/// TD security | ||
const SEC_RESERVED_P = 0x7F << 16; | ||
/// Bits 23:26. Reserved for future SEC flags that will indicate negative impact on | ||
/// TD security | ||
const SEC_RESERVED_N = 0xF << 23; | ||
/// Bit 27. TD is allowed to use Linear Address Space Separation | ||
const LASS = 1 << 27; | ||
/// Bit 28. Disable EPT violation conversion to #VE on guest TD access of | ||
/// PENDING pages | ||
const SEPT_VE_DISABLE = 1 << 28; | ||
/// Bit 29. TD is migratable (using a Migration TD) | ||
const MIGRATABLE = 1 << 29; | ||
/// Bit 30. TD is allowed to use Supervisor Protection Keys | ||
const PKS = 1 << 30; | ||
/// Bit 31. TD is allowed to use Key Locker | ||
const KL = 1 << 31; | ||
|
||
/// RESERVED Group | ||
|
||
/// Bits 55:32. Reserved for future expansion of the SEC group | ||
const SEC_EXP_RESERVED = 0xFFFFFF << 32; | ||
|
||
/// OTHER group | ||
|
||
/// Bits 61:32. Reserved for future OTHER flags | ||
const OTHER_RESERVED = 0x3FFFFFFF << 32; | ||
/// Bit 62. The TD is a TDX Connet Provisioning Agent | ||
const TPA = 1 << 62; | ||
/// Bit 63. TD is allowed to use Perfmon and PERF_METRICS capabilities | ||
const PERFMON = 1 << 63; | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct XFAMFlags: u64 { | ||
/// Bit 0. Always enabled | ||
const FP = 1; | ||
/// Bit 1. Always enabled | ||
const SSE = 1 << 1; | ||
/// Bit 2. Execution is directly controlled by XCR0 | ||
const AVX = 1 << 2; | ||
/// Bits 4:3. Being deprecated | ||
const MPX = 0x3 << 3; | ||
/// Bits 7:5. Execution is directly contrtolled by XCR0. May be enabled only if | ||
/// AVX is enabled | ||
const AVX512 = 0x7 << 5; | ||
/// Bit 8. Execution is controlled by IA32_RTIT_CTL | ||
const PT = 1 << 8; | ||
/// Bit 9. Execution is controlled by CR4.PKE | ||
const PK = 1 << 9; | ||
/// Bit 10. Execution is controlled by IA32_PASID MSR | ||
const ENQCMD = 1 << 10; | ||
/// Bits 12:11. Execution is controlled by CR4.CET | ||
const CET = 0x3 << 11; | ||
/// Bit 13. Hardware Duty Cycle is controlled by package-scope IA32_PKG_HDC_CTL | ||
/// and LP-scope IA32_PM_CTL1 MSRs | ||
const HDC = 1 << 13; | ||
/// Bit 14. Execution is controlled by CR4.UINTR | ||
const ULI = 1 << 14; | ||
/// Bit 15. Execution is controlled by IA32_LBR_CTL | ||
const LBR = 1 << 15; | ||
/// Bit 16. Execution of Hardware-Controlled Performance State is controlled by | ||
/// IA32_HWP MSRs | ||
const HWP = 1 << 16; | ||
/// Bits 18:17. Advanced Matrix Extensions (AMX) is directly controlled by XCR0 | ||
const AMX = 0x3 << 17; | ||
} | ||
} | ||
|
||
/// Reflects the Intel TDX module capabilities and configuration and CPU | ||
/// capabilities | ||
#[derive(Debug)] | ||
pub struct Attributes { | ||
pub fixed0: AttributesFlags, | ||
pub fixed1: AttributesFlags, | ||
} | ||
|
||
/// Determines the set of extended features available for use by the guest TD | ||
#[derive(Debug)] | ||
pub struct Xfam { | ||
pub fixed0: XFAMFlags, | ||
pub fixed1: XFAMFlags, | ||
} | ||
|
||
/// Provides information about the Intel TDX module | ||
#[derive(Debug)] | ||
pub struct TdxCapabilities { | ||
pub attributes: Attributes, | ||
pub xfam: Xfam, | ||
/// supported Guest Physical Address Width | ||
pub supported_gpaw: u32, | ||
|
||
pub cpuid_configs: Vec<CpuidConfig>, | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct TdxError { | ||
pub code: i32, | ||
pub message: String, | ||
} | ||
|
||
impl From<kvm_ioctls::Error> for TdxError { | ||
fn from(kvm_err: kvm_ioctls::Error) -> Self { | ||
match kvm_err.errno() { | ||
7 => TdxError { | ||
code: 7, | ||
message: String::from("Invalid value for NR_CPUID_CONFIGS"), | ||
}, | ||
25 => TdxError { | ||
code: 25, | ||
message: String::from("Inappropriate ioctl for device. Ensure the proper VM type is being used for the ioctl"), | ||
}, | ||
_ => TdxError { | ||
code: kvm_err.errno(), | ||
message: format!("errno: {}", kvm_err.errno()), | ||
}, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters