On Tue, Jun 27, 2023 at 02:12:50AM +1200, Kai Huang wrote: > diff --git a/arch/x86/virt/vmx/tdx/tdxcall.S b/arch/x86/virt/vmx/tdx/tdxcall.S > index 49a54356ae99..757b0c34be10 100644 > --- a/arch/x86/virt/vmx/tdx/tdxcall.S > +++ b/arch/x86/virt/vmx/tdx/tdxcall.S > @@ -1,6 +1,7 @@ > /* SPDX-License-Identifier: GPL-2.0 */ > #include <asm/asm-offsets.h> > #include <asm/tdx.h> > +#include <asm/asm.h> > > /* > * TDCALL and SEAMCALL are supported in Binutils >= 2.36. > @@ -45,6 +46,7 @@ > /* Leave input param 2 in RDX */ > > .if \host > +1: > seamcall So what registers are actually clobbered by SEAMCALL ? There's a distinct lack of it in SDM Vol.2 instruction list :-( > /* > * SEAMCALL instruction is essentially a VMExit from VMX root > @@ -57,10 +59,23 @@ > * This value will never be used as actual SEAMCALL error code as > * it is from the Reserved status code class. > */ > - jnc .Lno_vmfailinvalid > + jnc .Lseamcall_out > mov $TDX_SEAMCALL_VMFAILINVALID, %rax > -.Lno_vmfailinvalid: > + jmp .Lseamcall_out > +2: > + /* > + * SEAMCALL caused #GP or #UD. By reaching here %eax contains > + * the trap number. Convert the trap number to the TDX error > + * code by setting TDX_SW_ERROR to the high 32-bits of %rax. > + * > + * Note cannot OR TDX_SW_ERROR directly to %rax as OR instruction > + * only accepts 32-bit immediate at most. > + */ > + mov $TDX_SW_ERROR, %r12 > + orq %r12, %rax > > + _ASM_EXTABLE_FAULT(1b, 2b) > +.Lseamcall_out: This is all pretty atrocious code flow... would it at all be possible to write it like: SYM_FUNC_START(...) .if \host 1: seamcall cmovc %spare, %rax 2: .else tdcall .endif ..... RET 3: mov $TDX_SW_ERROR, %r12 orq %r12, %rax jmp 2b _ASM_EXTABLE_FAULT(1b, 3b) SYM_FUNC_END() That is, having all that inline in the hotpath is quite horrific.