On Wed, Jul 12, 2023 at 08:55:21PM +1200, Kai Huang wrote: > @@ -65,6 +104,37 @@ > .endif > > .if \ret > + .if \saved > + /* > + * Restore the structure from stack to saved the output registers > + * > + * In case of VP.ENTER returns due to TDVMCALL, all registers are > + * valid thus no register can be used as spare to restore the > + * structure from the stack (see "TDH.VP.ENTER Output Operands > + * Definition on TDCALL(TDG.VP.VMCALL) Following a TD Entry"). > + * For this case, need to make one register as spare by saving it > + * to the stack and then manually load the structure pointer to > + * the spare register. > + * > + * Note for other TDCALLs/SEAMCALLs there are spare registers > + * thus no need for such hack but just use this for all for now. > + */ > + pushq %rax /* save the TDCALL/SEAMCALL return code */ > + movq 8(%rsp), %rax /* restore the structure pointer */ > + movq %rsi, TDX_MODULE_rsi(%rax) /* save %rsi */ > + movq %rax, %rsi /* use %rsi as structure pointer */ > + popq %rax /* restore the return code */ > + popq %rsi /* pop the structure pointer */ Urgghh... At least for the \host case you can simply pop %rsi, no? VP.ENTER returns with 0 there IIRC. /* xor-swap (%rsp) and %rax */ xorq (%rsp), %rax xorq %rax, (%rsp) xorq (%rsp), %rax movq %rsi, TDX_MODULE_rsi(%rax); movq %rax, %rsi popq %rax Isn't much better is it :/ Too bad xchg implies lock prefix. > + > + /* Copy additional output regs to the structure */ > + movq %r12, TDX_MODULE_r12(%rsi) > + movq %r13, TDX_MODULE_r13(%rsi) > + movq %r14, TDX_MODULE_r14(%rsi) > + movq %r15, TDX_MODULE_r15(%rsi) > + movq %rbx, TDX_MODULE_rbx(%rsi) > + movq %rdi, TDX_MODULE_rdi(%rsi) > + .endif /* \saved */ > + > /* Copy output regs to the structure */ > movq %rcx, TDX_MODULE_rcx(%rsi) > movq %rdx, TDX_MODULE_rdx(%rsi)