1/* SPDX-License-Identifier: GPL-2.0 */ 2#include <asm/asm-offsets.h> 3#include <asm/tdx.h> 4 5/* 6 * TDCALL and SEAMCALL are supported in Binutils >= 2.36. 7 */ 8#define tdcall .byte 0x66,0x0f,0x01,0xcc 9#define seamcall .byte 0x66,0x0f,0x01,0xcf 10 11/* 12 * TDX_MODULE_CALL - common helper macro for both 13 * TDCALL and SEAMCALL instructions. 14 * 15 * TDCALL - used by TDX guests to make requests to the 16 * TDX module and hypercalls to the VMM. 17 * SEAMCALL - used by TDX hosts to make requests to the 18 * TDX module. 19 */ 20.macro TDX_MODULE_CALL host:req 21 /* 22 * R12 will be used as temporary storage for struct tdx_module_output 23 * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL 24 * services supported by this function, it can be reused. 25 */ 26 27 /* Callee saved, so preserve it */ 28 push %r12 29 30 /* 31 * Push output pointer to stack. 32 * After the operation, it will be fetched into R12 register. 33 */ 34 push %r9 35 36 /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */ 37 /* Move Leaf ID to RAX */ 38 mov %rdi, %rax 39 /* Move input 4 to R9 */ 40 mov %r8, %r9 41 /* Move input 3 to R8 */ 42 mov %rcx, %r8 43 /* Move input 1 to RCX */ 44 mov %rsi, %rcx 45 /* Leave input param 2 in RDX */ 46 47 .if \host 48 seamcall 49 /* 50 * SEAMCALL instruction is essentially a VMExit from VMX root 51 * mode to SEAM VMX root mode. VMfailInvalid (CF=1) indicates 52 * that the targeted SEAM firmware is not loaded or disabled, 53 * or P-SEAMLDR is busy with another SEAMCALL. %rax is not 54 * changed in this case. 55 * 56 * Set %rax to TDX_SEAMCALL_VMFAILINVALID for VMfailInvalid. 57 * This value will never be used as actual SEAMCALL error code as 58 * it is from the Reserved status code class. 59 */ 60 jnc .Lno_vmfailinvalid 61 mov $TDX_SEAMCALL_VMFAILINVALID, %rax 62.Lno_vmfailinvalid: 63 64 .else 65 tdcall 66 .endif 67 68 /* 69 * Fetch output pointer from stack to R12 (It is used 70 * as temporary storage) 71 */ 72 pop %r12 73 74 /* 75 * Since this macro can be invoked with NULL as an output pointer, 76 * check if caller provided an output struct before storing output 77 * registers. 78 * 79 * Update output registers, even if the call failed (RAX != 0). 80 * Other registers may contain details of the failure. 81 */ 82 test %r12, %r12 83 jz .Lno_output_struct 84 85 /* Copy result registers to output struct: */ 86 movq %rcx, TDX_MODULE_rcx(%r12) 87 movq %rdx, TDX_MODULE_rdx(%r12) 88 movq %r8, TDX_MODULE_r8(%r12) 89 movq %r9, TDX_MODULE_r9(%r12) 90 movq %r10, TDX_MODULE_r10(%r12) 91 movq %r11, TDX_MODULE_r11(%r12) 92 93.Lno_output_struct: 94 /* Restore the state of R12 register */ 95 pop %r12 96.endm 97