xref: /dragonfly/sys/dev/virtual/nvmm/x86/nvmm_x86.h (revision 634ba020)
1 /*	$NetBSD: nvmm_x86.h,v 1.15.4.2 2020/08/26 17:55:49 martin Exp $	*/
2 
3 /*
4  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Maxime Villard.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _NVMM_X86_H_
33 #define _NVMM_X86_H_
34 
35 /* -------------------------------------------------------------------------- */
36 
37 #ifndef ASM_NVMM
38 
39 struct nvmm_x86_exit_memory {
40 	int prot;
41 	gpaddr_t gpa;
42 	uint8_t inst_len;
43 	uint8_t inst_bytes[15];
44 };
45 
46 struct nvmm_x86_exit_io {
47 	bool in;
48 	uint16_t port;
49 	int8_t seg;
50 	uint8_t address_size;
51 	uint8_t operand_size;
52 	bool rep;
53 	bool str;
54 	uint64_t npc;
55 };
56 
57 struct nvmm_x86_exit_rdmsr {
58 	uint32_t msr;
59 	uint64_t npc;
60 };
61 
62 struct nvmm_x86_exit_wrmsr {
63 	uint32_t msr;
64 	uint64_t val;
65 	uint64_t npc;
66 };
67 
68 struct nvmm_x86_exit_insn {
69 	uint64_t npc;
70 };
71 
72 struct nvmm_x86_exit_invalid {
73 	uint64_t hwcode;
74 };
75 
76 /* Generic. */
77 #define NVMM_VCPU_EXIT_NONE		0x0000000000000000ULL
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 <machine/npx.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 	union savefpu 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