Skip to content

Commit 1187c0b

Browse files
committed
Merge branch into tip/master: 'x86/tdx'
# New commits in x86/tdx: 9ee4318 ("x86/tdx: Mark TSC reliable") 518755a ("x86/tdx: Fix __noreturn build warning around __tdx_hypercall_failed()") 7b80413 ("x86/virt/tdx: Make TDX_MODULE_CALL handle SEAMCALL #UD and #GP") c33621b ("x86/virt/tdx: Wire up basic SEAMCALL functions") 8a8544b ("x86/tdx: Remove 'struct tdx_hypercall_args'") 90f5ecd ("x86/tdx: Reimplement __tdx_hypercall() using TDX_MODULE_CALL asm") c641cfb ("x86/tdx: Make TDX_HYPERCALL asm similar to TDX_MODULE_CALL") 12f34ed ("x86/tdx: Extend TDX_MODULE_CALL to support more TDCALL/SEAMCALL leafs") 57a420b ("x86/tdx: Pass TDCALL/SEAMCALL input/output registers via a structure") 5efb962 ("x86/tdx: Rename __tdx_module_call() to __tdcall()") f0024db ("x86/tdx: Make macros of TDCALLs consistent with the spec") 03a423d ("x86/tdx: Skip saving output regs when SEAMCALL fails with VMFailInvalid") 5d092b6 ("x86/tdx: Zero out the missing RSI in TDX_HYPERCALL macro") 019b383 ("x86/tdx: Retry partially-completed page conversion hypercalls") Signed-off-by: Ingo Molnar <mingo@kernel.org>
2 parents ec3e2ac + 9ee4318 commit 1187c0b

16 files changed

Lines changed: 491 additions & 366 deletions

File tree

arch/x86/Kconfig

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

19661966
If unsure, say N.
19671967

1968+
config INTEL_TDX_HOST
1969+
bool "Intel Trust Domain Extensions (TDX) host support"
1970+
depends on CPU_SUP_INTEL
1971+
depends on X86_64
1972+
depends on KVM_INTEL
1973+
help
1974+
Intel Trust Domain Extensions (TDX) protects guest VMs from malicious
1975+
host and certain physical attacks. This option enables necessary TDX
1976+
support in the host kernel to run confidential VMs.
1977+
1978+
If unsure, say N.
1979+
19681980
config EFI
19691981
bool "EFI runtime service support"
19701982
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/boot/compressed/tdx.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@ void __tdx_hypercall_failed(void)
1818

