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/* GHCB GPA Register */
63#define GHCB_MSR_REG_GPA_REQ		0x012
64#define GHCB_MSR_REG_GPA_REQ_VAL(v)			\
65	/* GHCBData[63:12] */				\
66	(((u64)((v) & GENMASK_ULL(51, 0)) << 12) |	\
67	/* GHCBData[11:0] */				\
68	GHCB_MSR_REG_GPA_REQ)
69
70#define GHCB_MSR_REG_GPA_RESP		0x013
71#define GHCB_MSR_REG_GPA_RESP_VAL(v)			\
72	/* GHCBData[63:12] */				\
73	(((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
74
75/*
76 * SNP Page State Change Operation
77 *
78 * GHCBData[55:52] - Page operation:
79 *   0x0001	Page assignment, Private
80 *   0x0002	Page assignment, Shared
81 */
82enum psc_op {
83	SNP_PAGE_STATE_PRIVATE = 1,
84	SNP_PAGE_STATE_SHARED,
85};
86
87#define GHCB_MSR_PSC_REQ		0x014
88#define GHCB_MSR_PSC_REQ_GFN(gfn, op)			\
89	/* GHCBData[55:52] */				\
90	(((u64)((op) & 0xf) << 52) |			\
91	/* GHCBData[51:12] */				\
92	((u64)((gfn) & GENMASK_ULL(39, 0)) << 12) |	\
93	/* GHCBData[11:0] */				\
94	GHCB_MSR_PSC_REQ)
95
96#define GHCB_MSR_PSC_RESP		0x015
97#define GHCB_MSR_PSC_RESP_VAL(val)			\
98	/* GHCBData[63:32] */				\
99	(((u64)(val) & GENMASK_ULL(63, 32)) >> 32)
100
101/* GHCB Hypervisor Feature Request/Response */
102#define GHCB_MSR_HV_FT_REQ		0x080
103#define GHCB_MSR_HV_FT_RESP		0x081
104#define GHCB_MSR_HV_FT_POS		12
105#define GHCB_MSR_HV_FT_MASK		GENMASK_ULL(51, 0)
106#define GHCB_MSR_HV_FT_RESP_VAL(v)			\
107	/* GHCBData[63:12] */				\
108	(((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
109
110#define GHCB_HV_FT_SNP			BIT_ULL(0)
111#define GHCB_HV_FT_SNP_AP_CREATION	BIT_ULL(1)
112
113/*
114 * SNP Page State Change NAE event
115 *   The VMGEXIT_PSC_MAX_ENTRY determines the size of the PSC structure, which
116 *   is a local stack variable in set_pages_state(). Do not increase this value
117 *   without evaluating the impact to stack usage.
118 */
119#define VMGEXIT_PSC_MAX_ENTRY		64
120
121struct psc_hdr {
122	u16 cur_entry;
123	u16 end_entry;
124	u32 reserved;
125} __packed;
126
127struct psc_entry {
128	u64	cur_page	: 12,
129		gfn		: 40,
130		operation	: 4,
131		pagesize	: 1,
132		reserved	: 7;
133} __packed;
134
135struct snp_psc_desc {
136	struct psc_hdr hdr;
137	struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY];
138} __packed;
139
140#define GHCB_MSR_TERM_REQ		0x100
141#define GHCB_MSR_TERM_REASON_SET_POS	12
142#define GHCB_MSR_TERM_REASON_SET_MASK	0xf
143#define GHCB_MSR_TERM_REASON_POS	16
144#define GHCB_MSR_TERM_REASON_MASK	0xff
145
146#define GHCB_SEV_TERM_REASON(reason_set, reason_val)	\
147	/* GHCBData[15:12] */				\
148	(((((u64)reason_set) &  0xf) << 12) |		\
149	 /* GHCBData[23:16] */				\
150	((((u64)reason_val) & 0xff) << 16))
151
152/* Error codes from reason set 0 */
153#define SEV_TERM_SET_GEN		0
154#define GHCB_SEV_ES_GEN_REQ		0
155#define GHCB_SEV_ES_PROT_UNSUPPORTED	1
156#define GHCB_SNP_UNSUPPORTED		2
157
158/* Linux-specific reason codes (used with reason set 1) */
159#define SEV_TERM_SET_LINUX		1
160#define GHCB_TERM_REGISTER		0	/* GHCB GPA registration failure */
161#define GHCB_TERM_PSC			1	/* Page State Change failure */
162#define GHCB_TERM_PVALIDATE		2	/* Pvalidate failure */
163#define GHCB_TERM_NOT_VMPL0		3	/* SNP guest is not running at VMPL-0 */
164#define GHCB_TERM_CPUID			4	/* CPUID-validation failure */
165#define GHCB_TERM_CPUID_HV		5	/* CPUID failure during hypervisor fallback */
166
167#define GHCB_RESP_CODE(v)		((v) & GHCB_MSR_INFO_MASK)
168
169/*
170 * Error codes related to GHCB input that can be communicated back to the guest
171 * by setting the lower 32-bits of the GHCB SW_EXITINFO1 field to 2.
172 */
173#define GHCB_ERR_NOT_REGISTERED		1
174#define GHCB_ERR_INVALID_USAGE		2
175#define GHCB_ERR_INVALID_SCRATCH_AREA	3
176#define GHCB_ERR_MISSING_INPUT		4
177#define GHCB_ERR_INVALID_INPUT		5
178#define GHCB_ERR_INVALID_EVENT		6
179
180#endif
181