97 lines
2.5 KiB
ArmAsm
97 lines
2.5 KiB
ArmAsm
|
/* 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
|