Skip to content

Commit c33621b

Browse files
kaihuanghansendc
authored andcommitted
x86/virt/tdx: Wire up basic SEAMCALL functions
Intel Trust Domain Extensions (TDX) protects guest VMs from malicious host and certain physical attacks. A CPU-attested software module called 'the TDX module' runs inside a new isolated memory range as a trusted hypervisor to manage and run protected VMs. TDX introduces a new CPU mode: Secure Arbitration Mode (SEAM). This mode runs only the TDX module itself or other code to load the TDX module. The host kernel communicates with SEAM software via a new SEAMCALL instruction. This is conceptually similar to a guest->host hypercall, except it is made from the host to SEAM software instead. The TDX module establishes a new SEAMCALL ABI which allows the host to initialize the module and to manage VMs. The SEAMCALL ABI is very similar to the TDCALL ABI and leverages much TDCALL infrastructure. Wire up basic functions to make SEAMCALLs for the basic support of running TDX guests: __seamcall(), __seamcall_ret(), and __seamcall_saved_ret() for TDH.VP.ENTER. All SEAMCALLs involved in the basic TDX support don't use "callee-saved" registers as input and output, except the TDH.VP.ENTER. To start to support TDX, create a new arch/x86/virt/vmx/tdx/tdx.c for TDX host kernel support. Add a new Kconfig option CONFIG_INTEL_TDX_HOST to opt-in TDX host kernel support (to distinguish with TDX guest kernel support). So far only KVM uses TDX. Make the new config option depend on KVM_INTEL. Signed-off-by: Kai Huang <kai.huang@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Isaku Yamahata <isaku.yamahata@intel.com> Link: https://lore.kernel.org/all/4db7c3fc085e6af12acc2932294254ddb3d320b3.1692096753.git.kai.huang%40intel.com
1 parent 8a8544b commit c33621b

File tree

7 files changed

+88
-0
lines changed

7 files changed

+88
-0
lines changed

arch/x86/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,18 @@ config X86_USER_SHADOW_STACK
19391939

19401940
If unsure, say N.
19411941

1942+
config INTEL_TDX_HOST
1943+
bool "Intel Trust Domain Extensions (TDX) host support"
1944+
depends on CPU_SUP_INTEL
1945+
depends on X86_64
1946+
depends on KVM_INTEL
1947+
help
1948+
Intel Trust Domain Extensions (TDX) protects guest VMs from malicious
1949+
host and certain physical attacks. This option enables necessary TDX
1950+
support in the host kernel to run confidential VMs.
1951+
1952+
If unsure, say N.
1953+
19421954
config EFI
19431955
bool "EFI runtime service support"
19441956
depends on ACPI

arch/x86/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ archheaders:
252252

253253
libs-y += arch/x86/lib/
254254

255+
core-y += arch/x86/virt/
256+
255257
# drivers-y are linked after core-y
256258
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
257259
drivers-$(CONFIG_PCI) += arch/x86/pci/

arch/x86/include/asm/tdx.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,12 @@ static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1,
7272
return -ENODEV;
7373
}
7474
#endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */
75+
76+
#ifdef CONFIG_INTEL_TDX_HOST
77+
u64 __seamcall(u64 fn, struct tdx_module_args *args);
78+
u64 __seamcall_ret(u64 fn, struct tdx_module_args *args);
79+
u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args);
80+
#endif /* CONFIG_INTEL_TDX_HOST */
81+
7582
#endif /* !__ASSEMBLY__ */
7683
#endif /* _ASM_X86_TDX_H */

arch/x86/virt/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-y += vmx/

arch/x86/virt/vmx/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-$(CONFIG_INTEL_TDX_HOST) += tdx/

arch/x86/virt/vmx/tdx/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-y += seamcall.o

arch/x86/virt/vmx/tdx/seamcall.S

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#include <linux/linkage.h>
3+
#include <asm/frame.h>
4+
5+
#include "tdxcall.S"
6+
7+
/*
8+
* __seamcall() - Host-side interface functions to SEAM software
9+
* (the P-SEAMLDR or the TDX module).
10+
*
11+
* __seamcall() function ABI:
12+
*
13+
* @fn (RDI) - SEAMCALL Leaf number, moved to RAX
14+
* @args (RSI) - struct tdx_module_args for input
15+
*
16+
* Only RCX/RDX/R8-R11 are used as input registers.
17+
*
18+
* Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
19+
* fails, or the completion status of the SEAMCALL leaf function.
20+
*/
21+
SYM_FUNC_START(__seamcall)
22+
TDX_MODULE_CALL host=1
23+
SYM_FUNC_END(__seamcall)
24+
25+
/*
26+
* __seamcall_ret() - Host-side interface functions to SEAM software
27+
* (the P-SEAMLDR or the TDX module), with saving output registers to
28+
* the 'struct tdx_module_args' used as input.
29+
*
30+
* __seamcall_ret() function ABI:
31+
*
32+
* @fn (RDI) - SEAMCALL Leaf number, moved to RAX
33+
* @args (RSI) - struct tdx_module_args for input and output
34+
*
35+
* Only RCX/RDX/R8-R11 are used as input/output registers.
36+
*
37+
* Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
38+
* fails, or the completion status of the SEAMCALL leaf function.
39+
*/
40+
SYM_FUNC_START(__seamcall_ret)
41+
TDX_MODULE_CALL host=1 ret=1
42+
SYM_FUNC_END(__seamcall_ret)
43+
44+
/*
45+
* __seamcall_saved_ret() - Host-side interface functions to SEAM software
46+
* (the P-SEAMLDR or the TDX module), with saving output registers to the
47+
* 'struct tdx_module_args' used as input.
48+
*
49+
* __seamcall_saved_ret() function ABI:
50+
*
51+
* @fn (RDI) - SEAMCALL Leaf number, moved to RAX
52+
* @args (RSI) - struct tdx_module_args for input and output
53+
*
54+
* All registers in @args are used as input/output registers.
55+
*
56+
* Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
57+
* fails, or the completion status of the SEAMCALL leaf function.
58+
*/
59+
SYM_FUNC_START(__seamcall_saved_ret)
60+
TDX_MODULE_CALL host=1 ret=1 saved=1
61+
SYM_FUNC_END(__seamcall_saved_ret)

0 commit comments

Comments
 (0)