1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_SHARED_TDX_H |
3 | #define _ASM_X86_SHARED_TDX_H |
4 | |
5 | #include <linux/bits.h> |
6 | #include <linux/types.h> |
7 | |
8 | #define TDX_HYPERCALL_STANDARD 0 |
9 | |
10 | #define TDX_CPUID_LEAF_ID 0x21 |
11 | #define TDX_IDENT "IntelTDX " |
12 | |
13 | /* TDX module Call Leaf IDs */ |
14 | #define TDG_VP_VMCALL 0 |
15 | #define TDG_VP_INFO 1 |
16 | #define TDG_MR_RTMR_EXTEND 2 |
17 | #define TDG_VP_VEINFO_GET 3 |
18 | #define TDG_MR_REPORT 4 |
19 | #define TDG_MEM_PAGE_ACCEPT 6 |
20 | #define TDG_VM_RD 7 |
21 | #define TDG_VM_WR 8 |
22 | |
23 | /* TDX attributes */ |
24 | #define TDX_ATTR_DEBUG_BIT 0 |
25 | #define TDX_ATTR_DEBUG BIT_ULL(TDX_ATTR_DEBUG_BIT) |
26 | #define TDX_ATTR_HGS_PLUS_PROF_BIT 4 |
27 | #define TDX_ATTR_HGS_PLUS_PROF BIT_ULL(TDX_ATTR_HGS_PLUS_PROF_BIT) |
28 | #define TDX_ATTR_PERF_PROF_BIT 5 |
29 | #define TDX_ATTR_PERF_PROF BIT_ULL(TDX_ATTR_PERF_PROF_BIT) |
30 | #define TDX_ATTR_PMT_PROF_BIT 6 |
31 | #define TDX_ATTR_PMT_PROF BIT_ULL(TDX_ATTR_PMT_PROF_BIT) |
32 | #define TDX_ATTR_ICSSD_BIT 16 |
33 | #define TDX_ATTR_ICSSD BIT_ULL(TDX_ATTR_ICSSD_BIT) |
34 | #define TDX_ATTR_LASS_BIT 27 |
35 | #define TDX_ATTR_LASS BIT_ULL(TDX_ATTR_LASS_BIT) |
36 | #define TDX_ATTR_SEPT_VE_DISABLE_BIT 28 |
37 | #define TDX_ATTR_SEPT_VE_DISABLE BIT_ULL(TDX_ATTR_SEPT_VE_DISABLE_BIT) |
38 | #define TDX_ATTR_MIGRTABLE_BIT 29 |
39 | #define TDX_ATTR_MIGRTABLE BIT_ULL(TDX_ATTR_MIGRTABLE_BIT) |
40 | #define TDX_ATTR_PKS_BIT 30 |
41 | #define TDX_ATTR_PKS BIT_ULL(TDX_ATTR_PKS_BIT) |
42 | #define TDX_ATTR_KL_BIT 31 |
43 | #define TDX_ATTR_KL BIT_ULL(TDX_ATTR_KL_BIT) |
44 | #define TDX_ATTR_TPA_BIT 62 |
45 | #define TDX_ATTR_TPA BIT_ULL(TDX_ATTR_TPA_BIT) |
46 | #define TDX_ATTR_PERFMON_BIT 63 |
47 | #define TDX_ATTR_PERFMON BIT_ULL(TDX_ATTR_PERFMON_BIT) |
48 | |
49 | /* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */ |
50 | #define TDCS_CONFIG_FLAGS 0x1110000300000016 |
51 | #define TDCS_TD_CTLS 0x1110000300000017 |
52 | #define TDCS_NOTIFY_ENABLES 0x9100000000000010 |
53 | #define TDCS_TOPOLOGY_ENUM_CONFIGURED 0x9100000000000019 |
54 | |
55 | /* TDCS_CONFIG_FLAGS bits */ |
56 | #define TDCS_CONFIG_FLEXIBLE_PENDING_VE BIT_ULL(1) |
57 | |
58 | /* TDCS_TD_CTLS bits */ |
59 | #define TD_CTLS_PENDING_VE_DISABLE_BIT 0 |
60 | #define TD_CTLS_PENDING_VE_DISABLE BIT_ULL(TD_CTLS_PENDING_VE_DISABLE_BIT) |
61 | #define TD_CTLS_ENUM_TOPOLOGY_BIT 1 |
62 | #define TD_CTLS_ENUM_TOPOLOGY BIT_ULL(TD_CTLS_ENUM_TOPOLOGY_BIT) |
63 | #define TD_CTLS_VIRT_CPUID2_BIT 2 |
64 | #define TD_CTLS_VIRT_CPUID2 BIT_ULL(TD_CTLS_VIRT_CPUID2_BIT) |
65 | #define TD_CTLS_REDUCE_VE_BIT 3 |
66 | #define TD_CTLS_REDUCE_VE BIT_ULL(TD_CTLS_REDUCE_VE_BIT) |
67 | #define TD_CTLS_LOCK_BIT 63 |
68 | #define TD_CTLS_LOCK BIT_ULL(TD_CTLS_LOCK_BIT) |
69 | |
70 | /* TDX hypercall Leaf IDs */ |
71 | #define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 |
72 | #define TDVMCALL_MAP_GPA 0x10001 |
73 | #define TDVMCALL_GET_QUOTE 0x10002 |
74 | #define TDVMCALL_REPORT_FATAL_ERROR 0x10003 |
75 | |
76 | /* |
77 | * TDG.VP.VMCALL Status Codes (returned in R10) |
78 | */ |
79 | #define TDVMCALL_STATUS_SUCCESS 0x0000000000000000ULL |
80 | #define TDVMCALL_STATUS_RETRY 0x0000000000000001ULL |
81 | #define TDVMCALL_STATUS_INVALID_OPERAND 0x8000000000000000ULL |
82 | #define TDVMCALL_STATUS_ALIGN_ERROR 0x8000000000000002ULL |
83 | |
84 | /* |
85 | * Bitmasks of exposed registers (with VMM). |
86 | */ |
87 | #define TDX_RDX BIT(2) |
88 | #define TDX_RBX BIT(3) |
89 | #define TDX_RSI BIT(6) |
90 | #define TDX_RDI BIT(7) |
91 | #define TDX_R8 BIT(8) |
92 | #define TDX_R9 BIT(9) |
93 | #define TDX_R10 BIT(10) |
94 | #define TDX_R11 BIT(11) |
95 | #define TDX_R12 BIT(12) |
96 | #define TDX_R13 BIT(13) |
97 | #define TDX_R14 BIT(14) |
98 | #define TDX_R15 BIT(15) |
99 | |
100 | /* |
101 | * These registers are clobbered to hold arguments for each |
102 | * TDVMCALL. They are safe to expose to the VMM. |
103 | * Each bit in this mask represents a register ID. Bit field |
104 | * details can be found in TDX GHCI specification, section |
105 | * titled "TDCALL [TDG.VP.VMCALL] leaf". |
106 | */ |
107 | #define TDVMCALL_EXPOSE_REGS_MASK \ |
108 | (TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \ |
109 | TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15) |
110 | |
111 | /* TDX supported page sizes from the TDX module ABI. */ |
112 | #define TDX_PS_4K 0 |
113 | #define TDX_PS_2M 1 |
114 | #define TDX_PS_1G 2 |
115 | #define TDX_PS_NR (TDX_PS_1G + 1) |
116 | |
117 | #ifndef __ASSEMBLER__ |
118 | |
119 | #include <linux/compiler_attributes.h> |
120 | |
121 | /* |
122 | * Used in __tdcall*() to gather the input/output registers' values of the |
123 | * TDCALL instruction when requesting services from the TDX module. This is a |
124 | * software only structure and not part of the TDX module/VMM ABI |
125 | */ |
126 | struct tdx_module_args { |
127 | /* callee-clobbered */ |
128 | u64 rcx; |
129 | u64 rdx; |
130 | u64 r8; |
131 | u64 r9; |
132 | /* extra callee-clobbered */ |
133 | u64 r10; |
134 | u64 r11; |
135 | /* callee-saved + rdi/rsi */ |
136 | u64 r12; |
137 | u64 r13; |
138 | u64 r14; |
139 | u64 r15; |
140 | u64 rbx; |
141 | u64 rdi; |
142 | u64 rsi; |
143 | }; |
144 | |
145 | /* Used to communicate with the TDX module */ |
146 | u64 __tdcall(u64 fn, struct tdx_module_args *args); |
147 | u64 __tdcall_ret(u64 fn, struct tdx_module_args *args); |
148 | u64 __tdcall_saved_ret(u64 fn, struct tdx_module_args *args); |
149 | |
150 | /* Used to request services from the VMM */ |
151 | u64 __tdx_hypercall(struct tdx_module_args *args); |
152 | |
153 | /* |
154 | * Wrapper for standard use of __tdx_hypercall with no output aside from |
155 | * return code. |
156 | */ |
157 | static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15) |
158 | { |
159 | struct tdx_module_args args = { |
160 | .r10 = TDX_HYPERCALL_STANDARD, |
161 | .r11 = fn, |
162 | .r12 = r12, |
163 | .r13 = r13, |
164 | .r14 = r14, |
165 | .r15 = r15, |
166 | }; |
167 | |
168 | return __tdx_hypercall(args: &args); |
169 | } |
170 | |
171 | |
172 | /* Called from __tdx_hypercall() for unrecoverable failure */ |
173 | void __noreturn __tdx_hypercall_failed(void); |
174 | |
175 | bool tdx_accept_memory(phys_addr_t start, phys_addr_t end); |
176 | |
177 | /* |
178 | * The TDG.VP.VMCALL-Instruction-execution sub-functions are defined |
179 | * independently from but are currently matched 1:1 with VMX EXIT_REASONs. |
180 | * Reusing the KVM EXIT_REASON macros makes it easier to connect the host and |
181 | * guest sides of these calls. |
182 | */ |
183 | static __always_inline u64 hcall_func(u64 exit_reason) |
184 | { |
185 | return exit_reason; |
186 | } |
187 | |
188 | #endif /* !__ASSEMBLER__ */ |
189 | #endif /* _ASM_X86_SHARED_TDX_H */ |
190 | |