英特尔可信域扩展 (TDX)¶
概述¶
英特尔的可信域扩展 (TDX) 保护机密客户虚拟机免受主机和物理攻击。一个名为“TDX 模块”的 CPU 认证软件模块在一个新的 CPU 隔离范围内运行,以提供管理和运行受保护虚拟机(又称 TDX 客户机或 TD)的功能。
请参阅 [1] 获取白皮书、规范和其他资源。
本文档描述了 TDX 特有的 KVM ABI。TDX 模块在使用 KVM 运行任何 TDX 客户机之前需要进行初始化。主机核心内核提供初始化 TDX 模块的支持,具体描述请参见英特尔可信域扩展 (TDX)。
API 描述¶
KVM_MEMORY_ENCRYPT_OP¶
- 类型:
VM ioctl, VCPU ioctl
对于 TDX 操作,KVM_MEMORY_ENCRYPT_OP 被重新用作带有 TDX 特定子 ioctl() 命令的通用 ioctl。
/* Trust Domain Extensions sub-ioctl() commands. */
enum kvm_tdx_cmd_id {
KVM_TDX_CAPABILITIES = 0,
KVM_TDX_INIT_VM,
KVM_TDX_INIT_VCPU,
KVM_TDX_INIT_MEM_REGION,
KVM_TDX_FINALIZE_VM,
KVM_TDX_GET_CPUID,
KVM_TDX_CMD_NR_MAX,
};
struct kvm_tdx_cmd {
/* enum kvm_tdx_cmd_id */
__u32 id;
/* flags for sub-command. If sub-command doesn't use this, set zero. */
__u32 flags;
/*
* data for each sub-command. An immediate or a pointer to the actual
* data in process virtual address. If sub-command doesn't use it,
* set zero.
*/
__u64 data;
/*
* Auxiliary error code. The sub-command may return TDX SEAMCALL
* status code in addition to -Exxx.
*/
__u64 hw_error;
};
KVM_TDX_CAPABILITIES¶
- 类型:
VM ioctl
- 返回值:
成功时为 0,错误时为 <0
返回当前 KVM 在系统中加载特定 TDX 模块后支持的 TDX 功能。它报告允许为 TDX 客户机配置哪些功能/特性。
id: KVM_TDX_CAPABILITIES
flags: 必须为 0
data: 指向 struct kvm_tdx_capabilities 的指针
hw_error: 必须为 0
struct kvm_tdx_capabilities {
__u64 supported_attrs;
__u64 supported_xfam;
__u64 reserved[254];
/* Configurable CPUID bits for userspace */
struct kvm_cpuid2 cpuid;
};
KVM_TDX_INIT_VM¶
- 类型:
VM ioctl
- 返回值:
成功时为 0,错误时为 <0
执行 TDX 特定的 VM 初始化。这需要在调用 KVM_CREATE_VM 之后、创建任何 VCPU 之前调用。
id: KVM_TDX_INIT_VM
flags: 必须为 0
data: 指向 struct kvm_tdx_init_vm 的指针
hw_error: 必须为 0
struct kvm_tdx_init_vm {
__u64 attributes;
__u64 xfam;
__u64 mrconfigid[6]; /* sha384 digest */
__u64 mrowner[6]; /* sha384 digest */
__u64 mrownerconfig[6]; /* sha384 digest */
/* The total space for TD_PARAMS before the CPUIDs is 256 bytes */
__u64 reserved[12];
/*
* Call KVM_TDX_INIT_VM before vcpu creation, thus before
* KVM_SET_CPUID2.
* This configuration supersedes KVM_SET_CPUID2s for VCPUs because the
* TDX module directly virtualizes those CPUIDs without VMM. The user
* space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with
* those values. If it doesn't, KVM may have wrong idea of vCPUIDs of
* the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX
* module doesn't virtualize.
*/
struct kvm_cpuid2 cpuid;
};
KVM_TDX_INIT_VCPU¶
- 类型:
VCPU ioctl
- 返回值:
成功时为 0,错误时为 <0
执行 TDX 特定的 VCPU 初始化。
id: KVM_TDX_INIT_VCPU
flags: 必须为 0
data: 客户机 TD VCPU RCX 的初始值
hw_error: 必须为 0
KVM_TDX_INIT_MEM_REGION¶
- 类型:
VCPU ioctl
- 返回值:
成功时为 0,错误时为 <0
使用用户空间提供的 @source_addr 数据,从 @gpa 开始初始化 @nr_pages 的 TDX 客户机私有内存。
注意,在调用此子命令之前,范围 [gpa, gpa + nr_pages] 的内存属性需要是私有的。用户空间可以使用 KVM_SET_MEMORY_ATTRIBUTES 来设置属性。
如果指定了 KVM_TDX_MEASURE_MEMORY_REGION 标志,它还会扩展测量。
id: KVM_TDX_INIT_MEM_REGION
flags: 目前仅定义了 KVM_TDX_MEASURE_MEMORY_REGION
data: 指向 struct kvm_tdx_init_mem_region 的指针
hw_error: 必须为 0
#define KVM_TDX_MEASURE_MEMORY_REGION (1UL << 0)
struct kvm_tdx_init_mem_region {
__u64 source_addr;
__u64 gpa;
__u64 nr_pages;
};
KVM_TDX_FINALIZE_VM¶
- 类型:
VM ioctl
- 返回值:
成功时为 0,错误时为 <0
完成初始 TD 内容的测量并标记为可运行。
id: KVM_TDX_FINALIZE_VM
flags: 必须为 0
data: 必须为 0
hw_error: 必须为 0
KVM_TDX_GET_CPUID¶
- 类型:
VCPU ioctl
- 返回值:
成功时为 0,错误时为 <0
获取 TDX 模块为 TD 客户机虚拟化的 CPUID 值。当返回 -E2BIG 时,用户空间应分配更大的缓冲区并重试。最小缓冲区大小会在 struct kvm_cpuid2 的 nent 字段中更新。
id: KVM_TDX_GET_CPUID
flags: 必须为 0
data: 指向 struct kvm_cpuid2 的指针 (输入/输出)
hw_error: 必须为 0 (输出)
struct kvm_cpuid2 {
__u32 nent;
__u32 padding;
struct kvm_cpuid_entry2 entries[0];
};
struct kvm_cpuid_entry2 {
__u32 function;
__u32 index;
__u32 flags;
__u32 eax;
__u32 ebx;
__u32 ecx;
__u32 edx;
__u32 padding[3];
};
KVM TDX 创建流程¶
除了标准的 KVM 流程外,还需要调用新的 TDX ioctl。控制流程如下
检查系统范围功能
KVM_CAP_VM_TYPES: 检查是否支持 VM 类型以及是否支持 KVM_X86_TDX_VM。
创建 VM
KVM_CREATE_VM
KVM_TDX_CAPABILITIES: 查询用于创建 TDX 客户机的 TDX 功能。
KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPUS): 查询 TD 在 VM 级别可以支持的最大 VCPU 数量 (TDX 在此方面有自己的限制)。
KVM_SET_TSC_KHZ: 如果需要与主机不同的 TSC 频率,请配置 TD 的 TSC 频率。这是可选的。
KVM_TDX_INIT_VM: 传递 TDX 特定的 VM 参数。
创建 VCPU
KVM_CREATE_VCPU
KVM_TDX_INIT_VCPU: 传递 TDX 特定的 VCPU 参数。
KVM_SET_CPUID2: 配置 TD 的 CPUID。
KVM_SET_MSRS: 配置 TD 的 MSR。
初始化初始客户机内存
准备初始客户机内存的内容。
KVM_TDX_INIT_MEM_REGION: 添加初始客户机内存。
KVM_TDX_FINALIZE_VM: 完成 TDX 客户机的测量。
运行 VCPU
参考¶
https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html