Messages in this thread | | | Date | Fri, 4 Feb 2022 22:51:38 +1300 | From | Kai Huang <> | Subject | Re: [PATCHv2 03/29] x86/tdx: Add __tdx_module_call() and __tdx_hypercall() helper functions |
| |
> + > +.macro TDX_MODULE_CALL host:req > + /* > + * R12 will be used as temporary storage for struct tdx_module_output > + * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL > + * services supported by this function, it can be reused. > + */ > + > + /* Callee saved, so preserve it */ > + push %r12 > + > + /* > + * Push output pointer to stack. > + * After the operation, it will be fetched into R12 register. > + */ > + push %r9 > + > + /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */ > + /* Move Leaf ID to RAX */ > + mov %rdi, %rax > + /* Move input 4 to R9 */ > + mov %r8, %r9 > + /* Move input 3 to R8 */ > + mov %rcx, %r8 > + /* Move input 1 to RCX */ > + mov %rsi, %rcx > + /* Leave input param 2 in RDX */ > + > + .if \host > + seamcall > + /* > + * SEAMCALL instruction is essentially a VMExit from VMX root > + * mode to SEAM VMX root mode. VMfailInvalid (CF=1) indicates > + * that the targeted SEAM firmware is not loaded or disabled, > + * or P-SEAMLDR is busy with another SEAMCALL. %rax is not > + * changed in this case. > + * > + * Set %rax to TDX_SEAMCALL_VMFAILINVALID for VMfailInvalid. > + * This value will never be used as actual SEAMCALL error code. > + */ > + jnc .Lno_vmfailinvalid > + mov $TDX_SEAMCALL_VMFAILINVALID, %rax > + jmp .Lno_output_struct
If I read correctly, in case of VMfailInvalid, another "pop %r12" is needed before jmp to .Lno_output_struct, otherwise it doesn't match the stack (pushed twice).
However, since "test %rax, %rax" will also catch TDX_SEAMCALL_VMFAILINVALID, it seems we can just delete above "jmp .Lno_output_struct"?
> +.Lno_vmfailinvalid: > + .else > + tdcall > + .endif > + > + /* > + * Fetch output pointer from stack to R12 (It is used > + * as temporary storage) > + */ > + pop %r12 > + > + /* Check for success: 0 - Successful, otherwise failed */ > + test %rax, %rax > + jnz .Lno_output_struct > + > + /* > + * Since this function can be initiated without an output pointer, > + * check if caller provided an output struct before storing > + * output registers. > + */ > + test %r12, %r12 > + jz .Lno_output_struct > + > + /* Copy result registers to output struct: */ > + movq %rcx, TDX_MODULE_rcx(%r12) > + movq %rdx, TDX_MODULE_rdx(%r12) > + movq %r8, TDX_MODULE_r8(%r12) > + movq %r9, TDX_MODULE_r9(%r12) > + movq %r10, TDX_MODULE_r10(%r12) > + movq %r11, TDX_MODULE_r11(%r12) > + > +.Lno_output_struct: > + /* Restore the state of R12 register */ > + pop %r12 > +.endm > -- > Kirill A. Shutemov
| |