xref: /openbmc/linux/arch/x86/virt/vmx/tdx/tdxcall.S (revision cd1e565a5b7fa60c349ca8a16db1e61715fe8230)
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <asm/asm-offsets.h>
3#include <asm/frame.h>
4#include <asm/tdx.h>
5
6/*
7 * TDCALL and SEAMCALL are supported in Binutils >= 2.36.
8 */
9#define tdcall		.byte 0x66,0x0f,0x01,0xcc
10#define seamcall	.byte 0x66,0x0f,0x01,0xcf
11
12/*
13 * TDX_MODULE_CALL - common helper macro for both
14 *                 TDCALL and SEAMCALL instructions.
15 *
16 * TDCALL   - used by TDX guests to make requests to the
17 *            TDX module and hypercalls to the VMM.
18 * SEAMCALL - used by TDX hosts to make requests to the
19 *            TDX module.
20 *
21 *-------------------------------------------------------------------------
22 * TDCALL/SEAMCALL ABI:
23 *-------------------------------------------------------------------------
24 * Input Registers:
25 *
26 * RAX                 - TDCALL/SEAMCALL Leaf number.
27 * RCX,RDX,R8-R11      - TDCALL/SEAMCALL Leaf specific input registers.
28 *
29 * Output Registers:
30 *
31 * RAX                 - TDCALL/SEAMCALL instruction error code.
32 * RCX,RDX,R8-R11      - TDCALL/SEAMCALL Leaf specific output registers.
33 *
34 *-------------------------------------------------------------------------
35 */
36.macro TDX_MODULE_CALL host:req ret=0
37	FRAME_BEGIN
38
39	/* Move Leaf ID to RAX */
40	mov %rdi, %rax
41
42	/* Move other input regs from 'struct tdx_module_args' */
43	movq	TDX_MODULE_rcx(%rsi), %rcx
44	movq	TDX_MODULE_rdx(%rsi), %rdx
45	movq	TDX_MODULE_r8(%rsi),  %r8
46	movq	TDX_MODULE_r9(%rsi),  %r9
47	movq	TDX_MODULE_r10(%rsi), %r10
48	movq	TDX_MODULE_r11(%rsi), %r11
49
50.if \host
51	seamcall
52	/*
53	 * SEAMCALL instruction is essentially a VMExit from VMX root
54	 * mode to SEAM VMX root mode.  VMfailInvalid (CF=1) indicates
55	 * that the targeted SEAM firmware is not loaded or disabled,
56	 * or P-SEAMLDR is busy with another SEAMCALL.  %rax is not
57	 * changed in this case.
58	 *
59	 * Set %rax to TDX_SEAMCALL_VMFAILINVALID for VMfailInvalid.
60	 * This value will never be used as actual SEAMCALL error code as
61	 * it is from the Reserved status code class.
62	 */
63	jc .Lseamcall_vmfailinvalid\@
64.else
65	tdcall
66.endif
67
68.if \ret
69	/* Copy output registers to the structure */
70	movq %rcx, TDX_MODULE_rcx(%rsi)
71	movq %rdx, TDX_MODULE_rdx(%rsi)
72	movq %r8,  TDX_MODULE_r8(%rsi)
73	movq %r9,  TDX_MODULE_r9(%rsi)
74	movq %r10, TDX_MODULE_r10(%rsi)
75	movq %r11, TDX_MODULE_r11(%rsi)
76.endif
77
78.if \host
79.Lout\@:
80.endif
81	FRAME_END
82	RET
83
84.if \host
85.Lseamcall_vmfailinvalid\@:
86	mov $TDX_SEAMCALL_VMFAILINVALID, %rax
87	jmp .Lout\@
88.endif	/* \host */
89
90.endm
91