1*eb94f1b6SKuppuswamy Sathyanarayanan/* SPDX-License-Identifier: GPL-2.0 */ 2*eb94f1b6SKuppuswamy Sathyanarayanan#include <asm/asm-offsets.h> 3*eb94f1b6SKuppuswamy Sathyanarayanan#include <asm/asm.h> 4*eb94f1b6SKuppuswamy Sathyanarayanan#include <asm/frame.h> 5*eb94f1b6SKuppuswamy Sathyanarayanan#include <asm/unwind_hints.h> 6*eb94f1b6SKuppuswamy Sathyanarayanan 7*eb94f1b6SKuppuswamy Sathyanarayanan#include <linux/linkage.h> 8*eb94f1b6SKuppuswamy Sathyanarayanan#include <linux/bits.h> 9*eb94f1b6SKuppuswamy Sathyanarayanan#include <linux/errno.h> 10*eb94f1b6SKuppuswamy Sathyanarayanan 11*eb94f1b6SKuppuswamy Sathyanarayanan#include "../../virt/vmx/tdx/tdxcall.S" 12*eb94f1b6SKuppuswamy Sathyanarayanan 13*eb94f1b6SKuppuswamy Sathyanarayanan/* 14*eb94f1b6SKuppuswamy Sathyanarayanan * Bitmasks of exposed registers (with VMM). 15*eb94f1b6SKuppuswamy Sathyanarayanan */ 16*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R10 BIT(10) 17*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R11 BIT(11) 18*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R12 BIT(12) 19*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R13 BIT(13) 20*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R14 BIT(14) 21*eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R15 BIT(15) 22*eb94f1b6SKuppuswamy Sathyanarayanan 23*eb94f1b6SKuppuswamy Sathyanarayanan/* 24*eb94f1b6SKuppuswamy Sathyanarayanan * These registers are clobbered to hold arguments for each 25*eb94f1b6SKuppuswamy Sathyanarayanan * TDVMCALL. They are safe to expose to the VMM. 26*eb94f1b6SKuppuswamy Sathyanarayanan * Each bit in this mask represents a register ID. Bit field 27*eb94f1b6SKuppuswamy Sathyanarayanan * details can be found in TDX GHCI specification, section 28*eb94f1b6SKuppuswamy Sathyanarayanan * titled "TDCALL [TDG.VP.VMCALL] leaf". 29*eb94f1b6SKuppuswamy Sathyanarayanan */ 30*eb94f1b6SKuppuswamy Sathyanarayanan#define TDVMCALL_EXPOSE_REGS_MASK ( TDX_R10 | TDX_R11 | \ 31*eb94f1b6SKuppuswamy Sathyanarayanan TDX_R12 | TDX_R13 | \ 32*eb94f1b6SKuppuswamy Sathyanarayanan TDX_R14 | TDX_R15 ) 33*eb94f1b6SKuppuswamy Sathyanarayanan 34*eb94f1b6SKuppuswamy Sathyanarayanan/* 35*eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_module_call() - Used by TDX guests to request services from 36*eb94f1b6SKuppuswamy Sathyanarayanan * the TDX module (does not include VMM services) using TDCALL instruction. 37*eb94f1b6SKuppuswamy Sathyanarayanan * 38*eb94f1b6SKuppuswamy Sathyanarayanan * Transforms function call register arguments into the TDCALL register ABI. 39*eb94f1b6SKuppuswamy Sathyanarayanan * After TDCALL operation, TDX module output is saved in @out (if it is 40*eb94f1b6SKuppuswamy Sathyanarayanan * provided by the user). 41*eb94f1b6SKuppuswamy Sathyanarayanan * 42*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 43*eb94f1b6SKuppuswamy Sathyanarayanan * TDCALL ABI: 44*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 45*eb94f1b6SKuppuswamy Sathyanarayanan * Input Registers: 46*eb94f1b6SKuppuswamy Sathyanarayanan * 47*eb94f1b6SKuppuswamy Sathyanarayanan * RAX - TDCALL Leaf number. 48*eb94f1b6SKuppuswamy Sathyanarayanan * RCX,RDX,R8-R9 - TDCALL Leaf specific input registers. 49*eb94f1b6SKuppuswamy Sathyanarayanan * 50*eb94f1b6SKuppuswamy Sathyanarayanan * Output Registers: 51*eb94f1b6SKuppuswamy Sathyanarayanan * 52*eb94f1b6SKuppuswamy Sathyanarayanan * RAX - TDCALL instruction error code. 53*eb94f1b6SKuppuswamy Sathyanarayanan * RCX,RDX,R8-R11 - TDCALL Leaf specific output registers. 54*eb94f1b6SKuppuswamy Sathyanarayanan * 55*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 56*eb94f1b6SKuppuswamy Sathyanarayanan * 57*eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_module_call() function ABI: 58*eb94f1b6SKuppuswamy Sathyanarayanan * 59*eb94f1b6SKuppuswamy Sathyanarayanan * @fn (RDI) - TDCALL Leaf ID, moved to RAX 60*eb94f1b6SKuppuswamy Sathyanarayanan * @rcx (RSI) - Input parameter 1, moved to RCX 61*eb94f1b6SKuppuswamy Sathyanarayanan * @rdx (RDX) - Input parameter 2, moved to RDX 62*eb94f1b6SKuppuswamy Sathyanarayanan * @r8 (RCX) - Input parameter 3, moved to R8 63*eb94f1b6SKuppuswamy Sathyanarayanan * @r9 (R8) - Input parameter 4, moved to R9 64*eb94f1b6SKuppuswamy Sathyanarayanan * 65*eb94f1b6SKuppuswamy Sathyanarayanan * @out (R9) - struct tdx_module_output pointer 66*eb94f1b6SKuppuswamy Sathyanarayanan * stored temporarily in R12 (not 67*eb94f1b6SKuppuswamy Sathyanarayanan * shared with the TDX module). It 68*eb94f1b6SKuppuswamy Sathyanarayanan * can be NULL. 69*eb94f1b6SKuppuswamy Sathyanarayanan * 70*eb94f1b6SKuppuswamy Sathyanarayanan * Return status of TDCALL via RAX. 71*eb94f1b6SKuppuswamy Sathyanarayanan */ 72*eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_START(__tdx_module_call) 73*eb94f1b6SKuppuswamy Sathyanarayanan FRAME_BEGIN 74*eb94f1b6SKuppuswamy Sathyanarayanan TDX_MODULE_CALL host=0 75*eb94f1b6SKuppuswamy Sathyanarayanan FRAME_END 76*eb94f1b6SKuppuswamy Sathyanarayanan ret 77*eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_END(__tdx_module_call) 78*eb94f1b6SKuppuswamy Sathyanarayanan 79*eb94f1b6SKuppuswamy Sathyanarayanan/* 80*eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_hypercall() - Make hypercalls to a TDX VMM using TDVMCALL leaf 81*eb94f1b6SKuppuswamy Sathyanarayanan * of TDCALL instruction 82*eb94f1b6SKuppuswamy Sathyanarayanan * 83*eb94f1b6SKuppuswamy Sathyanarayanan * Transforms values in function call argument struct tdx_hypercall_args @args 84*eb94f1b6SKuppuswamy Sathyanarayanan * into the TDCALL register ABI. After TDCALL operation, VMM output is saved 85*eb94f1b6SKuppuswamy Sathyanarayanan * back in @args. 86*eb94f1b6SKuppuswamy Sathyanarayanan * 87*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 88*eb94f1b6SKuppuswamy Sathyanarayanan * TD VMCALL ABI: 89*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 90*eb94f1b6SKuppuswamy Sathyanarayanan * 91*eb94f1b6SKuppuswamy Sathyanarayanan * Input Registers: 92*eb94f1b6SKuppuswamy Sathyanarayanan * 93*eb94f1b6SKuppuswamy Sathyanarayanan * RAX - TDCALL instruction leaf number (0 - TDG.VP.VMCALL) 94*eb94f1b6SKuppuswamy Sathyanarayanan * RCX - BITMAP which controls which part of TD Guest GPR 95*eb94f1b6SKuppuswamy Sathyanarayanan * is passed as-is to the VMM and back. 96*eb94f1b6SKuppuswamy Sathyanarayanan * R10 - Set 0 to indicate TDCALL follows standard TDX ABI 97*eb94f1b6SKuppuswamy Sathyanarayanan * specification. Non zero value indicates vendor 98*eb94f1b6SKuppuswamy Sathyanarayanan * specific ABI. 99*eb94f1b6SKuppuswamy Sathyanarayanan * R11 - VMCALL sub function number 100*eb94f1b6SKuppuswamy Sathyanarayanan * RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific arguments. 101*eb94f1b6SKuppuswamy Sathyanarayanan * R8-R9, R12-R15 - Same as above. 102*eb94f1b6SKuppuswamy Sathyanarayanan * 103*eb94f1b6SKuppuswamy Sathyanarayanan * Output Registers: 104*eb94f1b6SKuppuswamy Sathyanarayanan * 105*eb94f1b6SKuppuswamy Sathyanarayanan * RAX - TDCALL instruction status (Not related to hypercall 106*eb94f1b6SKuppuswamy Sathyanarayanan * output). 107*eb94f1b6SKuppuswamy Sathyanarayanan * R10 - Hypercall output error code. 108*eb94f1b6SKuppuswamy Sathyanarayanan * R11-R15 - Hypercall sub function specific output values. 109*eb94f1b6SKuppuswamy Sathyanarayanan * 110*eb94f1b6SKuppuswamy Sathyanarayanan *------------------------------------------------------------------------- 111*eb94f1b6SKuppuswamy Sathyanarayanan * 112*eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_hypercall() function ABI: 113*eb94f1b6SKuppuswamy Sathyanarayanan * 114*eb94f1b6SKuppuswamy Sathyanarayanan * @args (RDI) - struct tdx_hypercall_args for input and output 115*eb94f1b6SKuppuswamy Sathyanarayanan * @flags (RSI) - TDX_HCALL_* flags 116*eb94f1b6SKuppuswamy Sathyanarayanan * 117*eb94f1b6SKuppuswamy Sathyanarayanan * On successful completion, return the hypercall error code. 118*eb94f1b6SKuppuswamy Sathyanarayanan */ 119*eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_START(__tdx_hypercall) 120*eb94f1b6SKuppuswamy Sathyanarayanan FRAME_BEGIN 121*eb94f1b6SKuppuswamy Sathyanarayanan 122*eb94f1b6SKuppuswamy Sathyanarayanan /* Save callee-saved GPRs as mandated by the x86_64 ABI */ 123*eb94f1b6SKuppuswamy Sathyanarayanan push %r15 124*eb94f1b6SKuppuswamy Sathyanarayanan push %r14 125*eb94f1b6SKuppuswamy Sathyanarayanan push %r13 126*eb94f1b6SKuppuswamy Sathyanarayanan push %r12 127*eb94f1b6SKuppuswamy Sathyanarayanan 128*eb94f1b6SKuppuswamy Sathyanarayanan /* Mangle function call ABI into TDCALL ABI: */ 129*eb94f1b6SKuppuswamy Sathyanarayanan /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */ 130*eb94f1b6SKuppuswamy Sathyanarayanan xor %eax, %eax 131*eb94f1b6SKuppuswamy Sathyanarayanan 132*eb94f1b6SKuppuswamy Sathyanarayanan /* Copy hypercall registers from arg struct: */ 133*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r10(%rdi), %r10 134*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r11(%rdi), %r11 135*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r12(%rdi), %r12 136*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r13(%rdi), %r13 137*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r14(%rdi), %r14 138*eb94f1b6SKuppuswamy Sathyanarayanan movq TDX_HYPERCALL_r15(%rdi), %r15 139*eb94f1b6SKuppuswamy Sathyanarayanan 140*eb94f1b6SKuppuswamy Sathyanarayanan movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx 141*eb94f1b6SKuppuswamy Sathyanarayanan 142*eb94f1b6SKuppuswamy Sathyanarayanan tdcall 143*eb94f1b6SKuppuswamy Sathyanarayanan 144*eb94f1b6SKuppuswamy Sathyanarayanan /* 145*eb94f1b6SKuppuswamy Sathyanarayanan * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that 146*eb94f1b6SKuppuswamy Sathyanarayanan * something has gone horribly wrong with the TDX module. 147*eb94f1b6SKuppuswamy Sathyanarayanan * 148*eb94f1b6SKuppuswamy Sathyanarayanan * The return status of the hypercall operation is in a separate 149*eb94f1b6SKuppuswamy Sathyanarayanan * register (in R10). Hypercall errors are a part of normal operation 150*eb94f1b6SKuppuswamy Sathyanarayanan * and are handled by callers. 151*eb94f1b6SKuppuswamy Sathyanarayanan */ 152*eb94f1b6SKuppuswamy Sathyanarayanan testq %rax, %rax 153*eb94f1b6SKuppuswamy Sathyanarayanan jne .Lpanic 154*eb94f1b6SKuppuswamy Sathyanarayanan 155*eb94f1b6SKuppuswamy Sathyanarayanan /* TDVMCALL leaf return code is in R10 */ 156*eb94f1b6SKuppuswamy Sathyanarayanan movq %r10, %rax 157*eb94f1b6SKuppuswamy Sathyanarayanan 158*eb94f1b6SKuppuswamy Sathyanarayanan /* Copy hypercall result registers to arg struct if needed */ 159*eb94f1b6SKuppuswamy Sathyanarayanan testq $TDX_HCALL_HAS_OUTPUT, %rsi 160*eb94f1b6SKuppuswamy Sathyanarayanan jz .Lout 161*eb94f1b6SKuppuswamy Sathyanarayanan 162*eb94f1b6SKuppuswamy Sathyanarayanan movq %r10, TDX_HYPERCALL_r10(%rdi) 163*eb94f1b6SKuppuswamy Sathyanarayanan movq %r11, TDX_HYPERCALL_r11(%rdi) 164*eb94f1b6SKuppuswamy Sathyanarayanan movq %r12, TDX_HYPERCALL_r12(%rdi) 165*eb94f1b6SKuppuswamy Sathyanarayanan movq %r13, TDX_HYPERCALL_r13(%rdi) 166*eb94f1b6SKuppuswamy Sathyanarayanan movq %r14, TDX_HYPERCALL_r14(%rdi) 167*eb94f1b6SKuppuswamy Sathyanarayanan movq %r15, TDX_HYPERCALL_r15(%rdi) 168*eb94f1b6SKuppuswamy Sathyanarayanan.Lout: 169*eb94f1b6SKuppuswamy Sathyanarayanan /* 170*eb94f1b6SKuppuswamy Sathyanarayanan * Zero out registers exposed to the VMM to avoid speculative execution 171*eb94f1b6SKuppuswamy Sathyanarayanan * with VMM-controlled values. This needs to include all registers 172*eb94f1b6SKuppuswamy Sathyanarayanan * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15 173*eb94f1b6SKuppuswamy Sathyanarayanan * context will be restored. 174*eb94f1b6SKuppuswamy Sathyanarayanan */ 175*eb94f1b6SKuppuswamy Sathyanarayanan xor %r10d, %r10d 176*eb94f1b6SKuppuswamy Sathyanarayanan xor %r11d, %r11d 177*eb94f1b6SKuppuswamy Sathyanarayanan 178*eb94f1b6SKuppuswamy Sathyanarayanan /* Restore callee-saved GPRs as mandated by the x86_64 ABI */ 179*eb94f1b6SKuppuswamy Sathyanarayanan pop %r12 180*eb94f1b6SKuppuswamy Sathyanarayanan pop %r13 181*eb94f1b6SKuppuswamy Sathyanarayanan pop %r14 182*eb94f1b6SKuppuswamy Sathyanarayanan pop %r15 183*eb94f1b6SKuppuswamy Sathyanarayanan 184*eb94f1b6SKuppuswamy Sathyanarayanan FRAME_END 185*eb94f1b6SKuppuswamy Sathyanarayanan 186*eb94f1b6SKuppuswamy Sathyanarayanan retq 187*eb94f1b6SKuppuswamy Sathyanarayanan.Lpanic: 188*eb94f1b6SKuppuswamy Sathyanarayanan call __tdx_hypercall_failed 189*eb94f1b6SKuppuswamy Sathyanarayanan /* __tdx_hypercall_failed never returns */ 190*eb94f1b6SKuppuswamy Sathyanarayanan jmp .Lpanic 191*eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_END(__tdx_hypercall) 192