TDCALL calls are centralized into a few megawrappers that take the struct tdx_module_args as input. Most of the call sites only use a few arguments, but they have to zero out unused fields in the structure to avoid data leaks to the VMM. This leads to the compiler generating inefficient code: dozens of instructions per call site to clear unused fields of the structure. This issue can be avoided by using more targeted wrappers. tdvmcall_trampoline() provides a common base for them. The function will be used from inline assembly to handle most TDVMCALL cases. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- arch/x86/coco/tdx/tdcall.S | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S index 52d9786da308..12185fbd33ba 100644 --- a/arch/x86/coco/tdx/tdcall.S +++ b/arch/x86/coco/tdx/tdcall.S @@ -61,3 +61,52 @@ SYM_FUNC_END(__tdcall_ret) SYM_FUNC_START(__tdcall_saved_ret) TDX_MODULE_CALL host=0 ret=1 saved=1 SYM_FUNC_END(__tdcall_saved_ret) + +/* + * tdvmcall_trampoline() - Wrapper for TDG.VP.VMCALL. Covers common cases: up + * to five input and out arguments. + * + * tdvmcall_trampoline() function ABI is not SYSV ABI compliant. Caller has to + * deal with it. + * + * Input: + * RAX - Type of call, TDX_HYPERCALL_STANDARD for calls defined in GHCI spec + * RBX - 1st argument (R11), leaf ID if RAX is TDX_HYPERCALL_STANDARD + * RDI - 2nd argument (R12) + * RSI - 3rd argument (R13) + * RDX - 4th argument (R14) + * RCX - 5th argument (R15) + * + * Output: + * R10 - TDVMCALL error code + * R11 - Output 1 + * R12 - Output 2 + * R13 - Output 3 + * R14 - Output 4 + * R15 - Output 5 + */ +.pushsection .noinstr.text, "ax" +SYM_FUNC_START(tdvmcall_trampoline) + movq %rax, %r10 + movq %rbx, %r11 + movq %rdi, %r12 + movq %rsi, %r13 + movq %rdx, %r14 + movq %rcx, %r15 + + movq $TDG_VP_VMCALL, %rax + + /* RCX is bitmap of registers exposed to VMM on TDG.VM.VMCALL */ + movq $(TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15), %rcx + + tdcall + + /* TDG.VP.VMCALL never fails on correct use. Panic if it fails. */ + testq %rax, %rax + jnz .Lpanic + + RET +.Lpanic: + ud2 +SYM_FUNC_END(tdvmcall_trampoline) +.popsection -- 2.43.0