x86/tdx: Skip saving output regs when SEAMCALL fails with VMFailInvalid

[ Upstream commit 03a423d40cb30e0e1cb77a801acb56ddb0bf6f5e ]

If SEAMCALL fails with VMFailInvalid, the SEAM software (e.g., the TDX
module) won't have chance to set any output register.  Skip saving the
output registers to the structure in this case.

Also, as '.Lno_output_struct' is the very last symbol before RET, rename
it to '.Lout' to make it short.

Opportunistically make the asm directives unindented.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
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>
Link: https://lore.kernel.org/all/704088f5b4d72c7e24084f7f15bd1ac5005b7213.1692096753.git.kai.huang%40intel.com
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Kai Huang
2023-08-15 23:01:56 +12:00
committed by Greg Kroah-Hartman
parent c72a9456fd
commit 2765142c05
2 changed files with 20 additions and 12 deletions

View File

@@ -78,10 +78,7 @@
* Return status of TDCALL via RAX.
*/
SYM_FUNC_START(__tdx_module_call)
FRAME_BEGIN
TDX_MODULE_CALL host=0
FRAME_END
RET
SYM_FUNC_END(__tdx_module_call)
/*

View File

@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/asm-offsets.h>
#include <asm/frame.h>
#include <asm/tdx.h>
/*
@@ -18,6 +19,7 @@
* TDX module.
*/
.macro TDX_MODULE_CALL host:req
FRAME_BEGIN
/*
* R12 will be used as temporary storage for struct tdx_module_output
* pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
@@ -44,7 +46,7 @@
mov %rsi, %rcx
/* Leave input param 2 in RDX */
.if \host
.if \host
seamcall
/*
* SEAMCALL instruction is essentially a VMExit from VMX root
@@ -57,13 +59,10 @@
* This value will never be used as actual SEAMCALL error code as
* it is from the Reserved status code class.
*/
jnc .Lno_vmfailinvalid
mov $TDX_SEAMCALL_VMFAILINVALID, %rax
.Lno_vmfailinvalid:
.else
jc .Lseamcall_vmfailinvalid
.else
tdcall
.endif
.endif
/*
* Fetch output pointer from stack to R12 (It is used
@@ -80,7 +79,7 @@
* Other registers may contain details of the failure.
*/
test %r12, %r12
jz .Lno_output_struct
jz .Lout
/* Copy result registers to output struct: */
movq %rcx, TDX_MODULE_rcx(%r12)
@@ -90,7 +89,19 @@
movq %r10, TDX_MODULE_r10(%r12)
movq %r11, TDX_MODULE_r11(%r12)
.Lno_output_struct:
.Lout:
/* Restore the state of R12 register */
pop %r12
FRAME_END
RET
.if \host
.Lseamcall_vmfailinvalid:
mov $TDX_SEAMCALL_VMFAILINVALID, %rax
/* pop the unused output pointer back to %r9 */
pop %r9
jmp .Lout
.endif /* \host */
.endm