Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #include <asm/asm-offsets.h>
0003 #include <asm/tdx.h>
0004 
0005 /*
0006  * TDCALL and SEAMCALL are supported in Binutils >= 2.36.
0007  */
0008 #define tdcall      .byte 0x66,0x0f,0x01,0xcc
0009 #define seamcall    .byte 0x66,0x0f,0x01,0xcf
0010 
0011 /*
0012  * TDX_MODULE_CALL - common helper macro for both
0013  *                 TDCALL and SEAMCALL instructions.
0014  *
0015  * TDCALL   - used by TDX guests to make requests to the
0016  *            TDX module and hypercalls to the VMM.
0017  * SEAMCALL - used by TDX hosts to make requests to the
0018  *            TDX module.
0019  */
0020 .macro TDX_MODULE_CALL host:req
0021     /*
0022      * R12 will be used as temporary storage for struct tdx_module_output
0023      * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
0024      * services supported by this function, it can be reused.
0025      */
0026 
0027     /* Callee saved, so preserve it */
0028     push %r12
0029 
0030     /*
0031      * Push output pointer to stack.
0032      * After the operation, it will be fetched into R12 register.
0033      */
0034     push %r9
0035 
0036     /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */
0037     /* Move Leaf ID to RAX */
0038     mov %rdi, %rax
0039     /* Move input 4 to R9 */
0040     mov %r8,  %r9
0041     /* Move input 3 to R8 */
0042     mov %rcx, %r8
0043     /* Move input 1 to RCX */
0044     mov %rsi, %rcx
0045     /* Leave input param 2 in RDX */
0046 
0047     .if \host
0048     seamcall
0049     /*
0050      * SEAMCALL instruction is essentially a VMExit from VMX root
0051      * mode to SEAM VMX root mode.  VMfailInvalid (CF=1) indicates
0052      * that the targeted SEAM firmware is not loaded or disabled,
0053      * or P-SEAMLDR is busy with another SEAMCALL.  %rax is not
0054      * changed in this case.
0055      *
0056      * Set %rax to TDX_SEAMCALL_VMFAILINVALID for VMfailInvalid.
0057      * This value will never be used as actual SEAMCALL error code as
0058      * it is from the Reserved status code class.
0059      */
0060     jnc .Lno_vmfailinvalid
0061     mov $TDX_SEAMCALL_VMFAILINVALID, %rax
0062 .Lno_vmfailinvalid:
0063 
0064     .else
0065     tdcall
0066     .endif
0067 
0068     /*
0069      * Fetch output pointer from stack to R12 (It is used
0070      * as temporary storage)
0071      */
0072     pop %r12
0073 
0074     /*
0075      * Since this macro can be invoked with NULL as an output pointer,
0076      * check if caller provided an output struct before storing output
0077      * registers.
0078      *
0079      * Update output registers, even if the call failed (RAX != 0).
0080      * Other registers may contain details of the failure.
0081      */
0082     test %r12, %r12
0083     jz .Lno_output_struct
0084 
0085     /* Copy result registers to output struct: */
0086     movq %rcx, TDX_MODULE_rcx(%r12)
0087     movq %rdx, TDX_MODULE_rdx(%r12)
0088     movq %r8,  TDX_MODULE_r8(%r12)
0089     movq %r9,  TDX_MODULE_r9(%r12)
0090     movq %r10, TDX_MODULE_r10(%r12)
0091     movq %r11, TDX_MODULE_r11(%r12)
0092 
0093 .Lno_output_struct:
0094     /* Restore the state of R12 register */
0095     pop %r12
0096 .endm