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 83 /* TDG.VP.VMCALL hypercalls executed in kernel and forwarded to 84 * userspace, respectively 85 */ 86 __u64 kernel_tdvmcallinfo_1_r11; 87 __u64 user_tdvmcallinfo_1_r11; 88 89 /* TDG.VP.VMCALL instruction executions subfunctions executed in kernel 90 * and forwarded to userspace, respectively 91 */ 92 __u64 kernel_tdvmcallinfo_1_r12; 93 __u64 user_tdvmcallinfo_1_r12; 94 95 __u64 reserved[250]; 96 97 /* Configurable CPUID bits for userspace */ 98 struct kvm_cpuid2 cpuid; 99 }; 100 101 102KVM_TDX_INIT_VM 103--------------- 104:Type: vm ioctl 105:Returns: 0 on success, <0 on error 106 107Perform TDX specific VM initialization. This needs to be called after 108KVM_CREATE_VM and before creating any VCPUs. 109 110- id: KVM_TDX_INIT_VM 111- flags: must be 0 112- data: pointer to struct kvm_tdx_init_vm 113- hw_error: must be 0 114 115:: 116 117 struct kvm_tdx_init_vm { 118 __u64 attributes; 119 __u64 xfam; 120 __u64 mrconfigid[6]; /* sha384 digest */ 121 __u64 mrowner[6]; /* sha384 digest */ 122 __u64 mrownerconfig[6]; /* sha384 digest */ 123 124 /* The total space for TD_PARAMS before the CPUIDs is 256 bytes */ 125 __u64 reserved[12]; 126 127 /* 128 * Call KVM_TDX_INIT_VM before vcpu creation, thus before 129 * KVM_SET_CPUID2. 130 * This configuration supersedes KVM_SET_CPUID2s for VCPUs because the 131 * TDX module directly virtualizes those CPUIDs without VMM. The user 132 * space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with 133 * those values. If it doesn't, KVM may have wrong idea of vCPUIDs of 134 * the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX 135 * module doesn't virtualize. 136 */ 137 struct kvm_cpuid2 cpuid; 138 }; 139 140 141KVM_TDX_INIT_VCPU 142----------------- 143:Type: vcpu ioctl 144:Returns: 0 on success, <0 on error 145 146Perform TDX specific VCPU initialization. 147 148- id: KVM_TDX_INIT_VCPU 149- flags: must be 0 150- data: initial value of the guest TD VCPU RCX 151- hw_error: must be 0 152 153KVM_TDX_INIT_MEM_REGION 154----------------------- 155:Type: vcpu ioctl 156:Returns: 0 on success, <0 on error 157 158Initialize @nr_pages TDX guest private memory starting from @gpa with userspace 159provided data from @source_addr. 160 161Note, before calling this sub command, memory attribute of the range 162[gpa, gpa + nr_pages] needs to be private. Userspace can use 163KVM_SET_MEMORY_ATTRIBUTES to set the attribute. 164 165If KVM_TDX_MEASURE_MEMORY_REGION flag is specified, it also extends measurement. 166 167- id: KVM_TDX_INIT_MEM_REGION 168- flags: currently only KVM_TDX_MEASURE_MEMORY_REGION is defined 169- data: pointer to struct kvm_tdx_init_mem_region 170- hw_error: must be 0 171 172:: 173 174 #define KVM_TDX_MEASURE_MEMORY_REGION (1UL << 0) 175 176 struct kvm_tdx_init_mem_region { 177 __u64 source_addr; 178 __u64 gpa; 179 __u64 nr_pages; 180 }; 181 182 183KVM_TDX_FINALIZE_VM 184------------------- 185:Type: vm ioctl 186:Returns: 0 on success, <0 on error 187 188Complete measurement of the initial TD contents and mark it ready to run. 189 190- id: KVM_TDX_FINALIZE_VM 191- flags: must be 0 192- data: must be 0 193- hw_error: must be 0 194 195 196KVM_TDX_GET_CPUID 197----------------- 198:Type: vcpu ioctl 199:Returns: 0 on success, <0 on error 200 201Get the CPUID values that the TDX module virtualizes for the TD guest. 202When it returns -E2BIG, the user space should allocate a larger buffer and 203retry. The minimum buffer size is updated in the nent field of the 204struct kvm_cpuid2. 205 206- id: KVM_TDX_GET_CPUID 207- flags: must be 0 208- data: pointer to struct kvm_cpuid2 (in/out) 209- hw_error: must be 0 (out) 210 211:: 212 213 struct kvm_cpuid2 { 214 __u32 nent; 215 __u32 padding; 216 struct kvm_cpuid_entry2 entries[0]; 217 }; 218 219 struct kvm_cpuid_entry2 { 220 __u32 function; 221 __u32 index; 222 __u32 flags; 223 __u32 eax; 224 __u32 ebx; 225 __u32 ecx; 226 __u32 edx; 227 __u32 padding[3]; 228 }; 229 230KVM TDX creation flow 231===================== 232In addition to the standard KVM flow, new TDX ioctls need to be called. The 233control flow is as follows: 234 235#. Check system wide capability 236 237 * KVM_CAP_VM_TYPES: Check if VM type is supported and if KVM_X86_TDX_VM 238 is supported. 239 240#. Create VM 241 242 * KVM_CREATE_VM 243 * KVM_TDX_CAPABILITIES: Query TDX capabilities for creating TDX guests. 244 * KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPUS): Query maximum VCPUs the TD can 245 support at VM level (TDX has its own limitation on this). 246 * KVM_SET_TSC_KHZ: Configure TD's TSC frequency if a different TSC frequency 247 than host is desired. This is Optional. 248 * KVM_TDX_INIT_VM: Pass TDX specific VM parameters. 249 250#. Create VCPU 251 252 * KVM_CREATE_VCPU 253 * KVM_TDX_INIT_VCPU: Pass TDX specific VCPU parameters. 254 * KVM_SET_CPUID2: Configure TD's CPUIDs. 255 * KVM_SET_MSRS: Configure TD's MSRs. 256 257#. Initialize initial guest memory 258 259 * Prepare content of initial guest memory. 260 * KVM_TDX_INIT_MEM_REGION: Add initial guest memory. 261 * KVM_TDX_FINALIZE_VM: Finalize the measurement of the TDX guest. 262 263#. Run VCPU 264 265References 266========== 267 268https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html 269