xref: /linux/Documentation/virt/kvm/x86/intel-tdx.rst (revision 43db1111073049220381944af4a3b8a5400eda71)
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