Skip to content

Commit 7b664cc

Browse files
committed
Merge tag 'x86_tdx_for_6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 tdx update from Dave Hansen: "The original tdx hypercall assembly code took two flags in %RSI to tweak its behavior at runtime. PeterZ recently axed one flag in commit e80a48b ("x86/tdx: Remove TDX_HCALL_ISSUE_STI"). Kill the other flag too and tweak the 'output' mode with an assembly macro instead. This results in elimination of one push/pop pair and overall easier to read assembly. - Do conditional __tdx_hypercall() 'output' processing via an assembly macro argument rather than a runtime register" * tag 'x86_tdx_for_6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/tdx: Drop flags from __tdx_hypercall()
2 parents e54debe + 7a3a401 commit 7b664cc

4 files changed

Lines changed: 51 additions & 42 deletions

File tree

arch/x86/boot/compressed/tdx.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
2626
.r14 = port,
2727
};
2828

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

3232
return args.r11;
@@ -43,7 +43,7 @@ static inline void tdx_io_out(int size, u16 port, u32 value)
4343
.r15 = value,
4444
};
4545

46-
__tdx_hypercall(&args, 0);
46+
__tdx_hypercall(&args);
4747
}
4848

4949
static inline u8 tdx_inb(u16 port)

arch/x86/coco/tdx/tdcall.S

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ SYM_FUNC_START(__tdx_module_call)
8585
SYM_FUNC_END(__tdx_module_call)
8686

8787
/*
88-
* __tdx_hypercall() - Make hypercalls to a TDX VMM using TDVMCALL leaf
89-
* of TDCALL instruction
88+
* TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
89+
* instruction
9090
*
9191
* Transforms values in function call argument struct tdx_hypercall_args @args
9292
* into the TDCALL register ABI. After TDCALL operation, VMM output is saved
93-
* back in @args.
93+
* back in @args, if \ret is 1.
9494
*
9595
*-------------------------------------------------------------------------
9696
* TD VMCALL ABI:
@@ -105,26 +105,18 @@ SYM_FUNC_END(__tdx_module_call)
105105
* specification. Non zero value indicates vendor
106106
* specific ABI.
107107
* R11 - VMCALL sub function number
108-
* RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific arguments.
108+
* RBX, RDX, RDI, RSI - Used to pass VMCALL sub function specific arguments.
109109
* R8-R9, R12-R15 - Same as above.
110110
*
111111
* Output Registers:
112112
*
113113
* RAX - TDCALL instruction status (Not related to hypercall
114114
* output).
115-
* R10 - Hypercall output error code.
116-
* R11-R15 - Hypercall sub function specific output values.
115+
* RBX, RDX, RDI, RSI - Hypercall sub function specific output values.
116+
* R8-R15 - Same as above.
117117
*
118-
*-------------------------------------------------------------------------
119-
*
120-
* __tdx_hypercall() function ABI:
121-
*
122-
* @args (RDI) - struct tdx_hypercall_args for input and output
123-
* @flags (RSI) - TDX_HCALL_* flags
124-
*
125-
* On successful completion, return the hypercall error code.
126118
*/
127-
SYM_FUNC_START(__tdx_hypercall)
119+
.macro TDX_HYPERCALL ret:req
128120
FRAME_BEGIN
129121

130122
/* Save callee-saved GPRs as mandated by the x86_64 ABI */
@@ -134,9 +126,8 @@ SYM_FUNC_START(__tdx_hypercall)
134126
push %r12
135127
push %rbx
136128

137-
/* Free RDI and RSI to be used as TDVMCALL arguments */
129+
/* Free RDI to be used as TDVMCALL arguments */
138130
movq %rdi, %rax
139-
push %rsi
140131

141132
/* Copy hypercall registers from arg struct: */
142133
movq TDX_HYPERCALL_r8(%rax), %r8
@@ -171,14 +162,11 @@ SYM_FUNC_START(__tdx_hypercall)
171162
* and are handled by callers.
172163
*/
173164
testq %rax, %rax
174-
jne .Lpanic
165+
jne .Lpanic\@
175166

176167
pop %rax
177168

178-
/* Copy hypercall result registers to arg struct if needed */
179-
testq $TDX_HCALL_HAS_OUTPUT, (%rsp)
180-
jz .Lout
181-
169+
.if \ret
182170
movq %r8, TDX_HYPERCALL_r8(%rax)
183171
movq %r9, TDX_HYPERCALL_r9(%rax)
184172
movq %r10, TDX_HYPERCALL_r10(%rax)
@@ -191,7 +179,8 @@ SYM_FUNC_START(__tdx_hypercall)
191179
movq %rsi, TDX_HYPERCALL_rsi(%rax)
192180
movq %rbx, TDX_HYPERCALL_rbx(%rax)
193181
movq %rdx, TDX_HYPERCALL_rdx(%rax)
194-
.Lout:
182+
.endif
183+
195184
/* TDVMCALL leaf return code is in R10 */
196185
movq %r10, %rax
197186

@@ -208,9 +197,6 @@ SYM_FUNC_START(__tdx_hypercall)
208197
xor %rdi, %rdi
209198
xor %rdx, %rdx
210199