1919
static inline unsigned int tdx_io_in(int size, u16 port)
2020
{
21-
struct tdx_hypercall_args args = {
21+
struct tdx_module_args args = {
2222
.r10 = TDX_HYPERCALL_STANDARD,
2323
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
2424
.r12 = size,
2525
.r13 = 0,
2626
.r14 = port,
2727
};
2828

29-
if (__tdx_hypercall_ret(&args))
29+
if (__tdx_hypercall(&args))
3030
return UINT_MAX;
3131

3232
return args.r11;
3333
}
3434

3535
static inline void tdx_io_out(int size, u16 port, u32 value)
3636
{
37-
struct tdx_hypercall_args args = {
37+
struct tdx_module_args args = {
3838
.r10 = TDX_HYPERCALL_STANDARD,
3939
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
4040
.r12 = size,

arch/x86/coco/tdx/tdcall.S

Lines changed: 29 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -1,239 +1,63 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
#include <asm/asm-offsets.h>
33
#include <asm/asm.h>
4-
#include <asm/frame.h>
5-
#include <asm/unwind_hints.h>
64

75
#include <linux/linkage.h>
8-
#include <linux/bits.h>
96
#include <linux/errno.h>
107

118
#include "../../virt/vmx/tdx/tdxcall.S"
129

13-
/*
14-
* Bitmasks of exposed registers (with VMM).
15-
*/
16-
#define TDX_RDX BIT(2)
17-
#define TDX_RBX BIT(3)
18-
#define TDX_RSI BIT(6)
19-
#define TDX_RDI BIT(7)
20-
#define TDX_R8 BIT(8)
21-
#define TDX_R9 BIT(9)
22-
#define TDX_R10 BIT(10)
23-
#define TDX_R11 BIT(11)
24-
#define TDX_R12 BIT(12)
25-
#define TDX_R13 BIT(13)
26-
#define TDX_R14 BIT(14)
27-
#define TDX_R15 BIT(15)
28-
29-
/*
30-
* These registers are clobbered to hold arguments for each
31-
* TDVMCALL. They are safe to expose to the VMM.
32-
* Each bit in this mask represents a register ID. Bit field
33-
* details can be found in TDX GHCI specification, section
34-
* titled "TDCALL [TDG.VP.VMCALL] leaf".
35-
*/
36-
#define TDVMCALL_EXPOSE_REGS_MASK \
37-
( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \
38-
TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 )
39-
4010
.section .noinstr.text, "ax"
4111

4212
/*
43-
* __tdx_module_call() - Used by TDX guests to request services from
44-
* the TDX module (does not include VMM services) using TDCALL instruction.
45-
*
46-
* Transforms function call register arguments into the TDCALL register ABI.
47-
* After TDCALL operation, TDX module output is saved in @out (if it is
48-
* provided by the user).
49-
*
50-
*-------------------------------------------------------------------------
51-
* TDCALL ABI:
52-
*-------------------------------------------------------------------------
53-
* Input Registers:
54-
*
55-
* RAX - TDCALL Leaf number.
56-
* RCX,RDX,R8-R9 - TDCALL Leaf specific input registers.
57-
*
58-
* Output Registers:
13+
* __tdcall() - Used by TDX guests to request services from the TDX
14+
* module (does not include VMM services) using TDCALL instruction.
5915
*
60-
* RAX - TDCALL instruction error code.
61-
* RCX,RDX,R8-R11 - TDCALL Leaf specific output registers.
16+
* __tdcall() function ABI:
6217
*
63-
*-------------------------------------------------------------------------
18+
* @fn (RDI) - TDCALL Leaf ID, moved to RAX
19+
* @args (RSI) - struct tdx_module_args for input
6420
*
65-
* __tdx_module_call() function ABI:
66-
*
67-
* @fn (RDI) - TDCALL Leaf ID, moved to RAX
68-
* @rcx (RSI) - Input parameter 1, moved to RCX
69-
* @rdx (RDX) - Input parameter 2, moved to RDX
70-
* @r8 (RCX) - Input parameter 3, moved to R8
71-
* @r9 (R8) - Input parameter 4, moved to R9
72-
*
73-
* @out (R9) - struct tdx_module_output pointer
74-
* stored temporarily in R12 (not
75-
* shared with the TDX module). It
76-
* can be NULL.
21+
* Only RCX/RDX/R8-R11 are used as input registers.
7722
*
7823
* Return status of TDCALL via RAX.
7924
*/
80-
SYM_FUNC_START(__tdx_module_call)
81-
FRAME_BEGIN
25+
SYM_FUNC_START(__tdcall)
8226
TDX_MODULE_CALL host=0
83-
FRAME_END
84-
RET
85-
SYM_FUNC_END(__tdx_module_call)
27+
SYM_FUNC_END(__tdcall)
8628

8729
/*
88-
* TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
89-
* instruction
90-
*
91-
* Transforms values in function call argument struct tdx_hypercall_args @args
92-
* into the TDCALL register ABI. After TDCALL operation, VMM output is saved
93-
* back in @args, if \ret is 1.
94-
*
95-
*-------------------------------------------------------------------------
96-
* TD VMCALL ABI:
97-
*-------------------------------------------------------------------------
98-
*
99-
* Input Registers:
30+
* __tdcall_ret() - Used by TDX guests to request services from the TDX
31+
* module (does not include VMM services) using TDCALL instruction, with
32+
* saving output registers to the 'struct tdx_module_args' used as input.
10033
*
101-
* RAX - TDCALL instruction leaf number (0 - TDG.VP.VMCALL)
102-
* RCX - BITMAP which controls which part of TD Guest GPR
103-
* is passed as-is to the VMM and back.
104-
* R10 - Set 0 to indicate TDCALL follows standard TDX ABI
105-
* specification. Non zero value indicates vendor
106-
* specific ABI.
107-
* R11 - VMCALL sub function number
108-
* RBX, RDX, RDI, RSI - Used to pass VMCALL sub function specific arguments.
109-
* R8-R9, R12-R15 - Same as above.
34+
* __tdcall_ret() function ABI:
11035
*
111-
* Output Registers:
36+
* @fn (RDI) - TDCALL Leaf ID, moved to RAX
37+
* @args (RSI) - struct tdx_module_args for input and output
11238
*
113-
* RAX - TDCALL instruction status (Not related to hypercall
114-
* output).
115-
* RBX, RDX, RDI, RSI - Hypercall sub function specific output values.
116-
* R8-R15 - Same as above.
39+
* Only RCX/RDX/R8-R11 are used as input/output registers.
11740
*
41+
* Return status of TDCALL via RAX.
11842
*/
119-
.macro TDX_HYPERCALL ret:req
120-
FRAME_BEGIN
121-
122-
/* Save callee-saved GPRs as mandated by the x86_64 ABI */
123-
push %r15
124-
push %r14
125-
push %r13
126-
push %r12
127-
push %rbx
128-
129-
/* Free RDI to be used as TDVMCALL arguments */
130-
movq %rdi, %rax
131-
132-
/* Copy hypercall registers from arg struct: */
133-
movq TDX_HYPERCALL_r8(%rax), %r8
134-
movq TDX_HYPERCALL_r9(%rax), %r9
135-
movq TDX_HYPERCALL_r10(%rax), %r10
136-
movq TDX_HYPERCALL_r11(%rax), %r11
137-
movq TDX_HYPERCALL_r12(%rax), %r12
138-
movq TDX_HYPERCALL_r13(%rax), %r13
139-
movq TDX_HYPERCALL_r14(%rax), %r14
140-
movq TDX_HYPERCALL_r15(%rax), %r15
141-
movq TDX_HYPERCALL_rdi(%rax), %rdi
142-
movq TDX_HYPERCALL_rsi(%rax), %rsi
143-
movq TDX_HYPERCALL_rbx(%rax), %rbx
144-
movq TDX_HYPERCALL_rdx(%rax), %rdx
145-
146-
push %rax
147-
148-
/* Mangle function call ABI into TDCALL ABI: */
149-
/* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */
150-
xor %eax, %eax
151-
152-
movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx
153-
154-
tdcall
155-
156-
/*
157-
* RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that
158-
* something has gone horribly wrong with the TDX module.
159-
*
160-
* The return status of the hypercall operation is in a separate
161-
* register (in R10). Hypercall errors are a part of normal operation
162-
* and are handled by callers.
163-
*/
164-
testq %rax, %rax
165-
jne .Lpanic\@
166-
167-
pop %rax
168-
169-
.if \ret
170-
movq %r8, TDX_HYPERCALL_r8(%rax)
171-
movq %r9, TDX_HYPERCALL_r9(%rax)
172-
movq %r10, TDX_HYPERCALL_r10(%rax)
173-
movq %r11, TDX_HYPERCALL_r11(%rax)
174-
movq %r12, TDX_HYPERCALL_r12(%rax)
175-
movq %r13, TDX_HYPERCALL_r13(%rax)
176-
movq %r14, TDX_HYPERCALL_r14(%rax)
177-
movq %r15, TDX_HYPERCALL_r15(%rax)
178-
movq %rdi, TDX_HYPERCALL_rdi(%rax)
179-
movq %rsi, TDX_HYPERCALL_rsi(%rax)
180-
movq %rbx, TDX_HYPERCALL_rbx(%rax)
181-
movq %rdx, TDX_HYPERCALL_rdx(%rax)
182-
.endif
183-
184-
/* TDVMCALL leaf return code is in R10 */
185-
movq %r10, %rax
186-
187-
/*
188-
* Zero out registers exposed to the VMM to avoid speculative execution
189-
* with VMM-controlled values. This needs to include all registers
190-
* present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which
191-
* will be restored.
192-
*/
193-
xor %r8d, %r8d
194-
xor %r9d, %r9d
195-
xor %r10d, %r10d
196-
xor %r11d, %r11d
197-
xor %rdi, %rdi
198-
xor %rdx, %rdx
199-
200-
/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
201-
pop %rbx
202-
pop %r12
203-
pop %r13
204-
pop %r14
205-
pop %r15
206-
207-
FRAME_END
208-
209-
RET
210-
.Lpanic\@:
211-
call __tdx_hypercall_failed
212-
/* __tdx_hypercall_failed never returns */
213-
REACHABLE
214-
jmp .Lpanic\@
215-
.endm
43+
SYM_FUNC_START(__tdcall_ret)
44+
TDX_MODULE_CALL host=0 ret=1
45+
SYM_FUNC_END(__tdcall_ret)
21646

21747
/*
48+
* __tdcall_saved_ret() - Used by TDX guests to request services from the
49+
* TDX module (including VMM services) using TDCALL instruction, with
50+
* saving output registers to the 'struct tdx_module_args' used as input.
21851
*
219-
* __tdx_hypercall() function ABI:
220-
*
221-
* @args (RDI) - struct tdx_hypercall_args for input
222-
*
223-
* On successful completion, return the hypercall error code.
224-
*/
225-
SYM_FUNC_START(__tdx_hypercall)
226-
TDX_HYPERCALL ret=0
227-
SYM_FUNC_END(__tdx_hypercall)
228-
229-
/*
52+
* __tdcall_saved_ret() function ABI:
23053
*
231-
* __tdx_hypercall_ret() function ABI:
54+
* @fn (RDI) - TDCALL leaf ID, moved to RAX
55+
* @args (RSI) - struct tdx_module_args for input/output
23256
*
233-
* @args (RDI) - struct tdx_hypercall_args for input and output
57+
* All registers in @args are used as input/output registers.
23458
*
23559
* On successful completion, return the hypercall error code.
23660
*/
237-
SYM_FUNC_START(__tdx_hypercall_ret)
238-
TDX_HYPERCALL ret=1
239-
SYM_FUNC_END(__tdx_hypercall_ret)
61+
SYM_FUNC_START(__tdcall_saved_ret)
62+
TDX_MODULE_CALL host=0 ret=1 saved=1
63+
SYM_FUNC_END(__tdcall_saved_ret)

arch/x86/coco/tdx/tdx-shared.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
55
enum pg_level pg_level)
66
{
77
unsigned long accept_size = page_level_size(pg_level);
8-
u64 tdcall_rcx;
8+
struct tdx_module_args args = {};
99
u8 page_size;
1010

1111
if (!IS_ALIGNED(start, accept_size))
@@ -34,8 +34,8 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
3434
return 0;
3535
}
3636

37-
tdcall_rcx = start | page_size;
38-
if (__tdx_module_call(TDX_ACCEPT_PAGE, tdcall_rcx, 0, 0, 0, NULL))
37+
args.rcx = start | page_size;
38+
if (__tdcall(TDG_MEM_PAGE_ACCEPT, &args))
3939
return 0;
4040

4141
return accept_size;
@@ -45,7 +45,7 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
4545
{
4646
/*
4747
* For shared->private conversion, accept the page using
48-
* TDX_ACCEPT_PAGE TDX module call.
48+
* TDG_MEM_PAGE_ACCEPT TDX module call.
4949
*/
5050
while (start < end) {
5151
unsigned long len = end - start;
@@ -69,3 +69,23 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
6969

7070
return true;
7171
}
72+
73+
noinstr u64 __tdx_hypercall(struct tdx_module_args *args)
74+
{
75+
/*
76+
* For TDVMCALL explicitly set RCX to the bitmap of shared registers.
77+
* The caller isn't expected to set @args->rcx anyway.
78+
*/
79+
args->rcx = TDVMCALL_EXPOSE_REGS_MASK;
80+
81+
/*
82+
* Failure of __tdcall_saved_ret() indicates a failure of the TDVMCALL
83+
* mechanism itself and that something has gone horribly wrong with
84+
* the TDX module. __tdx_hypercall_failed() never returns.
85+
*/
86+
if (__tdcall_saved_ret(TDG_VP_VMCALL, args))
87+
__tdx_hypercall_failed();
88+
89+
/* TDVMCALL leaf return code is in R10 */
90+
return args->r10;
91+
}

0 commit comments

Comments
 (0)