x86/tdx: Skip saving output regs when SEAMCALL fails with VMFailInvalid
authorKai Huang <kai.huang@intel.com>
Tue, 15 Aug 2023 11:01:56 +0000 (23:01 +1200)
committerDave Hansen <dave.hansen@linux.intel.com>
Mon, 11 Sep 2023 23:32:23 +0000 (16:32 -0700)
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
arch/x86/coco/tdx/tdcall.S
arch/x86/virt/vmx/tdx/tdxcall.S

index 2eca5f43734feb9aa93cddc18800201d6367934e..e5d4b7d8ecd4a40007ff9b7e39e27f0a524db239 100644 (file)
  * 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)
 
 /*
index 49a54356ae9925d7f53621696ec8ebc551d8fd18..6bdf6e1379534d4b5bc421469da25596030f4c04 100644 (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
         * 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)
        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