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