xref: /openbmc/linux/arch/x86/coco/tdx/tdcall.S (revision eb94f1b6)
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