xref: /netbsd-src/sys/dev/nvmm/x86/nvmm_x86.h (revision 222afabb3beb2ea01385ebeec5f5183940ea3cbe)
1 /*	$NetBSD: nvmm_x86.h,v 1.21 2021/03/26 15:59:53 reinoud Exp $	*/
2 
3 /*
4  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
5  * All rights reserved.
6  *
7  * This code is part of the NVMM hypervisor.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #ifndef _NVMM_X86_H_
32 #define _NVMM_X86_H_
33 
34 /* -------------------------------------------------------------------------- */
35 
36 #ifndef ASM_NVMM
37 
38 struct nvmm_x86_exit_memory {
39 	int prot;
40 	gpaddr_t gpa;
41 	uint8_t inst_len;
42 	uint8_t inst_bytes[15];
43 };
44 
45 struct nvmm_x86_exit_io {
46 	bool in;
47 	uint16_t port;
48 	int8_t seg;
49 	uint8_t address_size;
50 	uint8_t operand_size;
51 	bool rep;
52 	bool str;
53 	uint64_t npc;
54 };
55 
56 struct nvmm_x86_exit_rdmsr {
57 	uint32_t msr;
58 	uint64_t npc;
59 };
60 
61 struct nvmm_x86_exit_wrmsr {
62 	uint32_t msr;
63 	uint64_t val;
64 	uint64_t npc;
65 };
66 
67 struct nvmm_x86_exit_insn {
68 	uint64_t npc;
69 };
70 
71 struct nvmm_x86_exit_invalid {
72 	uint64_t hwcode;
73 };
74 
75 /* Generic. */
76 #define NVMM_VCPU_EXIT_NONE		0x0000000000000000ULL
77 #define NVMM_VCPU_EXIT_STOPPED		0xFFFFFFFFFFFFFFFEULL
78 #define NVMM_VCPU_EXIT_INVALID		0xFFFFFFFFFFFFFFFFULL
79 /* x86: operations. */
80 #define NVMM_VCPU_EXIT_MEMORY		0x0000000000000001ULL
81 #define NVMM_VCPU_EXIT_IO		0x0000000000000002ULL
82 /* x86: changes in VCPU state. */
83 #define NVMM_VCPU_EXIT_SHUTDOWN		0x0000000000001000ULL
84 #define NVMM_VCPU_EXIT_INT_READY	0x0000000000001001ULL
85 #define NVMM_VCPU_EXIT_NMI_READY	0x0000000000001002ULL
86 #define NVMM_VCPU_EXIT_HALTED		0x0000000000001003ULL
87 #define NVMM_VCPU_EXIT_TPR_CHANGED	0x0000000000001004ULL
88 /* x86: instructions. */
89 #define NVMM_VCPU_EXIT_RDMSR		0x0000000000002000ULL
90 #define NVMM_VCPU_EXIT_WRMSR		0x0000000000002001ULL
91 #define NVMM_VCPU_EXIT_MONITOR		0x0000000000002002ULL
92 #define NVMM_VCPU_EXIT_MWAIT		0x0000000000002003ULL
93 #define NVMM_VCPU_EXIT_CPUID		0x0000000000002004ULL
94 
95 struct nvmm_x86_exit {
96 	uint64_t reason;
97 	union {
98 		struct nvmm_x86_exit_memory mem;
99 		struct nvmm_x86_exit_io io;
100 		struct nvmm_x86_exit_rdmsr rdmsr;
101 		struct nvmm_x86_exit_wrmsr wrmsr;
102 		struct nvmm_x86_exit_insn insn;
103 		struct nvmm_x86_exit_invalid inv;
104 	} u;
105 	struct {
106 		uint64_t rflags;
107 		uint64_t cr8;
108 		uint64_t int_shadow:1;
109 		uint64_t int_window_exiting:1;
110 		uint64_t nmi_window_exiting:1;
111 		uint64_t evt_pending:1;
112 		uint64_t rsvd:60;
113 	} exitstate;
114 };
115 
116 #define NVMM_VCPU_EVENT_EXCP	0
117 #define NVMM_VCPU_EVENT_INTR	1
118 
119 struct nvmm_x86_event {
120 	u_int type;
121 	uint8_t vector;
122 	union {
123 		struct {
124 			uint64_t error;
125 		} excp;
126 	} u;
127 };
128 
129 struct nvmm_cap_md {
130 	uint64_t mach_conf_support;
131 
132 	uint64_t vcpu_conf_support;
133 #define NVMM_CAP_ARCH_VCPU_CONF_CPUID	__BIT(0)
134 #define NVMM_CAP_ARCH_VCPU_CONF_TPR	__BIT(1)
135 
136 	uint64_t xcr0_mask;
137 	uint32_t mxcsr_mask;
138 	uint32_t conf_cpuid_maxops;
139 	uint64_t rsvd[6];
140 };
141 
142 #endif
143 
144 /* -------------------------------------------------------------------------- */
145 
146 /*
147  * Segment state indexes. We use X64 as naming convention, not to confuse with
148  * X86 which originally implied 32bit.
149  */
150 
151 /* Segments. */
152 #define NVMM_X64_SEG_ES			0
153 #define NVMM_X64_SEG_CS			1
154 #define NVMM_X64_SEG_SS			2
155 #define NVMM_X64_SEG_DS			3
156 #define NVMM_X64_SEG_FS			4
157 #define NVMM_X64_SEG_GS			5
158 #define NVMM_X64_SEG_GDT		6
159 #define NVMM_X64_SEG_IDT		7
160 #define NVMM_X64_SEG_LDT		8
161 #define NVMM_X64_SEG_TR			9
162 #define NVMM_X64_NSEG			10
163 
164 /* General Purpose Registers. */
165 #define NVMM_X64_GPR_RAX		0
166 #define NVMM_X64_GPR_RCX		1
167 #define NVMM_X64_GPR_RDX		2
168 #define NVMM_X64_GPR_RBX		3
169 #define NVMM_X64_GPR_RSP		4
170 #define NVMM_X64_GPR_RBP		5
171 #define NVMM_X64_GPR_RSI		6
172 #define NVMM_X64_GPR_RDI		7
173 #define NVMM_X64_GPR_R8			8
174 #define NVMM_X64_GPR_R9			9
175 #define NVMM_X64_GPR_R10		10
176 #define NVMM_X64_GPR_R11		11
177 #define NVMM_X64_GPR_R12		12
178 #define NVMM_X64_GPR_R13		13
179 #define NVMM_X64_GPR_R14		14
180 #define NVMM_X64_GPR_R15		15
181 #define NVMM_X64_GPR_RIP		16
182 #define NVMM_X64_GPR_RFLAGS		17
183 #define NVMM_X64_NGPR			18
184 
185 /* Control Registers. */
186 #define NVMM_X64_CR_CR0			0
187 #define NVMM_X64_CR_CR2			1
188 #define NVMM_X64_CR_CR3			2
189 #define NVMM_X64_CR_CR4			3
190 #define NVMM_X64_CR_CR8			4
191 #define NVMM_X64_CR_XCR0		5
192 #define NVMM_X64_NCR			6
193 
194 /* Debug Registers. */
195 #define NVMM_X64_DR_DR0			0
196 #define NVMM_X64_DR_DR1			1
197 #define NVMM_X64_DR_DR2			2
198 #define NVMM_X64_DR_DR3			3
199 #define NVMM_X64_DR_DR6			4
200 #define NVMM_X64_DR_DR7			5
201 #define NVMM_X64_NDR			6
202 
203 /* MSRs. */
204 #define NVMM_X64_MSR_EFER		0
205 #define NVMM_X64_MSR_STAR		1
206 #define NVMM_X64_MSR_LSTAR		2
207 #define NVMM_X64_MSR_CSTAR		3
208 #define NVMM_X64_MSR_SFMASK		4
209 #define NVMM_X64_MSR_KERNELGSBASE	5
210 #define NVMM_X64_MSR_SYSENTER_CS	6
211 #define NVMM_X64_MSR_SYSENTER_ESP	7
212 #define NVMM_X64_MSR_SYSENTER_EIP	8
213 #define NVMM_X64_MSR_PAT		9
214 #define NVMM_X64_MSR_TSC		10
215 #define NVMM_X64_NMSR			11
216 
217 #ifndef ASM_NVMM
218 
219 #include <sys/types.h>
220 #include <x86/cpu_extended_state.h>
221 
222 struct nvmm_x64_state_seg {
223 	uint16_t selector;
224 	struct {		/* hidden */
225 		uint16_t type:4;
226 		uint16_t s:1;
227 		uint16_t dpl:2;
228 		uint16_t p:1;
229 		uint16_t avl:1;
230 		uint16_t l:1;
231 		uint16_t def:1;
232 		uint16_t g:1;
233 		uint16_t rsvd:4;
234 	} attrib;
235 	uint32_t limit;		/* hidden */
236 	uint64_t base;		/* hidden */
237 };
238 
239 struct nvmm_x64_state_intr {
240 	uint64_t int_shadow:1;
241 	uint64_t int_window_exiting:1;
242 	uint64_t nmi_window_exiting:1;
243 	uint64_t evt_pending:1;
244 	uint64_t rsvd:60;
245 };
246 
247 /* Flags. */
248 #define NVMM_X64_STATE_SEGS	0x01
249 #define NVMM_X64_STATE_GPRS	0x02
250 #define NVMM_X64_STATE_CRS	0x04
251 #define NVMM_X64_STATE_DRS	0x08
252 #define NVMM_X64_STATE_MSRS	0x10
253 #define NVMM_X64_STATE_INTR	0x20
254 #define NVMM_X64_STATE_FPU	0x40
255 #define NVMM_X64_STATE_ALL	\
256 	(NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \
257 	 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \
258 	 NVMM_X64_STATE_FPU)
259 
260 struct nvmm_x64_state {
261 	struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
262 	uint64_t gprs[NVMM_X64_NGPR];
263 	uint64_t crs[NVMM_X64_NCR];
264 	uint64_t drs[NVMM_X64_NDR];
265 	uint64_t msrs[NVMM_X64_NMSR];
266 	struct nvmm_x64_state_intr intr;
267 	struct fxsave fpu;
268 };
269 
270 #define NVMM_VCPU_CONF_CPUID	NVMM_VCPU_CONF_MD_BEGIN
271 #define NVMM_VCPU_CONF_TPR	(NVMM_VCPU_CONF_MD_BEGIN + 1)
272 
273 struct nvmm_vcpu_conf_cpuid {
274 	/* The options. */
275 	uint32_t mask:1;
276 	uint32_t exit:1;
277 	uint32_t rsvd:30;
278 
279 	/* The leaf. */
280 	uint32_t leaf;
281 
282 	/* The params. */
283 	union {
284 		struct {
285 			struct {
286 				uint32_t eax;
287 				uint32_t ebx;
288 				uint32_t ecx;
289 				uint32_t edx;
290 			} set;
291 			struct {
292 				uint32_t eax;
293 				uint32_t ebx;
294 				uint32_t ecx;
295 				uint32_t edx;
296 			} del;
297 		} mask;
298 	} u;
299 };
300 
301 struct nvmm_vcpu_conf_tpr {
302 	uint32_t exit_changed:1;
303 	uint32_t rsvd:31;
304 };
305 
306 #define nvmm_vcpu_exit		nvmm_x86_exit
307 #define nvmm_vcpu_event		nvmm_x86_event
308 #define nvmm_vcpu_state		nvmm_x64_state
309 
310 #ifdef _KERNEL
311 #define NVMM_X86_MACH_NCONF	0
312 #define NVMM_X86_VCPU_NCONF	2
313 struct nvmm_x86_cpuid_mask {
314 	uint32_t eax;
315 	uint32_t ebx;
316 	uint32_t ecx;
317 	uint32_t edx;
318 };
319 extern const struct nvmm_x64_state nvmm_x86_reset_state;
320 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001;
321 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007;
322 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001;
323 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007;
324 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008;
325 bool nvmm_x86_pat_validate(uint64_t);
326 #endif
327 
328 #endif /* ASM_NVMM */
329 
330 #endif /* _NVMM_X86_H_ */
331