xref: /openbmc/linux/arch/x86/coco/tdx/tdcall.S (revision de4c5bac)
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 */
16752d1330SKirill A. Shutemov#define TDX_RDX		BIT(2)
17752d1330SKirill A. Shutemov#define TDX_RBX		BIT(3)
18752d1330SKirill A. Shutemov#define TDX_RSI		BIT(6)
19752d1330SKirill A. Shutemov#define TDX_RDI		BIT(7)
20752d1330SKirill A. Shutemov#define TDX_R8		BIT(8)
21752d1330SKirill A. Shutemov#define TDX_R9		BIT(9)
22eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R10		BIT(10)
23eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R11		BIT(11)
24eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R12		BIT(12)
25eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R13		BIT(13)
26eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R14		BIT(14)
27eb94f1b6SKuppuswamy Sathyanarayanan#define TDX_R15		BIT(15)
28eb94f1b6SKuppuswamy Sathyanarayanan
29eb94f1b6SKuppuswamy Sathyanarayanan/*
30eb94f1b6SKuppuswamy Sathyanarayanan * These registers are clobbered to hold arguments for each
31eb94f1b6SKuppuswamy Sathyanarayanan * TDVMCALL. They are safe to expose to the VMM.
32eb94f1b6SKuppuswamy Sathyanarayanan * Each bit in this mask represents a register ID. Bit field
33eb94f1b6SKuppuswamy Sathyanarayanan * details can be found in TDX GHCI specification, section
34eb94f1b6SKuppuswamy Sathyanarayanan * titled "TDCALL [TDG.VP.VMCALL] leaf".
35eb94f1b6SKuppuswamy Sathyanarayanan */
36752d1330SKirill A. Shutemov#define TDVMCALL_EXPOSE_REGS_MASK	\
37752d1330SKirill A. Shutemov	( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8  | TDX_R9  | \
38752d1330SKirill A. Shutemov	  TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 )
39eb94f1b6SKuppuswamy Sathyanarayanan
40c3982c1aSPeter Zijlstra.section .noinstr.text, "ax"
41c3982c1aSPeter Zijlstra
42eb94f1b6SKuppuswamy Sathyanarayanan/*
43eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_module_call()  - Used by TDX guests to request services from
44eb94f1b6SKuppuswamy Sathyanarayanan * the TDX module (does not include VMM services) using TDCALL instruction.
45eb94f1b6SKuppuswamy Sathyanarayanan *
46eb94f1b6SKuppuswamy Sathyanarayanan * Transforms function call register arguments into the TDCALL register ABI.
47eb94f1b6SKuppuswamy Sathyanarayanan * After TDCALL operation, TDX module output is saved in @out (if it is
48eb94f1b6SKuppuswamy Sathyanarayanan * provided by the user).
49eb94f1b6SKuppuswamy Sathyanarayanan *
50eb94f1b6SKuppuswamy Sathyanarayanan *-------------------------------------------------------------------------
51eb94f1b6SKuppuswamy Sathyanarayanan * TDCALL ABI:
52eb94f1b6SKuppuswamy Sathyanarayanan *-------------------------------------------------------------------------
53eb94f1b6SKuppuswamy Sathyanarayanan * Input Registers:
54eb94f1b6SKuppuswamy Sathyanarayanan *
55eb94f1b6SKuppuswamy Sathyanarayanan * RAX                 - TDCALL Leaf number.
56eb94f1b6SKuppuswamy Sathyanarayanan * RCX,RDX,R8-R9       - TDCALL Leaf specific input registers.
57eb94f1b6SKuppuswamy Sathyanarayanan *
58eb94f1b6SKuppuswamy Sathyanarayanan * Output Registers:
59eb94f1b6SKuppuswamy Sathyanarayanan *
60eb94f1b6SKuppuswamy Sathyanarayanan * RAX                 - TDCALL instruction error code.
61eb94f1b6SKuppuswamy Sathyanarayanan * RCX,RDX,R8-R11      - TDCALL Leaf specific output registers.
62eb94f1b6SKuppuswamy Sathyanarayanan *
63eb94f1b6SKuppuswamy Sathyanarayanan *-------------------------------------------------------------------------
64eb94f1b6SKuppuswamy Sathyanarayanan *
65eb94f1b6SKuppuswamy Sathyanarayanan * __tdx_module_call() function ABI:
66eb94f1b6SKuppuswamy Sathyanarayanan *
67eb94f1b6SKuppuswamy Sathyanarayanan * @fn  (RDI)          - TDCALL Leaf ID,    moved to RAX
68eb94f1b6SKuppuswamy Sathyanarayanan * @rcx (RSI)          - Input parameter 1, moved to RCX
69eb94f1b6SKuppuswamy Sathyanarayanan * @rdx (RDX)          - Input parameter 2, moved to RDX
70eb94f1b6SKuppuswamy Sathyanarayanan * @r8  (RCX)          - Input parameter 3, moved to R8
71eb94f1b6SKuppuswamy Sathyanarayanan * @r9  (R8)           - Input parameter 4, moved to R9
72eb94f1b6SKuppuswamy Sathyanarayanan *
73eb94f1b6SKuppuswamy Sathyanarayanan * @out (R9)           - struct tdx_module_output pointer
74eb94f1b6SKuppuswamy Sathyanarayanan *                       stored temporarily in R12 (not
75eb94f1b6SKuppuswamy Sathyanarayanan *                       shared with the TDX module). It
76eb94f1b6SKuppuswamy Sathyanarayanan *                       can be NULL.
77eb94f1b6SKuppuswamy Sathyanarayanan *
78eb94f1b6SKuppuswamy Sathyanarayanan * Return status of TDCALL via RAX.
79eb94f1b6SKuppuswamy Sathyanarayanan */
80eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_START(__tdx_module_call)
81eb94f1b6SKuppuswamy Sathyanarayanan	FRAME_BEGIN
82eb94f1b6SKuppuswamy Sathyanarayanan	TDX_MODULE_CALL host=0
83eb94f1b6SKuppuswamy Sathyanarayanan	FRAME_END
84c796f021SPeter Zijlstra	RET
85eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_END(__tdx_module_call)
86eb94f1b6SKuppuswamy Sathyanarayanan
87eb94f1b6SKuppuswamy Sathyanarayanan/*
887a3a4018SKirill A. Shutemov * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
897a3a4018SKirill A. Shutemov * instruction
90eb94f1b6SKuppuswamy Sathyanarayanan *
91eb94f1b6SKuppuswamy Sathyanarayanan * Transforms values in  function call argument struct tdx_hypercall_args @args
92eb94f1b6SKuppuswamy Sathyanarayanan * into the TDCALL register ABI. After TDCALL operation, VMM output is saved
937a3a4018SKirill A. Shutemov * back in @args, if \ret is 1.
94eb94f1b6SKuppuswamy Sathyanarayanan *
95eb94f1b6SKuppuswamy Sathyanarayanan *-------------------------------------------------------------------------
96eb94f1b6SKuppuswamy Sathyanarayanan * TD VMCALL ABI:
97eb94f1b6SKuppuswamy Sathyanarayanan *-------------------------------------------------------------------------
98eb94f1b6SKuppuswamy Sathyanarayanan *
99eb94f1b6SKuppuswamy Sathyanarayanan * Input Registers:
100eb94f1b6SKuppuswamy Sathyanarayanan *
101eb94f1b6SKuppuswamy Sathyanarayanan * RAX                 - TDCALL instruction leaf number (0 - TDG.VP.VMCALL)
102eb94f1b6SKuppuswamy Sathyanarayanan * RCX                 - BITMAP which controls which part of TD Guest GPR
103eb94f1b6SKuppuswamy Sathyanarayanan *                       is passed as-is to the VMM and back.
104eb94f1b6SKuppuswamy Sathyanarayanan * R10                 - Set 0 to indicate TDCALL follows standard TDX ABI
105eb94f1b6SKuppuswamy Sathyanarayanan *                       specification. Non zero value indicates vendor
106eb94f1b6SKuppuswamy Sathyanarayanan *                       specific ABI.
107eb94f1b6SKuppuswamy Sathyanarayanan * R11                 - VMCALL sub function number
1087a3a4018SKirill A. Shutemov * RBX, RDX, RDI, RSI  - Used to pass VMCALL sub function specific arguments.
109eb94f1b6SKuppuswamy Sathyanarayanan * R8-R9, R12-R15      - Same as above.
110eb94f1b6SKuppuswamy Sathyanarayanan *
111eb94f1b6SKuppuswamy Sathyanarayanan * Output Registers:
112eb94f1b6SKuppuswamy Sathyanarayanan *
113eb94f1b6SKuppuswamy Sathyanarayanan * RAX                 - TDCALL instruction status (Not related to hypercall
114eb94f1b6SKuppuswamy Sathyanarayanan *                        output).
1157a3a4018SKirill A. Shutemov * RBX, RDX, RDI, RSI  - Hypercall sub function specific output values.
1167a3a4018SKirill A. Shutemov * R8-R15              - Same as above.
117eb94f1b6SKuppuswamy Sathyanarayanan *
118eb94f1b6SKuppuswamy Sathyanarayanan */
1197a3a4018SKirill A. Shutemov.macro TDX_HYPERCALL ret:req
120eb94f1b6SKuppuswamy Sathyanarayanan	FRAME_BEGIN
121eb94f1b6SKuppuswamy Sathyanarayanan
122eb94f1b6SKuppuswamy Sathyanarayanan	/* Save callee-saved GPRs as mandated by the x86_64 ABI */
123eb94f1b6SKuppuswamy Sathyanarayanan	push %r15
124eb94f1b6SKuppuswamy Sathyanarayanan	push %r14
125eb94f1b6SKuppuswamy Sathyanarayanan	push %r13
126eb94f1b6SKuppuswamy Sathyanarayanan	push %r12
127752d1330SKirill A. Shutemov	push %rbx
128c30c4b25SKirill A. Shutemov
1297a3a4018SKirill A. Shutemov	/* Free RDI to be used as TDVMCALL arguments */
130c30c4b25SKirill A. Shutemov	movq %rdi, %rax
131c30c4b25SKirill A. Shutemov
132c30c4b25SKirill A. Shutemov	/* Copy hypercall registers from arg struct: */
133752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_r8(%rax),  %r8
134752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_r9(%rax),  %r9
135c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r10(%rax), %r10
136c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r11(%rax), %r11
137c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r12(%rax), %r12
138c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r13(%rax), %r13
139c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r14(%rax), %r14
140c30c4b25SKirill A. Shutemov	movq TDX_HYPERCALL_r15(%rax), %r15
141752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_rdi(%rax), %rdi
142752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_rsi(%rax), %rsi
143752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_rbx(%rax), %rbx
144752d1330SKirill A. Shutemov	movq TDX_HYPERCALL_rdx(%rax), %rdx
145c30c4b25SKirill A. Shutemov
146c30c4b25SKirill A. Shutemov	push %rax
147eb94f1b6SKuppuswamy Sathyanarayanan
148eb94f1b6SKuppuswamy Sathyanarayanan	/* Mangle function call ABI into TDCALL ABI: */
149eb94f1b6SKuppuswamy Sathyanarayanan	/* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */
150eb94f1b6SKuppuswamy Sathyanarayanan	xor %eax, %eax
151eb94f1b6SKuppuswamy Sathyanarayanan
152eb94f1b6SKuppuswamy Sathyanarayanan	movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx
153eb94f1b6SKuppuswamy Sathyanarayanan
154eb94f1b6SKuppuswamy Sathyanarayanan	tdcall
155eb94f1b6SKuppuswamy Sathyanarayanan
156eb94f1b6SKuppuswamy Sathyanarayanan	/*
1573543f883SKirill A. Shutemov	 * RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that
158eb94f1b6SKuppuswamy Sathyanarayanan	 * something has gone horribly wrong with the TDX module.
159eb94f1b6SKuppuswamy Sathyanarayanan	 *
160eb94f1b6SKuppuswamy Sathyanarayanan	 * The return status of the hypercall operation is in a separate
161eb94f1b6SKuppuswamy Sathyanarayanan	 * register (in R10). Hypercall errors are a part of normal operation
162eb94f1b6SKuppuswamy Sathyanarayanan	 * and are handled by callers.
163eb94f1b6SKuppuswamy Sathyanarayanan	 */
164eb94f1b6SKuppuswamy Sathyanarayanan	testq %rax, %rax
1657a3a4018SKirill A. Shutemov	jne .Lpanic\@
166eb94f1b6SKuppuswamy Sathyanarayanan
167c30c4b25SKirill A. Shutemov	pop %rax
168c30c4b25SKirill A. Shutemov
1697a3a4018SKirill A. Shutemov	.if \ret
170752d1330SKirill A. Shutemov	movq %r8,  TDX_HYPERCALL_r8(%rax)
171752d1330SKirill A. Shutemov	movq %r9,  TDX_HYPERCALL_r9(%rax)
172c30c4b25SKirill A. Shutemov	movq %r10, TDX_HYPERCALL_r10(%rax)
173c30c4b25SKirill A. Shutemov	movq %r11, TDX_HYPERCALL_r11(%rax)
174c30c4b25SKirill A. Shutemov	movq %r12, TDX_HYPERCALL_r12(%rax)
175c30c4b25SKirill A. Shutemov	movq %r13, TDX_HYPERCALL_r13(%rax)
176c30c4b25SKirill A. Shutemov	movq %r14, TDX_HYPERCALL_r14(%rax)
177c30c4b25SKirill A. Shutemov	movq %r15, TDX_HYPERCALL_r15(%rax)
178752d1330SKirill A. Shutemov	movq %rdi, TDX_HYPERCALL_rdi(%rax)
179752d1330SKirill A. Shutemov	movq %rsi, TDX_HYPERCALL_rsi(%rax)
180752d1330SKirill A. Shutemov	movq %rbx, TDX_HYPERCALL_rbx(%rax)
181752d1330SKirill A. Shutemov	movq %rdx, TDX_HYPERCALL_rdx(%rax)
1827a3a4018SKirill A. Shutemov	.endif
1837a3a4018SKirill A. Shutemov
184eb94f1b6SKuppuswamy Sathyanarayanan	/* TDVMCALL leaf return code is in R10 */
185eb94f1b6SKuppuswamy Sathyanarayanan	movq %r10, %rax
186eb94f1b6SKuppuswamy Sathyanarayanan
187eb94f1b6SKuppuswamy Sathyanarayanan	/*
188eb94f1b6SKuppuswamy Sathyanarayanan	 * Zero out registers exposed to the VMM to avoid speculative execution
189eb94f1b6SKuppuswamy Sathyanarayanan	 * with VMM-controlled values. This needs to include all registers
190752d1330SKirill A. Shutemov	 * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which
191752d1330SKirill A. Shutemov	 * will be restored.
192eb94f1b6SKuppuswamy Sathyanarayanan	 */
193752d1330SKirill A. Shutemov	xor %r8d,  %r8d
194752d1330SKirill A. Shutemov	xor %r9d,  %r9d
195eb94f1b6SKuppuswamy Sathyanarayanan	xor %r10d, %r10d
196eb94f1b6SKuppuswamy Sathyanarayanan	xor %r11d, %r11d
197752d1330SKirill A. Shutemov	xor %rdi,  %rdi
198*de4c5bacSKai Huang	xor %rsi,  %rsi
199752d1330SKirill A. Shutemov	xor %rdx,  %rdx
200eb94f1b6SKuppuswamy Sathyanarayanan
201eb94f1b6SKuppuswamy Sathyanarayanan	/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
202752d1330SKirill A. Shutemov	pop %rbx
203eb94f1b6SKuppuswamy Sathyanarayanan	pop %r12
204eb94f1b6SKuppuswamy Sathyanarayanan	pop %r13
205eb94f1b6SKuppuswamy Sathyanarayanan	pop %r14
206eb94f1b6SKuppuswamy Sathyanarayanan	pop %r15
207eb94f1b6SKuppuswamy Sathyanarayanan
208eb94f1b6SKuppuswamy Sathyanarayanan	FRAME_END
209eb94f1b6SKuppuswamy Sathyanarayanan
210c796f021SPeter Zijlstra	RET
2117a3a4018SKirill A. Shutemov.Lpanic\@:
212eb94f1b6SKuppuswamy Sathyanarayanan	call __tdx_hypercall_failed
213eb94f1b6SKuppuswamy Sathyanarayanan	/* __tdx_hypercall_failed never returns */
2145af14c29SBorislav Petkov	REACHABLE
2157a3a4018SKirill A. Shutemov	jmp .Lpanic\@
2167a3a4018SKirill A. Shutemov.endm
2177a3a4018SKirill A. Shutemov
2187a3a4018SKirill A. Shutemov/*
2197a3a4018SKirill A. Shutemov *
2207a3a4018SKirill A. Shutemov * __tdx_hypercall() function ABI:
2217a3a4018SKirill A. Shutemov *
2227a3a4018SKirill A. Shutemov * @args  (RDI)        - struct tdx_hypercall_args for input
2237a3a4018SKirill A. Shutemov *
2247a3a4018SKirill A. Shutemov * On successful completion, return the hypercall error code.
2257a3a4018SKirill A. Shutemov */
2267a3a4018SKirill A. ShutemovSYM_FUNC_START(__tdx_hypercall)
2277a3a4018SKirill A. Shutemov	TDX_HYPERCALL ret=0
228eb94f1b6SKuppuswamy SathyanarayananSYM_FUNC_END(__tdx_hypercall)
2297a3a4018SKirill A. Shutemov
2307a3a4018SKirill A. Shutemov/*
2317a3a4018SKirill A. Shutemov *
2327a3a4018SKirill A. Shutemov * __tdx_hypercall_ret() function ABI:
2337a3a4018SKirill A. Shutemov *
2347a3a4018SKirill A. Shutemov * @args  (RDI)        - struct tdx_hypercall_args for input and output
2357a3a4018SKirill A. Shutemov *
2367a3a4018SKirill A. Shutemov * On successful completion, return the hypercall error code.
2377a3a4018SKirill A. Shutemov */
2387a3a4018SKirill A. ShutemovSYM_FUNC_START(__tdx_hypercall_ret)
2397a3a4018SKirill A. Shutemov	TDX_HYPERCALL ret=1
2407a3a4018SKirill A. ShutemovSYM_FUNC_END(__tdx_hypercall_ret)
241