152f52ea7SIsaku Yamahata.. SPDX-License-Identifier: GPL-2.0 252f52ea7SIsaku Yamahata 352f52ea7SIsaku Yamahata=================================== 452f52ea7SIsaku YamahataIntel Trust Domain Extensions (TDX) 552f52ea7SIsaku Yamahata=================================== 652f52ea7SIsaku Yamahata 752f52ea7SIsaku YamahataOverview 852f52ea7SIsaku Yamahata======== 952f52ea7SIsaku YamahataIntel's Trust Domain Extensions (TDX) protect confidential guest VMs from the 1052f52ea7SIsaku Yamahatahost and physical attacks. A CPU-attested software module called 'the TDX 1152f52ea7SIsaku Yamahatamodule' runs inside a new CPU isolated range to provide the functionalities to 1252f52ea7SIsaku Yamahatamanage and run protected VMs, a.k.a, TDX guests or TDs. 1352f52ea7SIsaku Yamahata 1452f52ea7SIsaku YamahataPlease refer to [1] for the whitepaper, specifications and other resources. 1552f52ea7SIsaku Yamahata 1652f52ea7SIsaku YamahataThis documentation describes TDX-specific KVM ABIs. The TDX module needs to be 1752f52ea7SIsaku Yamahatainitialized before it can be used by KVM to run any TDX guests. The host 1852f52ea7SIsaku Yamahatacore-kernel provides the support of initializing the TDX module, which is 1952f52ea7SIsaku Yamahatadescribed in the Documentation/arch/x86/tdx.rst. 2052f52ea7SIsaku Yamahata 2152f52ea7SIsaku YamahataAPI description 2252f52ea7SIsaku Yamahata=============== 2352f52ea7SIsaku Yamahata 2452f52ea7SIsaku YamahataKVM_MEMORY_ENCRYPT_OP 2552f52ea7SIsaku Yamahata--------------------- 2652f52ea7SIsaku Yamahata:Type: vm ioctl, vcpu ioctl 2752f52ea7SIsaku Yamahata 2852f52ea7SIsaku YamahataFor TDX operations, KVM_MEMORY_ENCRYPT_OP is re-purposed to be generic 2952f52ea7SIsaku Yamahataioctl with TDX specific sub-ioctl() commands. 3052f52ea7SIsaku Yamahata 3152f52ea7SIsaku Yamahata:: 3252f52ea7SIsaku Yamahata 3352f52ea7SIsaku Yamahata /* Trust Domain Extensions sub-ioctl() commands. */ 3452f52ea7SIsaku Yamahata enum kvm_tdx_cmd_id { 3552f52ea7SIsaku Yamahata KVM_TDX_CAPABILITIES = 0, 3652f52ea7SIsaku Yamahata KVM_TDX_INIT_VM, 3752f52ea7SIsaku Yamahata KVM_TDX_INIT_VCPU, 3852f52ea7SIsaku Yamahata KVM_TDX_INIT_MEM_REGION, 3952f52ea7SIsaku Yamahata KVM_TDX_FINALIZE_VM, 4052f52ea7SIsaku Yamahata KVM_TDX_GET_CPUID, 4152f52ea7SIsaku Yamahata 4252f52ea7SIsaku Yamahata KVM_TDX_CMD_NR_MAX, 4352f52ea7SIsaku Yamahata }; 4452f52ea7SIsaku Yamahata 4552f52ea7SIsaku Yamahata struct kvm_tdx_cmd { 4652f52ea7SIsaku Yamahata /* enum kvm_tdx_cmd_id */ 4752f52ea7SIsaku Yamahata __u32 id; 4852f52ea7SIsaku Yamahata /* flags for sub-command. If sub-command doesn't use this, set zero. */ 4952f52ea7SIsaku Yamahata __u32 flags; 5052f52ea7SIsaku Yamahata /* 5152f52ea7SIsaku Yamahata * data for each sub-command. An immediate or a pointer to the actual 5252f52ea7SIsaku Yamahata * data in process virtual address. If sub-command doesn't use it, 5352f52ea7SIsaku Yamahata * set zero. 5452f52ea7SIsaku Yamahata */ 5552f52ea7SIsaku Yamahata __u64 data; 5652f52ea7SIsaku Yamahata /* 5752f52ea7SIsaku Yamahata * Auxiliary error code. The sub-command may return TDX SEAMCALL 5852f52ea7SIsaku Yamahata * status code in addition to -Exxx. 5952f52ea7SIsaku Yamahata */ 6052f52ea7SIsaku Yamahata __u64 hw_error; 6152f52ea7SIsaku Yamahata }; 6252f52ea7SIsaku Yamahata 6352f52ea7SIsaku YamahataKVM_TDX_CAPABILITIES 6452f52ea7SIsaku Yamahata-------------------- 6552f52ea7SIsaku Yamahata:Type: vm ioctl 6652f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 6752f52ea7SIsaku Yamahata 6852f52ea7SIsaku YamahataReturn the TDX capabilities that current KVM supports with the specific TDX 6952f52ea7SIsaku Yamahatamodule loaded in the system. It reports what features/capabilities are allowed 7052f52ea7SIsaku Yamahatato be configured to the TDX guest. 7152f52ea7SIsaku Yamahata 7252f52ea7SIsaku Yamahata- id: KVM_TDX_CAPABILITIES 7352f52ea7SIsaku Yamahata- flags: must be 0 7452f52ea7SIsaku Yamahata- data: pointer to struct kvm_tdx_capabilities 7552f52ea7SIsaku Yamahata- hw_error: must be 0 7652f52ea7SIsaku Yamahata 7752f52ea7SIsaku Yamahata:: 7852f52ea7SIsaku Yamahata 7952f52ea7SIsaku Yamahata struct kvm_tdx_capabilities { 8052f52ea7SIsaku Yamahata __u64 supported_attrs; 8152f52ea7SIsaku Yamahata __u64 supported_xfam; 8252f52ea7SIsaku Yamahata __u64 reserved[254]; 8352f52ea7SIsaku Yamahata 8452f52ea7SIsaku Yamahata /* Configurable CPUID bits for userspace */ 8552f52ea7SIsaku Yamahata struct kvm_cpuid2 cpuid; 8652f52ea7SIsaku Yamahata }; 8752f52ea7SIsaku Yamahata 8852f52ea7SIsaku Yamahata 8952f52ea7SIsaku YamahataKVM_TDX_INIT_VM 9052f52ea7SIsaku Yamahata--------------- 9152f52ea7SIsaku Yamahata:Type: vm ioctl 9252f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 9352f52ea7SIsaku Yamahata 9452f52ea7SIsaku YamahataPerform TDX specific VM initialization. This needs to be called after 9552f52ea7SIsaku YamahataKVM_CREATE_VM and before creating any VCPUs. 9652f52ea7SIsaku Yamahata 9752f52ea7SIsaku Yamahata- id: KVM_TDX_INIT_VM 9852f52ea7SIsaku Yamahata- flags: must be 0 9952f52ea7SIsaku Yamahata- data: pointer to struct kvm_tdx_init_vm 10052f52ea7SIsaku Yamahata- hw_error: must be 0 10152f52ea7SIsaku Yamahata 10252f52ea7SIsaku Yamahata:: 10352f52ea7SIsaku Yamahata 10452f52ea7SIsaku Yamahata struct kvm_tdx_init_vm { 10552f52ea7SIsaku Yamahata __u64 attributes; 10652f52ea7SIsaku Yamahata __u64 xfam; 10752f52ea7SIsaku Yamahata __u64 mrconfigid[6]; /* sha384 digest */ 10852f52ea7SIsaku Yamahata __u64 mrowner[6]; /* sha384 digest */ 10952f52ea7SIsaku Yamahata __u64 mrownerconfig[6]; /* sha384 digest */ 11052f52ea7SIsaku Yamahata 11152f52ea7SIsaku Yamahata /* The total space for TD_PARAMS before the CPUIDs is 256 bytes */ 11252f52ea7SIsaku Yamahata __u64 reserved[12]; 11352f52ea7SIsaku Yamahata 11452f52ea7SIsaku Yamahata /* 11552f52ea7SIsaku Yamahata * Call KVM_TDX_INIT_VM before vcpu creation, thus before 11652f52ea7SIsaku Yamahata * KVM_SET_CPUID2. 11752f52ea7SIsaku Yamahata * This configuration supersedes KVM_SET_CPUID2s for VCPUs because the 11852f52ea7SIsaku Yamahata * TDX module directly virtualizes those CPUIDs without VMM. The user 11952f52ea7SIsaku Yamahata * space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with 12052f52ea7SIsaku Yamahata * those values. If it doesn't, KVM may have wrong idea of vCPUIDs of 12152f52ea7SIsaku Yamahata * the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX 12252f52ea7SIsaku Yamahata * module doesn't virtualize. 12352f52ea7SIsaku Yamahata */ 12452f52ea7SIsaku Yamahata struct kvm_cpuid2 cpuid; 12552f52ea7SIsaku Yamahata }; 12652f52ea7SIsaku Yamahata 12752f52ea7SIsaku Yamahata 12852f52ea7SIsaku YamahataKVM_TDX_INIT_VCPU 12952f52ea7SIsaku Yamahata----------------- 13052f52ea7SIsaku Yamahata:Type: vcpu ioctl 13152f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 13252f52ea7SIsaku Yamahata 13352f52ea7SIsaku YamahataPerform TDX specific VCPU initialization. 13452f52ea7SIsaku Yamahata 13552f52ea7SIsaku Yamahata- id: KVM_TDX_INIT_VCPU 13652f52ea7SIsaku Yamahata- flags: must be 0 13752f52ea7SIsaku Yamahata- data: initial value of the guest TD VCPU RCX 13852f52ea7SIsaku Yamahata- hw_error: must be 0 13952f52ea7SIsaku Yamahata 14052f52ea7SIsaku YamahataKVM_TDX_INIT_MEM_REGION 14152f52ea7SIsaku Yamahata----------------------- 14252f52ea7SIsaku Yamahata:Type: vcpu ioctl 14352f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 14452f52ea7SIsaku Yamahata 14552f52ea7SIsaku YamahataInitialize @nr_pages TDX guest private memory starting from @gpa with userspace 14652f52ea7SIsaku Yamahataprovided data from @source_addr. 14752f52ea7SIsaku Yamahata 14852f52ea7SIsaku YamahataNote, before calling this sub command, memory attribute of the range 14952f52ea7SIsaku Yamahata[gpa, gpa + nr_pages] needs to be private. Userspace can use 15052f52ea7SIsaku YamahataKVM_SET_MEMORY_ATTRIBUTES to set the attribute. 15152f52ea7SIsaku Yamahata 15252f52ea7SIsaku YamahataIf KVM_TDX_MEASURE_MEMORY_REGION flag is specified, it also extends measurement. 15352f52ea7SIsaku Yamahata 15452f52ea7SIsaku Yamahata- id: KVM_TDX_INIT_MEM_REGION 15552f52ea7SIsaku Yamahata- flags: currently only KVM_TDX_MEASURE_MEMORY_REGION is defined 15652f52ea7SIsaku Yamahata- data: pointer to struct kvm_tdx_init_mem_region 15752f52ea7SIsaku Yamahata- hw_error: must be 0 15852f52ea7SIsaku Yamahata 15952f52ea7SIsaku Yamahata:: 16052f52ea7SIsaku Yamahata 16152f52ea7SIsaku Yamahata #define KVM_TDX_MEASURE_MEMORY_REGION (1UL << 0) 16252f52ea7SIsaku Yamahata 16352f52ea7SIsaku Yamahata struct kvm_tdx_init_mem_region { 16452f52ea7SIsaku Yamahata __u64 source_addr; 16552f52ea7SIsaku Yamahata __u64 gpa; 16652f52ea7SIsaku Yamahata __u64 nr_pages; 16752f52ea7SIsaku Yamahata }; 16852f52ea7SIsaku Yamahata 16952f52ea7SIsaku Yamahata 17052f52ea7SIsaku YamahataKVM_TDX_FINALIZE_VM 17152f52ea7SIsaku Yamahata------------------- 17252f52ea7SIsaku Yamahata:Type: vm ioctl 17352f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 17452f52ea7SIsaku Yamahata 17552f52ea7SIsaku YamahataComplete measurement of the initial TD contents and mark it ready to run. 17652f52ea7SIsaku Yamahata 17752f52ea7SIsaku Yamahata- id: KVM_TDX_FINALIZE_VM 17852f52ea7SIsaku Yamahata- flags: must be 0 17952f52ea7SIsaku Yamahata- data: must be 0 18052f52ea7SIsaku Yamahata- hw_error: must be 0 18152f52ea7SIsaku Yamahata 18252f52ea7SIsaku Yamahata 18352f52ea7SIsaku YamahataKVM_TDX_GET_CPUID 18452f52ea7SIsaku Yamahata----------------- 18552f52ea7SIsaku Yamahata:Type: vcpu ioctl 18652f52ea7SIsaku Yamahata:Returns: 0 on success, <0 on error 18752f52ea7SIsaku Yamahata 18852f52ea7SIsaku YamahataGet the CPUID values that the TDX module virtualizes for the TD guest. 18952f52ea7SIsaku YamahataWhen it returns -E2BIG, the user space should allocate a larger buffer and 19052f52ea7SIsaku Yamahataretry. The minimum buffer size is updated in the nent field of the 19152f52ea7SIsaku Yamahatastruct kvm_cpuid2. 19252f52ea7SIsaku Yamahata 19352f52ea7SIsaku Yamahata- id: KVM_TDX_GET_CPUID 19452f52ea7SIsaku Yamahata- flags: must be 0 19552f52ea7SIsaku Yamahata- data: pointer to struct kvm_cpuid2 (in/out) 19652f52ea7SIsaku Yamahata- hw_error: must be 0 (out) 19752f52ea7SIsaku Yamahata 19852f52ea7SIsaku Yamahata:: 19952f52ea7SIsaku Yamahata 20052f52ea7SIsaku Yamahata struct kvm_cpuid2 { 20152f52ea7SIsaku Yamahata __u32 nent; 20252f52ea7SIsaku Yamahata __u32 padding; 20352f52ea7SIsaku Yamahata struct kvm_cpuid_entry2 entries[0]; 20452f52ea7SIsaku Yamahata }; 20552f52ea7SIsaku Yamahata 20652f52ea7SIsaku Yamahata struct kvm_cpuid_entry2 { 20752f52ea7SIsaku Yamahata __u32 function; 20852f52ea7SIsaku Yamahata __u32 index; 20952f52ea7SIsaku Yamahata __u32 flags; 21052f52ea7SIsaku Yamahata __u32 eax; 21152f52ea7SIsaku Yamahata __u32 ebx; 21252f52ea7SIsaku Yamahata __u32 ecx; 21352f52ea7SIsaku Yamahata __u32 edx; 21452f52ea7SIsaku Yamahata __u32 padding[3]; 21552f52ea7SIsaku Yamahata }; 21652f52ea7SIsaku Yamahata 21752f52ea7SIsaku YamahataKVM TDX creation flow 21852f52ea7SIsaku Yamahata===================== 21952f52ea7SIsaku YamahataIn addition to the standard KVM flow, new TDX ioctls need to be called. The 22052f52ea7SIsaku Yamahatacontrol flow is as follows: 22152f52ea7SIsaku Yamahata 22252f52ea7SIsaku Yamahata#. Check system wide capability 22352f52ea7SIsaku Yamahata 22452f52ea7SIsaku Yamahata * KVM_CAP_VM_TYPES: Check if VM type is supported and if KVM_X86_TDX_VM 22552f52ea7SIsaku Yamahata is supported. 22652f52ea7SIsaku Yamahata 22752f52ea7SIsaku Yamahata#. Create VM 22852f52ea7SIsaku Yamahata 22952f52ea7SIsaku Yamahata * KVM_CREATE_VM 23052f52ea7SIsaku Yamahata * KVM_TDX_CAPABILITIES: Query TDX capabilities for creating TDX guests. 23152f52ea7SIsaku Yamahata * KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPUS): Query maximum VCPUs the TD can 23252f52ea7SIsaku Yamahata support at VM level (TDX has its own limitation on this). 23352f52ea7SIsaku Yamahata * KVM_SET_TSC_KHZ: Configure TD's TSC frequency if a different TSC frequency 23452f52ea7SIsaku Yamahata than host is desired. This is Optional. 23552f52ea7SIsaku Yamahata * KVM_TDX_INIT_VM: Pass TDX specific VM parameters. 23652f52ea7SIsaku Yamahata 23752f52ea7SIsaku Yamahata#. Create VCPU 23852f52ea7SIsaku Yamahata 23952f52ea7SIsaku Yamahata * KVM_CREATE_VCPU 24052f52ea7SIsaku Yamahata * KVM_TDX_INIT_VCPU: Pass TDX specific VCPU parameters. 24152f52ea7SIsaku Yamahata * KVM_SET_CPUID2: Configure TD's CPUIDs. 24252f52ea7SIsaku Yamahata * KVM_SET_MSRS: Configure TD's MSRs. 24352f52ea7SIsaku Yamahata 24452f52ea7SIsaku Yamahata#. Initialize initial guest memory 24552f52ea7SIsaku Yamahata 24652f52ea7SIsaku Yamahata * Prepare content of initial guest memory. 24752f52ea7SIsaku Yamahata * KVM_TDX_INIT_MEM_REGION: Add initial guest memory. 24852f52ea7SIsaku Yamahata * KVM_TDX_FINALIZE_VM: Finalize the measurement of the TDX guest. 24952f52ea7SIsaku Yamahata 25052f52ea7SIsaku Yamahata#. Run VCPU 25152f52ea7SIsaku Yamahata 25252f52ea7SIsaku YamahataReferences 25352f52ea7SIsaku Yamahata========== 25452f52ea7SIsaku Yamahata 255*2bb0e398SPaolo Bonzinihttps://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html 256