1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * AMD SEV header common between the guest and the hypervisor.
4 *
5 * Author: Brijesh Singh <brijesh.singh@amd.com>
6 */
7
8#ifndef __ASM_X86_SEV_COMMON_H
9#define __ASM_X86_SEV_COMMON_H
10
11#define GHCB_MSR_INFO_POS 0
12#define GHCB_DATA_LOW 12
13#define GHCB_MSR_INFO_MASK (BIT_ULL(GHCB_DATA_LOW) - 1)
14
15#define GHCB_DATA(v) \
16 (((unsigned long)(v) & ~GHCB_MSR_INFO_MASK) >> GHCB_DATA_LOW)
17
18/* SEV Information Request/Response */
19#define GHCB_MSR_SEV_INFO_RESP 0x001
20#define GHCB_MSR_SEV_INFO_REQ 0x002
21
22#define GHCB_MSR_SEV_INFO(_max, _min, _cbit) \
23 /* GHCBData[63:48] */ \
24 ((((_max) & 0xffff) << 48) | \
25 /* GHCBData[47:32] */ \
26 (((_min) & 0xffff) << 32) | \
27 /* GHCBData[31:24] */ \
28 (((_cbit) & 0xff) << 24) | \
29 GHCB_MSR_SEV_INFO_RESP)
30
31#define GHCB_MSR_INFO(v) ((v) & 0xfffUL)
32#define GHCB_MSR_PROTO_MAX(v) (((v) >> 48) & 0xffff)
33#define GHCB_MSR_PROTO_MIN(v) (((v) >> 32) & 0xffff)
34
35/* CPUID Request/Response */
36#define GHCB_MSR_CPUID_REQ 0x004
37#define GHCB_MSR_CPUID_RESP 0x005
38#define GHCB_MSR_CPUID_FUNC_POS 32
39#define GHCB_MSR_CPUID_FUNC_MASK 0xffffffff
40#define GHCB_MSR_CPUID_VALUE_POS 32
41#define GHCB_MSR_CPUID_VALUE_MASK 0xffffffff
42#define GHCB_MSR_CPUID_REG_POS 30
43#define GHCB_MSR_CPUID_REG_MASK 0x3
44#define GHCB_CPUID_REQ_EAX 0
45#define GHCB_CPUID_REQ_EBX 1
46#define GHCB_CPUID_REQ_ECX 2
47#define GHCB_CPUID_REQ_EDX 3
48#define GHCB_CPUID_REQ(fn, reg) \
49 /* GHCBData[11:0] */ \
50 (GHCB_MSR_CPUID_REQ | \
51 /* GHCBData[31:12] */ \
52 (((unsigned long)(reg) & 0x3) << 30) | \
53 /* GHCBData[63:32] */ \
54 (((unsigned long)fn) << 32))
55
56/* AP Reset Hold */
57#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
58#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
59#define GHCB_MSR_AP_RESET_HOLD_RESULT_POS 12
60#define GHCB_MSR_AP_RESET_HOLD_RESULT_MASK GENMASK_ULL(51, 0)
61
62/* Preferred GHCB GPA Request */
63#define GHCB_MSR_PREF_GPA_REQ 0x010
64#define GHCB_MSR_GPA_VALUE_POS 12
65#define GHCB_MSR_GPA_VALUE_MASK GENMASK_ULL(51, 0)
66
67#define GHCB_MSR_PREF_GPA_RESP 0x011
68#define GHCB_MSR_PREF_GPA_NONE 0xfffffffffffff
69
70/* GHCB GPA Register */
71#define GHCB_MSR_REG_GPA_REQ 0x012
72#define GHCB_MSR_REG_GPA_REQ_VAL(v) \
73 /* GHCBData[63:12] */ \
74 (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \
75 /* GHCBData[11:0] */ \
76 GHCB_MSR_REG_GPA_REQ)
77
78#define GHCB_MSR_REG_GPA_RESP 0x013
79#define GHCB_MSR_REG_GPA_RESP_VAL(v) \
80 /* GHCBData[63:12] */ \
81 (((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
82
83/*
84 * SNP Page State Change Operation
85 *
86 * GHCBData[55:52] - Page operation:
87 * 0x0001 Page assignment, Private
88 * 0x0002 Page assignment, Shared
89 */
90enum psc_op {
91 SNP_PAGE_STATE_PRIVATE = 1,
92 SNP_PAGE_STATE_SHARED,
93};
94
95#define GHCB_MSR_PSC_REQ 0x014
96#define GHCB_MSR_PSC_REQ_GFN(gfn, op) \
97 /* GHCBData[55:52] */ \
98 (((u64)((op) & 0xf) << 52) | \
99 /* GHCBData[51:12] */ \
100 ((u64)((gfn) & GENMASK_ULL(39, 0)) << 12) | \
101 /* GHCBData[11:0] */ \
102 GHCB_MSR_PSC_REQ)
103
104#define GHCB_MSR_PSC_REQ_TO_GFN(msr) (((msr) & GENMASK_ULL(51, 12)) >> 12)
105#define GHCB_MSR_PSC_REQ_TO_OP(msr) (((msr) & GENMASK_ULL(55, 52)) >> 52)
106
107#define GHCB_MSR_PSC_RESP 0x015
108#define GHCB_MSR_PSC_RESP_VAL(val) \
109 /* GHCBData[63:32] */ \
110 (((u64)(val) & GENMASK_ULL(63, 32)) >> 32)
111
112/* Set highest bit as a generic error response */
113#define GHCB_MSR_PSC_RESP_ERROR (BIT_ULL(63) | GHCB_MSR_PSC_RESP)
114
115/* GHCB Run at VMPL Request/Response */
116#define GHCB_MSR_VMPL_REQ 0x016
117#define GHCB_MSR_VMPL_REQ_LEVEL(v) \
118 /* GHCBData[39:32] */ \
119 ((((u64)(v) & GENMASK_ULL(7, 0)) << 32) | \
120 /* GHCBDdata[11:0] */ \
121 GHCB_MSR_VMPL_REQ)
122
123#define GHCB_MSR_VMPL_RESP 0x017
124#define GHCB_MSR_VMPL_RESP_VAL(v) \
125 /* GHCBData[63:32] */ \
126 (((u64)(v) & GENMASK_ULL(63, 32)) >> 32)
127
128/* GHCB Hypervisor Feature Request/Response */
129#define GHCB_MSR_HV_FT_REQ 0x080
130#define GHCB_MSR_HV_FT_RESP 0x081
131#define GHCB_MSR_HV_FT_POS 12
132#define GHCB_MSR_HV_FT_MASK GENMASK_ULL(51, 0)
133#define GHCB_MSR_HV_FT_RESP_VAL(v) \
134 /* GHCBData[63:12] */ \
135 (((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
136
137#define GHCB_HV_FT_SNP BIT_ULL(0)
138#define GHCB_HV_FT_SNP_AP_CREATION BIT_ULL(1)
139#define GHCB_HV_FT_SNP_MULTI_VMPL BIT_ULL(5)
140
141/*
142 * SNP Page State Change NAE event
143 * The VMGEXIT_PSC_MAX_ENTRY determines the size of the PSC structure, which
144 * is a local stack variable in set_pages_state(). Do not increase this value
145 * without evaluating the impact to stack usage.
146 *
147 * Use VMGEXIT_PSC_MAX_COUNT in cases where the actual GHCB-defined max value
148 * is needed, such as when processing GHCB requests on the hypervisor side.
149 */
150#define VMGEXIT_PSC_MAX_ENTRY 64
151#define VMGEXIT_PSC_MAX_COUNT 253
152
153#define VMGEXIT_PSC_ERROR_GENERIC (0x100UL << 32)
154#define VMGEXIT_PSC_ERROR_INVALID_HDR ((1UL << 32) | 1)
155#define VMGEXIT_PSC_ERROR_INVALID_ENTRY ((1UL << 32) | 2)
156
157#define VMGEXIT_PSC_OP_PRIVATE 1
158#define VMGEXIT_PSC_OP_SHARED 2
159
160struct psc_hdr {
161 u16 cur_entry;
162 u16 end_entry;
163 u32 reserved;
164} __packed;
165
166struct psc_entry {
167 u64 cur_page : 12,
168 gfn : 40,
169 operation : 4,
170 pagesize : 1,
171 reserved : 7;
172} __packed;
173
174struct snp_psc_desc {
175 struct psc_hdr hdr;
176 struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY];
177} __packed;
178
179#define GHCB_MSR_TERM_REQ 0x100
180#define GHCB_MSR_TERM_REASON_SET_POS 12
181#define GHCB_MSR_TERM_REASON_SET_MASK 0xf
182#define GHCB_MSR_TERM_REASON_POS 16
183#define GHCB_MSR_TERM_REASON_MASK 0xff
184
185#define GHCB_SEV_TERM_REASON(reason_set, reason_val) \
186 /* GHCBData[15:12] */ \
187 (((((u64)reason_set) & 0xf) << 12) | \
188 /* GHCBData[23:16] */ \
189 ((((u64)reason_val) & 0xff) << 16))
190
191/* Error codes from reason set 0 */
192#define SEV_TERM_SET_GEN 0
193#define GHCB_SEV_ES_GEN_REQ 0
194#define GHCB_SEV_ES_PROT_UNSUPPORTED 1
195#define GHCB_SNP_UNSUPPORTED 2
196
197/* Linux-specific reason codes (used with reason set 1) */
198#define SEV_TERM_SET_LINUX 1
199#define GHCB_TERM_REGISTER 0 /* GHCB GPA registration failure */
200#define GHCB_TERM_PSC 1 /* Page State Change failure */
201#define GHCB_TERM_PVALIDATE 2 /* Pvalidate failure */
202#define GHCB_TERM_NOT_VMPL0 3 /* SNP guest is not running at VMPL-0 */
203#define GHCB_TERM_CPUID 4 /* CPUID-validation failure */
204#define GHCB_TERM_CPUID_HV 5 /* CPUID failure during hypervisor fallback */
205#define GHCB_TERM_SECRETS_PAGE 6 /* Secrets page failure */
206#define GHCB_TERM_NO_SVSM 7 /* SVSM is not advertised in the secrets page */
207#define GHCB_TERM_SVSM_VMPL0 8 /* SVSM is present but has set VMPL to 0 */
208#define GHCB_TERM_SVSM_CAA 9 /* SVSM is present but CAA is not page aligned */
209#define GHCB_TERM_SECURE_TSC 10 /* Secure TSC initialization failed */
210#define GHCB_TERM_SVSM_CA_REMAP_FAIL 11 /* SVSM is present but CA could not be remapped */
211#define GHCB_TERM_SAVIC_FAIL 12 /* Secure AVIC-specific failure */
212
213#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
214
215/*
216 * GHCB-defined return codes that are communicated back to the guest via
217 * SW_EXITINFO1.
218 */
219#define GHCB_HV_RESP_NO_ACTION 0
220#define GHCB_HV_RESP_ISSUE_EXCEPTION 1
221#define GHCB_HV_RESP_MALFORMED_INPUT 2
222
223/*
224 * GHCB-defined sub-error codes for malformed input (see above) that are
225 * communicated back to the guest via SW_EXITINFO2[31:0].
226 */
227#define GHCB_ERR_NOT_REGISTERED 1
228#define GHCB_ERR_INVALID_USAGE 2
229#define GHCB_ERR_INVALID_SCRATCH_AREA 3
230#define GHCB_ERR_MISSING_INPUT 4
231#define GHCB_ERR_INVALID_INPUT 5
232#define GHCB_ERR_INVALID_EVENT 6
233
234struct sev_config {
235 __u64 debug : 1,
236
237 /*
238 * Indicates when the per-CPU GHCB has been created and registered
239 * and thus can be used by the BSP instead of the early boot GHCB.
240 *
241 * For APs, the per-CPU GHCB is created before they are started
242 * and registered upon startup, so this flag can be used globally
243 * for the BSP and APs.
244 */
245 ghcbs_initialized : 1,
246
247 /*
248 * Indicates when the per-CPU SVSM CA is to be used instead of the
249 * boot SVSM CA.
250 *
251 * For APs, the per-CPU SVSM CA is created as part of the AP
252 * bringup, so this flag can be used globally for the BSP and APs.
253 */
254 use_cas : 1,
255
256 __reserved : 61;
257};
258
259extern struct sev_config sev_cfg;
260
261#endif
262