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