211-
/* Remove TDX_HCALL_* flags from the stack */
212-
pop %rsi
213-
214200
/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
215201
pop %rbx
216202
pop %r12
@@ -221,9 +207,33 @@ SYM_FUNC_START(__tdx_hypercall)
221207
FRAME_END
222208

223209
RET
224-
.Lpanic:
210+
.Lpanic\@:
225211
call __tdx_hypercall_failed
226212
/* __tdx_hypercall_failed never returns */
227213
REACHABLE
228-
jmp .Lpanic
214+
jmp .Lpanic\@
215+
.endm
216+
217+
/*
218+
*
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
229227
SYM_FUNC_END(__tdx_hypercall)
228+
229+
/*
230+
*
231+
* __tdx_hypercall_ret() function ABI:
232+
*
233+
* @args (RDI) - struct tdx_hypercall_args for input and output
234+
*
235+
* On successful completion, return the hypercall error code.
236+
*/
237+
SYM_FUNC_START(__tdx_hypercall_ret)
238+
TDX_HYPERCALL ret=1
239+
SYM_FUNC_END(__tdx_hypercall_ret)

arch/x86/coco/tdx/tdx.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
6666
.r15 = r15,
6767
};
6868

69-
return __tdx_hypercall(&args, 0);
69+
return __tdx_hypercall(&args);
7070
}
7171

7272
/* Called from __tdx_hypercall() for unrecoverable failure */
@@ -99,7 +99,7 @@ long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
9999
.r14 = p4,
100100
};
101101

102-
return __tdx_hypercall(&args, 0);
102+
return __tdx_hypercall(&args);
103103
}
104104
EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
105105
#endif
@@ -179,7 +179,7 @@ static void __noreturn tdx_panic(const char *msg)
179179
* happens to return.
180180
*/
181181
while (1)
182-
__tdx_hypercall(&args, 0);
182+
__tdx_hypercall(&args);
183183
}
184184

185185
static void tdx_parse_tdinfo(u64 *cc_mask)
@@ -289,7 +289,7 @@ static u64 __cpuidle __halt(const bool irq_disabled)
289289
* can keep the vCPU in virtual HLT, even if an IRQ is
290290
* pending, without hanging/breaking the guest.
291291
*/
292-
return __tdx_hypercall(&args, 0);
292+
return __tdx_hypercall(&args);
293293
}
294294

295295
static int handle_halt(struct ve_info *ve)
@@ -326,7 +326,7 @@ static int read_msr(struct pt_regs *regs, struct ve_info *ve)
326326
* can be found in TDX Guest-Host-Communication Interface
327327
* (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
328328
*/
329-
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
329+
if (__tdx_hypercall_ret(&args))
330330
return -EIO;
331331

332332
regs->ax = lower_32_bits(args.r11);
@@ -348,7 +348,7 @@ static int write_msr(struct pt_regs *regs, struct ve_info *ve)
348348
* can be found in TDX Guest-Host-Communication Interface
349349
* (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>".
350350
*/
351-
if (__tdx_hypercall(&args, 0))
351+
if (__tdx_hypercall(&args))
352352
return -EIO;
353353

354354
return ve_instr_len(ve);
@@ -380,7 +380,7 @@ static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
380380
* ABI can be found in TDX Guest-Host-Communication Interface
381381
* (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
382382
*/
383-
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
383+
if (__tdx_hypercall_ret(&args))
384384
return -EIO;
385385

386386
/*
@@ -407,7 +407,7 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
407407
.r15 = *val,
408408
};
409409

410-
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
410+
if (__tdx_hypercall_ret(&args))
411411
return false;
412412
*val = args.r11;
413413
return true;
@@ -541,7 +541,7 @@ static bool handle_in(struct pt_regs *regs, int size, int port)
541541
* in TDX Guest-Host-Communication Interface (GHCI) section titled
542542
* "TDG.VP.VMCALL<Instruction.IO>".
543543
*/
544-
success = !__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT);
544+
success = !__tdx_hypercall_ret(&args);
545545

546546
/* Update part of the register affected by the emulated instruction */
547547
regs->ax &= ~mask;

arch/x86/include/asm/shared/tdx.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
#define TDX_HYPERCALL_STANDARD 0
99

10-
#define TDX_HCALL_HAS_OUTPUT BIT(0)
11-
1210
#define TDX_CPUID_LEAF_ID 0x21
1311
#define TDX_IDENT "IntelTDX "
1412

@@ -36,7 +34,8 @@ struct tdx_hypercall_args {
3634
};
3735

3836
/* Used to request services from the VMM */
39-
u64 __tdx_hypercall(struct tdx_hypercall_args *args, unsigned long flags);
37+
u64 __tdx_hypercall(struct tdx_hypercall_args *args);
38+
u64 __tdx_hypercall_ret(struct tdx_hypercall_args *args);
4039

4140
/* Called from __tdx_hypercall() for unrecoverable failure */
4241
void __tdx_hypercall_failed(void);

0 commit comments

Comments
 (0)