123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- /* SPDX-License-Identifier: GPL-2.0 */
- #include <asm/asm-offsets.h>
- #include <asm/tdx.h>
- /*
- * TDCALL and SEAMCALL are supported in Binutils >= 2.36.
- */
- #define tdcall .byte 0x66,0x0f,0x01,0xcc
- #define seamcall .byte 0x66,0x0f,0x01,0xcf
- /*
- * TDX_MODULE_CALL - common helper macro for both
- * TDCALL and SEAMCALL instructions.
- *
- * TDCALL - used by TDX guests to make requests to the
- * TDX module and hypercalls to the VMM.
- * SEAMCALL - used by TDX hosts to make requests to the
- * TDX module.
- */
- .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 as
- * it is from the Reserved status code class.
- */
- jnc .Lno_vmfailinvalid
- mov $TDX_SEAMCALL_VMFAILINVALID, %rax
- .Lno_vmfailinvalid:
- .else
- tdcall
- .endif
- /*
- * Fetch output pointer from stack to R12 (It is used
- * as temporary storage)
- */
- pop %r12
- /*
- * Since this macro can be invoked with NULL as an output pointer,
- * check if caller provided an output struct before storing output
- * registers.
- *
- * Update output registers, even if the call failed (RAX != 0).
- * Other registers may contain details of the failure.
- */
- 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
|