1.. SPDX-License-Identifier: GPL-2.0 2 3=================================== 4Intel Trust Domain Extensions (TDX) 5=================================== 6 7Overview 8======== 9Intel's Trust Domain Extensions (TDX) protect confidential guest VMs from the 10host and physical attacks. A CPU-attested software module called 'the TDX 11module' runs inside a new CPU isolated range to provide the functionalities to 12manage and run protected VMs, a.k.a, TDX guests or TDs. 13 14Please refer to [1] for the whitepaper, specifications and other resources. 15 16This documentation describes TDX-specific KVM ABIs. The TDX module needs to be 17initialized before it can be used by KVM to run any TDX guests. The host 18core-kernel provides the support of initializing the TDX module, which is 19described in the Documentation/arch/x86/tdx.rst. 20 21API description 22=============== 23 24KVM_MEMORY_ENCRYPT_OP 25--------------------- 26:Type: vm ioctl, vcpu ioctl 27 28For TDX operations, KVM_MEMORY_ENCRYPT_OP is re-purposed to be generic 29ioctl with TDX specific sub-ioctl() commands. 30 31:: 32 33 /* Trust Domain Extensions sub-ioctl() commands. */ 34 enum kvm_tdx_cmd_id { 35 KVM_TDX_CAPABILITIES = 0, 36 KVM_TDX_INIT_VM, 37 KVM_TDX_INIT_VCPU, 38 KVM_TDX_INIT_MEM_REGION, 39 KVM_TDX_FINALIZE_VM, 40 KVM_TDX_GET_CPUID, 41 42 KVM_TDX_CMD_NR_MAX, 43 }; 44 45 struct kvm_tdx_cmd { 46 /* enum kvm_tdx_cmd_id */ 47 __u32 id; 48 /* flags for sub-command. If sub-command doesn't use this, set zero. */ 49 __u32 flags; 50 /* 51 * data for each sub-command. An immediate or a pointer to the actual 52 * data in process virtual address. If sub-command doesn't use it, 53 * set zero. 54 */ 55 __u64 data; 56 /* 57 * Auxiliary error code. The sub-command may return TDX SEAMCALL 58 * status code in addition to -Exxx. 59 */ 60 __u64 hw_error; 61 }; 62 63KVM_TDX_CAPABILITIES 64-------------------- 65:Type: vm ioctl 66:Returns: 0 on success, <0 on error 67 68Return the TDX capabilities that current KVM supports with the specific TDX 69module loaded in the system. It reports what features/capabilities are allowed 70to be configured to the TDX guest. 71 72- id: KVM_TDX_CAPABILITIES 73- flags: must be 0 74- data: pointer to struct kvm_tdx_capabilities 75- hw_error: must be 0 76 77:: 78 79 struct kvm_tdx_capabilities { 80 __u64 supported_attrs; 81 __u64 supported_xfam; 82 __u64 reserved[254]; 83 84 /* Configurable CPUID bits for userspace */ 85 struct kvm_cpuid2 cpuid; 86 }; 87 88 89KVM_TDX_INIT_VM 90--------------- 91:Type: vm ioctl 92:Returns: 0 on success, <0 on error 93 94Perform TDX specific VM initialization. This needs to be called after 95KVM_CREATE_VM and before creating any VCPUs. 96 97- id: KVM_TDX_INIT_VM 98- flags: must be 0 99- data: pointer to struct kvm_tdx_init_vm 100- hw_error: must be 0 101 102:: 103 104 struct kvm_tdx_init_vm { 105 __u64 attributes; 106 __u64 xfam; 107 __u64 mrconfigid[6]; /* sha384 digest */ 108 __u64 mrowner[6]; /* sha384 digest */ 109 __u64 mrownerconfig[6]; /* sha384 digest */ 110 111 /* The total space for TD_PARAMS before the CPUIDs is 256 bytes */ 112 __u64 reserved[12]; 113 114 /* 115 * Call KVM_TDX_INIT_VM before vcpu creation, thus before 116 * KVM_SET_CPUID2. 117 * This configuration supersedes KVM_SET_CPUID2s for VCPUs because the 118 * TDX module directly virtualizes those CPUIDs without VMM. The user 119 * space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with 120 * those values. If it doesn't, KVM may have wrong idea of vCPUIDs of 121 * the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX 122 * module doesn't virtualize. 123 */ 124 struct kvm_cpuid2 cpuid; 125 }; 126 127 128KVM_TDX_INIT_VCPU 129----------------- 130:Type: vcpu ioctl 131:Returns: 0 on success, <0 on error 132 133Perform TDX specific VCPU initialization. 134 135- id: KVM_TDX_INIT_VCPU 136- flags: must be 0 137- data: initial value of the guest TD VCPU RCX 138- hw_error: must be 0 139 140KVM_TDX_INIT_MEM_REGION 141----------------------- 142:Type: vcpu ioctl 143:Returns: 0 on success, <0 on error 144 145Initialize @nr_pages TDX guest private memory starting from @gpa with userspace 146provided data from @source_addr. 147 148Note, before calling this sub command, memory attribute of the range 149[gpa, gpa + nr_pages] needs to be private. Userspace can use 150KVM_SET_MEMORY_ATTRIBUTES to set the attribute. 151 152If KVM_TDX_MEASURE_MEMORY_REGION flag is specified, it also extends measurement. 153 154- id: KVM_TDX_INIT_MEM_REGION 155- flags: currently only KVM_TDX_MEASURE_MEMORY_REGION is defined 156- data: pointer to struct kvm_tdx_init_mem_region 157- hw_error: must be 0 158 159:: 160 161 #define KVM_TDX_MEASURE_MEMORY_REGION (1UL << 0) 162 163 struct kvm_tdx_init_mem_region { 164 __u64 source_addr; 165 __u64 gpa; 166 __u64 nr_pages; 167 }; 168 169 170KVM_TDX_FINALIZE_VM 171------------------- 172:Type: vm ioctl 173:Returns: 0 on success, <0 on error 174 175Complete measurement of the initial TD contents and mark it ready to run. 176 177- id: KVM_TDX_FINALIZE_VM 178- flags: must be 0 179- data: must be 0 180- hw_error: must be 0 181 182 183KVM_TDX_GET_CPUID 184----------------- 185:Type: vcpu ioctl 186:Returns: 0 on success, <0 on error 187 188Get the CPUID values that the TDX module virtualizes for the TD guest. 189When it returns -E2BIG, the user space should allocate a larger buffer and 190retry. The minimum buffer size is updated in the nent field of the 191struct kvm_cpuid2. 192 193- id: KVM_TDX_GET_CPUID 194- flags: must be 0 195- data: pointer to struct kvm_cpuid2 (in/out) 196- hw_error: must be 0 (out) 197 198:: 199 200 struct kvm_cpuid2 { 201 __u32 nent; 202 __u32 padding; 203 struct kvm_cpuid_entry2 entries[0]; 204 }; 205 206 struct kvm_cpuid_entry2 { 207 __u32 function; 208 __u32 index; 209 __u32 flags; 210 __u32 eax; 211 __u32 ebx; 212 __u32 ecx; 213 __u32 edx; 214 __u32 padding[3]; 215 }; 216 217KVM TDX creation flow 218===================== 219In addition to the standard KVM flow, new TDX ioctls need to be called. The 220control flow is as follows: 221 222#. Check system wide capability 223 224 * KVM_CAP_VM_TYPES: Check if VM type is supported and if KVM_X86_TDX_VM 225 is supported. 226 227#. Create VM 228 229 * KVM_CREATE_VM 230 * KVM_TDX_CAPABILITIES: Query TDX capabilities for creating TDX guests. 231 * KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPUS): Query maximum VCPUs the TD can 232 support at VM level (TDX has its own limitation on this). 233 * KVM_SET_TSC_KHZ: Configure TD's TSC frequency if a different TSC frequency 234 than host is desired. This is Optional. 235 * KVM_TDX_INIT_VM: Pass TDX specific VM parameters. 236 237#. Create VCPU 238 239 * KVM_CREATE_VCPU 240 * KVM_TDX_INIT_VCPU: Pass TDX specific VCPU parameters. 241 * KVM_SET_CPUID2: Configure TD's CPUIDs. 242 * KVM_SET_MSRS: Configure TD's MSRs. 243 244#. Initialize initial guest memory 245 246 * Prepare content of initial guest memory. 247 * KVM_TDX_INIT_MEM_REGION: Add initial guest memory. 248 * KVM_TDX_FINALIZE_VM: Finalize the measurement of the TDX guest. 249 250#. Run VCPU 251 252References 253========== 254 255https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html 256