xref: /openbsd/sys/arch/amd64/include/vmmvar.h (revision fabcfecb)
1 /*	$OpenBSD: vmmvar.h,v 1.109 2024/10/22 21:50:02 jsg Exp $	*/
2 /*
3  * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /*
19  * CPU capabilities for VMM operation
20  */
21 #ifndef _MACHINE_VMMVAR_H_
22 #define _MACHINE_VMMVAR_H_
23 
24 #define VMM_HV_SIGNATURE 	"OpenBSDVMM58"
25 
26 /* VMX: Basic Exit Reasons */
27 #define VMX_EXIT_NMI				0
28 #define VMX_EXIT_EXTINT				1
29 #define VMX_EXIT_TRIPLE_FAULT			2
30 #define VMX_EXIT_INIT				3
31 #define VMX_EXIT_SIPI				4
32 #define VMX_EXIT_IO_SMI				5
33 #define VMX_EXIT_OTHER_SMI			6
34 #define VMX_EXIT_INT_WINDOW			7
35 #define VMX_EXIT_NMI_WINDOW			8
36 #define VMX_EXIT_TASK_SWITCH			9
37 #define VMX_EXIT_CPUID				10
38 #define VMX_EXIT_GETSEC				11
39 #define VMX_EXIT_HLT				12
40 #define VMX_EXIT_INVD				13
41 #define VMX_EXIT_INVLPG				14
42 #define VMX_EXIT_RDPMC				15
43 #define VMX_EXIT_RDTSC				16
44 #define VMX_EXIT_RSM				17
45 #define VMX_EXIT_VMCALL				18
46 #define VMX_EXIT_VMCLEAR			19
47 #define VMX_EXIT_VMLAUNCH			20
48 #define VMX_EXIT_VMPTRLD			21
49 #define VMX_EXIT_VMPTRST			22
50 #define VMX_EXIT_VMREAD				23
51 #define VMX_EXIT_VMRESUME			24
52 #define VMX_EXIT_VMWRITE			25
53 #define VMX_EXIT_VMXOFF				26
54 #define VMX_EXIT_VMXON				27
55 #define VMX_EXIT_CR_ACCESS			28
56 #define VMX_EXIT_MOV_DR				29
57 #define VMX_EXIT_IO				30
58 #define VMX_EXIT_RDMSR				31
59 #define VMX_EXIT_WRMSR				32
60 #define VMX_EXIT_ENTRY_FAILED_GUEST_STATE	33
61 #define VMX_EXIT_ENTRY_FAILED_MSR_LOAD		34
62 #define VMX_EXIT_MWAIT				36
63 #define VMX_EXIT_MTF				37
64 #define VMX_EXIT_MONITOR			39
65 #define VMX_EXIT_PAUSE				40
66 #define VMX_EXIT_ENTRY_FAILED_MCE		41
67 #define VMX_EXIT_TPR_BELOW_THRESHOLD		43
68 #define VMX_EXIT_APIC_ACCESS			44
69 #define VMX_EXIT_VIRTUALIZED_EOI		45
70 #define VMX_EXIT_GDTR_IDTR			46
71 #define	VMX_EXIT_LDTR_TR			47
72 #define VMX_EXIT_EPT_VIOLATION			48
73 #define VMX_EXIT_EPT_MISCONFIGURATION		49
74 #define VMX_EXIT_INVEPT				50
75 #define VMX_EXIT_RDTSCP				51
76 #define VMX_EXIT_VMX_PREEMPTION_TIMER_EXPIRED	52
77 #define VMX_EXIT_INVVPID			53
78 #define VMX_EXIT_WBINVD				54
79 #define VMX_EXIT_XSETBV				55
80 #define VMX_EXIT_APIC_WRITE			56
81 #define VMX_EXIT_RDRAND				57
82 #define VMX_EXIT_INVPCID			58
83 #define VMX_EXIT_VMFUNC				59
84 #define VMX_EXIT_RDSEED				61
85 #define VMX_EXIT_XSAVES				63
86 #define VMX_EXIT_XRSTORS			64
87 
88 #define VM_EXIT_TERMINATED			0xFFFE
89 #define VM_EXIT_NONE				0xFFFF
90 
91 /*
92  * VMX: Misc defines
93  */
94 #define VMX_MAX_CR3_TARGETS			256
95 #define VMX_VMCS_PA_CLEAR			0xFFFFFFFFFFFFFFFFUL
96 
97 /*
98  * SVM: Intercept codes (exit reasons)
99  */
100 #define SVM_VMEXIT_CR0_READ			0x00
101 #define SVM_VMEXIT_CR1_READ			0x01
102 #define SVM_VMEXIT_CR2_READ			0x02
103 #define SVM_VMEXIT_CR3_READ			0x03
104 #define SVM_VMEXIT_CR4_READ			0x04
105 #define SVM_VMEXIT_CR5_READ			0x05
106 #define SVM_VMEXIT_CR6_READ			0x06
107 #define SVM_VMEXIT_CR7_READ			0x07
108 #define SVM_VMEXIT_CR8_READ			0x08
109 #define SVM_VMEXIT_CR9_READ			0x09
110 #define SVM_VMEXIT_CR10_READ			0x0A
111 #define SVM_VMEXIT_CR11_READ			0x0B
112 #define SVM_VMEXIT_CR12_READ			0x0C
113 #define SVM_VMEXIT_CR13_READ			0x0D
114 #define SVM_VMEXIT_CR14_READ			0x0E
115 #define SVM_VMEXIT_CR15_READ			0x0F
116 #define SVM_VMEXIT_CR0_WRITE			0x10
117 #define SVM_VMEXIT_CR1_WRITE			0x11
118 #define SVM_VMEXIT_CR2_WRITE			0x12
119 #define SVM_VMEXIT_CR3_WRITE			0x13
120 #define SVM_VMEXIT_CR4_WRITE			0x14
121 #define SVM_VMEXIT_CR5_WRITE			0x15
122 #define SVM_VMEXIT_CR6_WRITE			0x16
123 #define SVM_VMEXIT_CR7_WRITE			0x17
124 #define SVM_VMEXIT_CR8_WRITE			0x18
125 #define SVM_VMEXIT_CR9_WRITE			0x19
126 #define SVM_VMEXIT_CR10_WRITE			0x1A
127 #define SVM_VMEXIT_CR11_WRITE			0x1B
128 #define SVM_VMEXIT_CR12_WRITE			0x1C
129 #define SVM_VMEXIT_CR13_WRITE			0x1D
130 #define SVM_VMEXIT_CR14_WRITE			0x1E
131 #define SVM_VMEXIT_CR15_WRITE			0x1F
132 #define SVM_VMEXIT_DR0_READ			0x20
133 #define SVM_VMEXIT_DR1_READ			0x21
134 #define SVM_VMEXIT_DR2_READ			0x22
135 #define SVM_VMEXIT_DR3_READ			0x23
136 #define SVM_VMEXIT_DR4_READ			0x24
137 #define SVM_VMEXIT_DR5_READ			0x25
138 #define SVM_VMEXIT_DR6_READ			0x26
139 #define SVM_VMEXIT_DR7_READ			0x27
140 #define SVM_VMEXIT_DR8_READ			0x28
141 #define SVM_VMEXIT_DR9_READ			0x29
142 #define SVM_VMEXIT_DR10_READ			0x2A
143 #define SVM_VMEXIT_DR11_READ			0x2B
144 #define SVM_VMEXIT_DR12_READ			0x2C
145 #define SVM_VMEXIT_DR13_READ			0x2D
146 #define SVM_VMEXIT_DR14_READ			0x2E
147 #define SVM_VMEXIT_DR15_READ			0x2F
148 #define SVM_VMEXIT_DR0_WRITE			0x30
149 #define SVM_VMEXIT_DR1_WRITE			0x31
150 #define SVM_VMEXIT_DR2_WRITE			0x32
151 #define SVM_VMEXIT_DR3_WRITE			0x33
152 #define SVM_VMEXIT_DR4_WRITE			0x34
153 #define SVM_VMEXIT_DR5_WRITE			0x35
154 #define SVM_VMEXIT_DR6_WRITE			0x36
155 #define SVM_VMEXIT_DR7_WRITE			0x37
156 #define SVM_VMEXIT_DR8_WRITE			0x38
157 #define SVM_VMEXIT_DR9_WRITE			0x39
158 #define SVM_VMEXIT_DR10_WRITE			0x3A
159 #define SVM_VMEXIT_DR11_WRITE			0x3B
160 #define SVM_VMEXIT_DR12_WRITE			0x3C
161 #define SVM_VMEXIT_DR13_WRITE			0x3D
162 #define SVM_VMEXIT_DR14_WRITE			0x3E
163 #define SVM_VMEXIT_DR15_WRITE			0x3F
164 #define SVM_VMEXIT_EXCP0			0x40
165 #define SVM_VMEXIT_EXCP1			0x41
166 #define SVM_VMEXIT_EXCP2			0x42
167 #define SVM_VMEXIT_EXCP3			0x43
168 #define SVM_VMEXIT_EXCP4			0x44
169 #define SVM_VMEXIT_EXCP5			0x45
170 #define SVM_VMEXIT_EXCP6			0x46
171 #define SVM_VMEXIT_EXCP7			0x47
172 #define SVM_VMEXIT_EXCP8			0x48
173 #define SVM_VMEXIT_EXCP9			0x49
174 #define SVM_VMEXIT_EXCP10			0x4A
175 #define SVM_VMEXIT_EXCP11			0x4B
176 #define SVM_VMEXIT_EXCP12			0x4C
177 #define SVM_VMEXIT_EXCP13			0x4D
178 #define SVM_VMEXIT_EXCP14			0x4E
179 #define SVM_VMEXIT_EXCP15			0x4F
180 #define SVM_VMEXIT_EXCP16			0x50
181 #define SVM_VMEXIT_EXCP17			0x51
182 #define SVM_VMEXIT_EXCP18			0x52
183 #define SVM_VMEXIT_EXCP19			0x53
184 #define SVM_VMEXIT_EXCP20			0x54
185 #define SVM_VMEXIT_EXCP21			0x55
186 #define SVM_VMEXIT_EXCP22			0x56
187 #define SVM_VMEXIT_EXCP23			0x57
188 #define SVM_VMEXIT_EXCP24			0x58
189 #define SVM_VMEXIT_EXCP25			0x59
190 #define SVM_VMEXIT_EXCP26			0x5A
191 #define SVM_VMEXIT_EXCP27			0x5B
192 #define SVM_VMEXIT_EXCP28			0x5C
193 #define SVM_VMEXIT_EXCP29			0x5D
194 #define SVM_VMEXIT_EXCP30			0x5E
195 #define SVM_VMEXIT_EXCP31			0x5F
196 #define SVM_VMEXIT_INTR				0x60
197 #define SVM_VMEXIT_NMI				0x61
198 #define SVM_VMEXIT_SMI				0x62
199 #define SVM_VMEXIT_INIT				0x63
200 #define SVM_VMEXIT_VINTR			0x64
201 #define SVM_VMEXIT_CR0_SEL_WRITE		0x65
202 #define SVM_VMEXIT_IDTR_READ			0x66
203 #define SVM_VMEXIT_GDTR_READ			0x67
204 #define SVM_VMEXIT_LDTR_READ			0x68
205 #define SVM_VMEXIT_TR_READ			0x69
206 #define SVM_VMEXIT_IDTR_WRITE			0x6A
207 #define SVM_VMEXIT_GDTR_WRITE			0x6B
208 #define SVM_VMEXIT_LDTR_WRITE			0x6C
209 #define SVM_VMEXIT_TR_WRITE			0x6D
210 #define SVM_VMEXIT_RDTSC			0x6E
211 #define SVM_VMEXIT_RDPMC			0x6F
212 #define SVM_VMEXIT_PUSHF			0x70
213 #define SVM_VMEXIT_POPF				0x71
214 #define SVM_VMEXIT_CPUID			0x72
215 #define SVM_VMEXIT_RSM				0x73
216 #define SVM_VMEXIT_IRET				0x74
217 #define SVM_VMEXIT_SWINT			0x75
218 #define SVM_VMEXIT_INVD				0x76
219 #define SVM_VMEXIT_PAUSE			0x77
220 #define SVM_VMEXIT_HLT				0x78
221 #define SVM_VMEXIT_INVLPG			0x79
222 #define SVM_VMEXIT_INVLPGA			0x7A
223 #define SVM_VMEXIT_IOIO				0x7B
224 #define SVM_VMEXIT_MSR				0x7C
225 #define SVM_VMEXIT_TASK_SWITCH			0x7D
226 #define SVM_VMEXIT_FERR_FREEZE			0x7E
227 #define SVM_VMEXIT_SHUTDOWN			0x7F
228 #define SVM_VMEXIT_VMRUN			0x80
229 #define SVM_VMEXIT_VMMCALL			0x81
230 #define SVM_VMEXIT_VMLOAD			0x82
231 #define SVM_VMEXIT_VMSAVE			0x83
232 #define SVM_VMEXIT_STGI				0x84
233 #define SVM_VMEXIT_CLGI				0x85
234 #define SVM_VMEXIT_SKINIT			0x86
235 #define SVM_VMEXIT_RDTSCP			0x87
236 #define SVM_VMEXIT_ICEBP			0x88
237 #define SVM_VMEXIT_WBINVD			0x89
238 #define SVM_VMEXIT_MONITOR			0x8A
239 #define SVM_VMEXIT_MWAIT			0x8B
240 #define SVM_VMEXIT_MWAIT_CONDITIONAL		0x8C
241 #define SVM_VMEXIT_XSETBV			0x8D
242 #define SVM_VMEXIT_EFER_WRITE_TRAP		0x8F
243 #define SVM_VMEXIT_CR0_WRITE_TRAP		0x90
244 #define SVM_VMEXIT_CR1_WRITE_TRAP		0x91
245 #define SVM_VMEXIT_CR2_WRITE_TRAP		0x92
246 #define SVM_VMEXIT_CR3_WRITE_TRAP		0x93
247 #define SVM_VMEXIT_CR4_WRITE_TRAP		0x94
248 #define SVM_VMEXIT_CR5_WRITE_TRAP		0x95
249 #define SVM_VMEXIT_CR6_WRITE_TRAP		0x96
250 #define SVM_VMEXIT_CR7_WRITE_TRAP		0x97
251 #define SVM_VMEXIT_CR8_WRITE_TRAP		0x98
252 #define SVM_VMEXIT_CR9_WRITE_TRAP		0x99
253 #define SVM_VMEXIT_CR10_WRITE_TRAP		0x9A
254 #define SVM_VMEXIT_CR11_WRITE_TRAP		0x9B
255 #define SVM_VMEXIT_CR12_WRITE_TRAP		0x9C
256 #define SVM_VMEXIT_CR13_WRITE_TRAP		0x9D
257 #define SVM_VMEXIT_CR14_WRITE_TRAP		0x9E
258 #define SVM_VMEXIT_CR15_WRITE_TRAP		0x9F
259 #define SVM_VMEXIT_NPF				0x400
260 #define SVM_AVIC_INCOMPLETE_IPI			0x401
261 #define SVM_AVIC_NOACCEL			0x402
262 #define SVM_VMEXIT_VMGEXIT			0x403
263 #define SVM_VMEXIT_INVALID			-1
264 
265 /*
266  * Exception injection vectors (these correspond to the CPU exception types
267  * defined in the SDM.)
268  */
269 #define VMM_EX_DE	0	/* Divide Error #DE */
270 #define VMM_EX_DB	1	/* Debug Exception #DB */
271 #define VMM_EX_NMI	2	/* NMI */
272 #define VMM_EX_BP	3	/* Breakpoint #BP */
273 #define VMM_EX_OF	4	/* Overflow #OF */
274 #define VMM_EX_BR	5	/* Bound range exceeded #BR */
275 #define VMM_EX_UD	6	/* Undefined opcode #UD */
276 #define VMM_EX_NM	7	/* Device not available #NM */
277 #define VMM_EX_DF	8	/* Double fault #DF */
278 #define VMM_EX_CP	9	/* Coprocessor segment overrun (unused) */
279 #define VMM_EX_TS	10	/* Invalid TSS #TS */
280 #define VMM_EX_NP	11	/* Segment not present #NP */
281 #define VMM_EX_SS	12	/* Stack segment fault #SS */
282 #define VMM_EX_GP	13	/* General protection #GP */
283 #define VMM_EX_PF	14	/* Page fault #PF */
284 #define VMM_EX_MF	16	/* x87 FPU floating point error #MF */
285 #define VMM_EX_AC	17	/* Alignment check #AC */
286 #define VMM_EX_MC	18	/* Machine check #MC */
287 #define VMM_EX_XM	19	/* SIMD floating point exception #XM */
288 #define VMM_EX_VE	20	/* Virtualization exception #VE */
289 
290 enum {
291 	VEI_DIR_OUT,
292 	VEI_DIR_IN
293 };
294 
295 enum {
296 	VEE_FAULT_INVALID = 0,
297 	VEE_FAULT_HANDLED,
298 	VEE_FAULT_MMIO_ASSIST,
299 	VEE_FAULT_PROTECT,
300 };
301 
302 enum {
303 	VMM_CPU_MODE_REAL,
304 	VMM_CPU_MODE_PROT,
305 	VMM_CPU_MODE_PROT32,
306 	VMM_CPU_MODE_COMPAT,
307 	VMM_CPU_MODE_LONG,
308 	VMM_CPU_MODE_UNKNOWN,
309 };
310 
311 struct vmm_softc_md {
312 	/* Capabilities */
313 	uint32_t		nr_rvi_cpus;	/* [I] */
314 	uint32_t		nr_ept_cpus;	/* [I] */
315 	uint8_t			pkru_enabled;	/* [I] */
316 };
317 
318 /*
319  * vm exit data
320  *  vm_exit_inout		: describes an IN/OUT exit
321  */
322 struct vm_exit_inout {
323 	uint8_t			vei_size;	/* Size of access */
324 	uint8_t			vei_dir;	/* Direction */
325 	uint8_t			vei_rep;	/* REP prefix? */
326 	uint8_t			vei_string;	/* string variety? */
327 	uint8_t			vei_encoding;	/* operand encoding */
328 	uint16_t		vei_port;	/* port */
329 	uint32_t		vei_data;	/* data */
330 	uint8_t			vei_insn_len;	/* Count of instruction bytes */
331 };
332 
333 /*
334  *  vm_exit_eptviolation	: describes an EPT VIOLATION exit
335  */
336 struct vm_exit_eptviolation {
337 	uint8_t		vee_fault_type;		/* type of vm exit */
338 	uint8_t		vee_insn_info;		/* bitfield */
339 #define VEE_LEN_VALID		0x1		/* vee_insn_len is valid */
340 #define VEE_BYTES_VALID		0x2		/* vee_insn_bytes is valid */
341 	uint8_t		vee_insn_len;		/* [VMX] instruction length */
342 	uint8_t		vee_insn_bytes[15];	/* [SVM] bytes at {R,E,}IP */
343 };
344 
345 /*
346  * struct vcpu_inject_event	: describes an exception or interrupt to inject.
347  */
348 struct vcpu_inject_event {
349 	uint8_t		vie_vector;	/* Exception or interrupt vector. */
350 	uint32_t	vie_errorcode;	/* Optional error code. */
351 	uint8_t		vie_type;
352 #define VCPU_INJECT_NONE	0
353 #define VCPU_INJECT_INTR	1	/* External hardware interrupt. */
354 #define VCPU_INJECT_EX		2	/* HW or SW Exception */
355 #define VCPU_INJECT_NMI		3	/* Non-maskable Interrupt */
356 };
357 
358 /*
359  * struct vcpu_segment_info
360  *
361  * Describes a segment + selector set, used in constructing the initial vcpu
362  * register content
363  */
364 struct vcpu_segment_info {
365 	uint16_t	vsi_sel;
366 	uint32_t	vsi_limit;
367 	uint32_t	vsi_ar;
368 	uint64_t	vsi_base;
369 };
370 
371 /* The GPRS are ordered to assist instruction decode. */
372 #define VCPU_REGS_RAX		0
373 #define VCPU_REGS_RCX		1
374 #define VCPU_REGS_RDX		2
375 #define VCPU_REGS_RBX		3
376 #define VCPU_REGS_RSP		4
377 #define VCPU_REGS_RBP		5
378 #define VCPU_REGS_RSI		6
379 #define VCPU_REGS_RDI		7
380 #define VCPU_REGS_R8		8
381 #define VCPU_REGS_R9		9
382 #define VCPU_REGS_R10		10
383 #define VCPU_REGS_R11		11
384 #define VCPU_REGS_R12		12
385 #define VCPU_REGS_R13		13
386 #define VCPU_REGS_R14		14
387 #define VCPU_REGS_R15		15
388 #define VCPU_REGS_RIP		16
389 #define VCPU_REGS_RFLAGS	17
390 #define VCPU_REGS_NGPRS		(VCPU_REGS_RFLAGS + 1)
391 
392 #define VCPU_REGS_CR0		0
393 #define VCPU_REGS_CR2		1
394 #define VCPU_REGS_CR3		2
395 #define VCPU_REGS_CR4		3
396 #define VCPU_REGS_CR8		4
397 #define VCPU_REGS_XCR0		5
398 #define VCPU_REGS_PDPTE0 	6
399 #define VCPU_REGS_PDPTE1 	7
400 #define VCPU_REGS_PDPTE2 	8
401 #define VCPU_REGS_PDPTE3 	9
402 #define VCPU_REGS_NCRS		(VCPU_REGS_PDPTE3 + 1)
403 
404 #define VCPU_REGS_ES		0
405 #define VCPU_REGS_CS		1
406 #define VCPU_REGS_SS		2
407 #define VCPU_REGS_DS		3
408 #define VCPU_REGS_FS		4
409 #define VCPU_REGS_GS		5
410 #define VCPU_REGS_LDTR		6
411 #define VCPU_REGS_TR		7
412 #define VCPU_REGS_NSREGS	(VCPU_REGS_TR + 1)
413 
414 #define VCPU_REGS_EFER   	0
415 #define VCPU_REGS_STAR   	1
416 #define VCPU_REGS_LSTAR  	2
417 #define VCPU_REGS_CSTAR  	3
418 #define VCPU_REGS_SFMASK 	4
419 #define VCPU_REGS_KGSBASE	5
420 #define VCPU_REGS_MISC_ENABLE	6
421 #define VCPU_REGS_NMSRS		(VCPU_REGS_MISC_ENABLE + 1)
422 
423 #define VCPU_REGS_DR0		0
424 #define VCPU_REGS_DR1		1
425 #define VCPU_REGS_DR2		2
426 #define VCPU_REGS_DR3		3
427 #define VCPU_REGS_DR6		4
428 #define VCPU_REGS_DR7		5
429 #define VCPU_REGS_NDRS		(VCPU_REGS_DR7 + 1)
430 
431 struct vcpu_reg_state {
432 	uint64_t			vrs_gprs[VCPU_REGS_NGPRS];
433 	uint64_t			vrs_crs[VCPU_REGS_NCRS];
434 	uint64_t			vrs_msrs[VCPU_REGS_NMSRS];
435 	uint64_t			vrs_drs[VCPU_REGS_NDRS];
436 	struct vcpu_segment_info	vrs_sregs[VCPU_REGS_NSREGS];
437 	struct vcpu_segment_info	vrs_gdtr;
438 	struct vcpu_segment_info	vrs_idtr;
439 };
440 
441 #define VCPU_HOST_REGS_EFER   		0
442 #define VCPU_HOST_REGS_STAR   		1
443 #define VCPU_HOST_REGS_LSTAR  		2
444 #define VCPU_HOST_REGS_CSTAR  		3
445 #define VCPU_HOST_REGS_SFMASK 		4
446 #define VCPU_HOST_REGS_KGSBASE		5
447 #define VCPU_HOST_REGS_MISC_ENABLE	6
448 #define VCPU_HOST_REGS_NMSRS		(VCPU_HOST_REGS_MISC_ENABLE + 1)
449 
450 /*
451  * struct vm_exit
452  *
453  * Contains VM exit information communicated to vmd(8). This information is
454  * gathered by vmm(4) from the CPU on each exit that requires help from vmd.
455  */
456 struct vm_exit {
457 	union {
458 		struct vm_exit_inout		vei;	/* IN/OUT exit */
459 		struct vm_exit_eptviolation	vee;	/* EPT VIOLATION exit*/
460 	};
461 
462 	struct vcpu_reg_state		vrs;
463 	int				cpl;
464 };
465 
466 struct vm_intr_params {
467 	/* Input parameters to VMM_IOC_INTR */
468 	uint32_t		vip_vm_id;
469 	uint32_t		vip_vcpu_id;
470 	uint16_t		vip_intr;
471 };
472 
473 #define VM_RWREGS_GPRS	0x1	/* read/write GPRs */
474 #define VM_RWREGS_SREGS	0x2	/* read/write segment registers */
475 #define VM_RWREGS_CRS	0x4	/* read/write CRs */
476 #define VM_RWREGS_MSRS	0x8	/* read/write MSRs */
477 #define VM_RWREGS_DRS	0x10	/* read/write DRs */
478 #define VM_RWREGS_ALL	(VM_RWREGS_GPRS | VM_RWREGS_SREGS | VM_RWREGS_CRS | \
479     VM_RWREGS_MSRS | VM_RWREGS_DRS)
480 
481 struct vm_rwregs_params {
482 	/*
483 	 * Input/output parameters to VMM_IOC_READREGS /
484 	 * VMM_IOC_WRITEREGS
485 	 */
486 	uint32_t		vrwp_vm_id;
487 	uint32_t		vrwp_vcpu_id;
488 	uint64_t		vrwp_mask;
489 	struct vcpu_reg_state	vrwp_regs;
490 };
491 
492 /* IOCTL definitions */
493 #define VMM_IOC_INTR _IOW('V', 6, struct vm_intr_params) /* Intr pending */
494 
495 /* CPUID masks */
496 /*
497  * clone host capabilities minus:
498  *  debug store (CPUIDECX_DTES64, CPUIDECX_DSCPL, CPUID_DS)
499  *  monitor/mwait (CPUIDECX_MWAIT, CPUIDECX_MWAITX)
500  *  vmx/svm (CPUIDECX_VMX, CPUIDECX_SVM)
501  *  smx (CPUIDECX_SMX)
502  *  speedstep (CPUIDECX_EST)
503  *  thermal (CPUIDECX_TM2, CPUID_ACPI, CPUID_TM)
504  *  context id (CPUIDECX_CNXTID)
505  *  machine check (CPUID_MCE, CPUID_MCA)
506  *  silicon debug (CPUIDECX_SDBG)
507  *  xTPR (CPUIDECX_XTPR)
508  *  perf/debug (CPUIDECX_PDCM)
509  *  pcid (CPUIDECX_PCID)
510  *  direct cache access (CPUIDECX_DCA)
511  *  x2APIC (CPUIDECX_X2APIC)
512  *  apic deadline (CPUIDECX_DEADLINE)
513  *  apic (CPUID_APIC)
514  *  psn (CPUID_PSN)
515  *  self snoop (CPUID_SS)
516  *  hyperthreading (CPUID_HTT)
517  *  pending break enabled (CPUID_PBE)
518  *  MTRR (CPUID_MTRR)
519  *  Speculative execution control features (AMD)
520  */
521 #define VMM_CPUIDECX_MASK ~(CPUIDECX_EST | CPUIDECX_TM2 | CPUIDECX_MWAIT | \
522     CPUIDECX_PDCM | CPUIDECX_VMX | CPUIDECX_DTES64 | \
523     CPUIDECX_DSCPL | CPUIDECX_SMX | CPUIDECX_CNXTID | \
524     CPUIDECX_SDBG | CPUIDECX_XTPR | CPUIDECX_PCID | \
525     CPUIDECX_DCA | CPUIDECX_X2APIC | CPUIDECX_DEADLINE)
526 #define VMM_ECPUIDECX_MASK ~(CPUIDECX_SVM | CPUIDECX_MWAITX)
527 #define VMM_CPUIDEDX_MASK ~(CPUID_ACPI | CPUID_TM | \
528     CPUID_HTT | CPUID_DS | CPUID_APIC | \
529     CPUID_PSN | CPUID_SS | CPUID_PBE | \
530     CPUID_MTRR | CPUID_MCE | CPUID_MCA)
531 #define VMM_AMDSPEC_EBX_MASK ~(CPUIDEBX_IBPB | CPUIDEBX_IBRS | \
532     CPUIDEBX_STIBP | CPUIDEBX_IBRS_ALWAYSON | CPUIDEBX_STIBP_ALWAYSON | \
533     CPUIDEBX_IBRS_PREF | CPUIDEBX_SSBD | CPUIDEBX_VIRT_SSBD | \
534     CPUIDEBX_SSBD_NOTREQ)
535 
536 /* This mask is an include list for bits we want to expose */
537 #define VMM_APMI_EDX_INCLUDE_MASK (CPUIDEDX_ITSC)
538 
539 /*
540  * SEFF flags - copy from host minus:
541  *  TSC_ADJUST (SEFF0EBX_TSC_ADJUST)
542  *  SGX (SEFF0EBX_SGX)
543  *  HLE (SEFF0EBX_HLE)
544  *  INVPCID (SEFF0EBX_INVPCID)
545  *  RTM (SEFF0EBX_RTM)
546  *  PQM (SEFF0EBX_PQM)
547  *  AVX512F (SEFF0EBX_AVX512F)
548  *  AVX512DQ (SEFF0EBX_AVX512DQ)
549  *  AVX512IFMA (SEFF0EBX_AVX512IFMA)
550  *  AVX512PF (SEFF0EBX_AVX512PF)
551  *  AVX512ER (SEFF0EBX_AVX512ER)
552  *  AVX512CD (SEFF0EBX_AVX512CD)
553  *  AVX512BW (SEFF0EBX_AVX512BW)
554  *  AVX512VL (SEFF0EBX_AVX512VL)
555  *  MPX (SEFF0EBX_MPX)
556  *  PCOMMIT (SEFF0EBX_PCOMMIT)
557  *  PT (SEFF0EBX_PT)
558  */
559 #define VMM_SEFF0EBX_MASK ~(SEFF0EBX_TSC_ADJUST | SEFF0EBX_SGX | \
560     SEFF0EBX_HLE | SEFF0EBX_INVPCID | \
561     SEFF0EBX_RTM | SEFF0EBX_PQM | SEFF0EBX_MPX | \
562     SEFF0EBX_PCOMMIT | SEFF0EBX_PT | \
563     SEFF0EBX_AVX512F | SEFF0EBX_AVX512DQ | \
564     SEFF0EBX_AVX512IFMA | SEFF0EBX_AVX512PF | \
565     SEFF0EBX_AVX512ER | SEFF0EBX_AVX512CD | \
566     SEFF0EBX_AVX512BW | SEFF0EBX_AVX512VL)
567 
568 /* ECX mask contains the bits to include */
569 #define VMM_SEFF0ECX_MASK (SEFF0ECX_UMIP)
570 
571 /* EDX mask contains the bits to include */
572 #define VMM_SEFF0EDX_MASK (SEFF0EDX_MD_CLEAR)
573 
574 /*
575  * Extended function flags - copy from host minus:
576  * 0x80000001  EDX:RDTSCP Support
577  */
578 #define VMM_FEAT_EFLAGS_MASK ~(CPUID_RDTSCP)
579 
580 /*
581  * CPUID[0x4] deterministic cache info
582  */
583 #define VMM_CPUID4_CACHE_TOPOLOGY_MASK	0x3FF
584 
585 #ifdef _KERNEL
586 
587 #define VMX_FAIL_LAUNCH_UNKNOWN 	1
588 #define VMX_FAIL_LAUNCH_INVALID_VMCS	2
589 #define VMX_FAIL_LAUNCH_VALID_VMCS	3
590 
591 /* MSR bitmap manipulation macros */
592 #define VMX_MSRIDX(m)			((m) / 8)
593 #define VMX_MSRBIT(m)			(1 << (m) % 8)
594 
595 #define SVM_MSRIDX(m)			((m) / 4)
596 #define SVM_MSRBIT_R(m)			(1 << (((m) % 4) * 2))
597 #define SVM_MSRBIT_W(m)			(1 << (((m) % 4) * 2 + 1))
598 
599 enum {
600 	VMM_MODE_UNKNOWN,
601 	VMM_MODE_EPT,
602 	VMM_MODE_RVI
603 };
604 
605 enum {
606 	VMM_MEM_TYPE_REGULAR,
607 	VMM_MEM_TYPE_MMIO,
608 	VMM_MEM_TYPE_UNKNOWN
609 };
610 
611 /* Forward declarations */
612 struct vm;
613 struct vm_create_params;
614 
615 /*
616  * Implementation-specific cpu state
617  */
618 
619 struct vmcb_segment {
620 	uint16_t 			vs_sel;			/* 000h */
621 	uint16_t 			vs_attr;		/* 002h */
622 	uint32_t			vs_lim;			/* 004h */
623 	uint64_t			vs_base;		/* 008h */
624 };
625 
626 #define SVM_ENABLE_NP	(1ULL << 0)
627 #define SVM_ENABLE_SEV	(1ULL << 1)
628 
629 struct vmcb {
630 	union {
631 		struct {
632 			uint32_t	v_cr_rw;		/* 000h */
633 			uint32_t	v_dr_rw;		/* 004h */
634 			uint32_t	v_excp;			/* 008h */
635 			uint32_t	v_intercept1;		/* 00Ch */
636 			uint32_t	v_intercept2;		/* 010h */
637 			uint8_t		v_pad1[0x28];		/* 014h-03Bh */
638 			uint16_t	v_pause_thr;		/* 03Ch */
639 			uint16_t	v_pause_ct;		/* 03Eh */
640 			uint64_t	v_iopm_pa;		/* 040h */
641 			uint64_t	v_msrpm_pa;		/* 048h */
642 			uint64_t	v_tsc_offset;		/* 050h */
643 			uint32_t	v_asid;			/* 058h */
644 			uint8_t		v_tlb_control;		/* 05Ch */
645 			uint8_t		v_pad2[0x3];		/* 05Dh-05Fh */
646 			uint8_t		v_tpr;			/* 060h */
647 			uint8_t		v_irq;			/* 061h */
648 			uint8_t		v_intr_misc;		/* 062h */
649 			uint8_t		v_intr_masking;		/* 063h */
650 			uint8_t		v_intr_vector;		/* 064h */
651 			uint8_t		v_pad3[0x3];		/* 065h-067h */
652 			uint64_t	v_intr_shadow;		/* 068h */
653 			uint64_t	v_exitcode;		/* 070h */
654 			uint64_t	v_exitinfo1;		/* 078h */
655 			uint64_t	v_exitinfo2;		/* 080h */
656 			uint64_t	v_exitintinfo;		/* 088h */
657 			uint64_t	v_np_enable;		/* 090h */
658 			uint64_t	v_avic_apic_bar;	/* 098h */
659 			uint64_t	v_pad4;			/* 0A0h */
660 			uint64_t	v_eventinj;		/* 0A8h */
661 			uint64_t	v_n_cr3;		/* 0B0h */
662 			uint64_t	v_lbr_virt_enable;	/* 0B8h */
663 			uint64_t	v_vmcb_clean_bits;	/* 0C0h */
664 			uint64_t	v_nrip;			/* 0C8h */
665 			uint8_t		v_n_bytes_fetched;	/* 0D0h */
666 			uint8_t		v_guest_ins_bytes[0xf];	/* 0D1h-0DFh */
667 			uint64_t	v_avic_apic_back_page;	/* 0E0h */
668 			uint64_t	v_pad5;			/* 0E8h-0EFh */
669 			uint64_t	v_avic_logical_table;	/* 0F0h */
670 			uint64_t	v_avic_phys;		/* 0F8h */
671 
672 		};
673 		uint8_t			vmcb_control[0x400];
674 	};
675 
676 	union {
677 		struct {
678 			/* Offsets here are relative to start of VMCB SSA */
679 			struct vmcb_segment	v_es;		/* 000h */
680 			struct vmcb_segment	v_cs;		/* 010h */
681 			struct vmcb_segment	v_ss;		/* 020h */
682 			struct vmcb_segment	v_ds;		/* 030h */
683 			struct vmcb_segment	v_fs;		/* 040h */
684 			struct vmcb_segment	v_gs;		/* 050h */
685 			struct vmcb_segment	v_gdtr;		/* 060h */
686 			struct vmcb_segment	v_ldtr;		/* 070h */
687 			struct vmcb_segment	v_idtr;		/* 080h */
688 			struct vmcb_segment	v_tr;		/* 090h */
689 			uint8_t 		v_pad6[0x2B];	/* 0A0h-0CAh */
690 			uint8_t			v_cpl;		/* 0CBh */
691 			uint32_t		v_pad7;		/* 0CCh-0CFh */
692 			uint64_t		v_efer;		/* 0D0h */
693 			uint8_t			v_pad8[0x70];	/* 0D8h-147h */
694 			uint64_t		v_cr4;		/* 148h */
695 			uint64_t		v_cr3;		/* 150h */
696 			uint64_t		v_cr0;		/* 158h */
697 			uint64_t		v_dr7;		/* 160h */
698 			uint64_t		v_dr6;		/* 168h */
699 			uint64_t		v_rflags;	/* 170h */
700 			uint64_t		v_rip;		/* 178h */
701 			uint64_t		v_pad9[0xB];	/* 180h-1D7h */
702 			uint64_t		v_rsp;		/* 1D8h */
703 			uint64_t		v_pad10[0x3];	/* 1E0h-1F7h */
704 			uint64_t		v_rax;		/* 1F8h */
705 			uint64_t		v_star;		/* 200h */
706 			uint64_t		v_lstar;	/* 208h */
707 			uint64_t		v_cstar;	/* 210h */
708 			uint64_t		v_sfmask;	/* 218h */
709 			uint64_t		v_kgsbase;	/* 220h */
710 			uint64_t		v_sysenter_cs;	/* 228h */
711 			uint64_t		v_sysenter_esp;	/* 230h */
712 			uint64_t		v_sysenter_eip;	/* 238h */
713 			uint64_t		v_cr2;		/* 240h */
714 			uint64_t		v_pad11[0x4];	/* 248h-267h */
715 			uint64_t		v_g_pat;	/* 268h */
716 			uint64_t		v_dbgctl;	/* 270h */
717 			uint64_t		v_br_from;	/* 278h */
718 			uint64_t		v_br_to;	/* 280h */
719 			uint64_t		v_lastexcpfrom;	/* 288h */
720 			uint64_t		v_lastexcpto;	/* 290h */
721 		};
722 		uint8_t				vmcb_layout[PAGE_SIZE - 0x400];
723 	};
724 };
725 
726 struct vmcs {
727 	uint32_t	vmcs_revision;
728 };
729 
730 struct vmx_invvpid_descriptor {
731 	uint64_t	vid_vpid;
732 	uint64_t	vid_addr;
733 };
734 
735 struct vmx_invept_descriptor {
736 	uint64_t	vid_eptp;
737 	uint64_t	vid_reserved;
738 };
739 
740 struct vmx_msr_store {
741 	uint64_t	vms_index;
742 	uint64_t	vms_data;
743 };
744 
745 /*
746  * Storage for guest registers not preserved in VMCS and various exit
747  * information.
748  *
749  * Note that vmx/svm_enter_guest depend on the layout of this struct for
750  * field access.
751  */
752 struct vcpu_gueststate {
753 	/* %rsi should be first */
754 	uint64_t	vg_rsi;			/* 0x00 */
755 	uint64_t	vg_rax;			/* 0x08 */
756 	uint64_t	vg_rbx;			/* 0x10 */
757 	uint64_t	vg_rcx;			/* 0x18 */
758 	uint64_t	vg_rdx;			/* 0x20 */
759 	uint64_t	vg_rdi;			/* 0x28 */
760 	uint64_t	vg_rbp;			/* 0x30 */
761 	uint64_t	vg_r8;			/* 0x38 */
762 	uint64_t	vg_r9;			/* 0x40 */
763 	uint64_t	vg_r10;			/* 0x48 */
764 	uint64_t	vg_r11;			/* 0x50 */
765 	uint64_t	vg_r12;			/* 0x58 */
766 	uint64_t	vg_r13;			/* 0x60 */
767 	uint64_t	vg_r14;			/* 0x68 */
768 	uint64_t	vg_r15;			/* 0x70 */
769 	uint64_t	vg_cr2;			/* 0x78 */
770 	uint64_t	vg_rip;			/* 0x80 */
771 	uint32_t	vg_exit_reason;		/* 0x88 */
772 	uint64_t	vg_rflags;		/* 0x90 */
773 	uint64_t	vg_xcr0;		/* 0x98 */
774 	/*
775 	 * Debug registers
776 	 * - %dr4/%dr5 are aliased to %dr6/%dr7 (or cause #DE)
777 	 * - %dr7 is saved automatically in the VMCS
778 	 */
779 	uint64_t	vg_dr0;			/* 0xa0 */
780 	uint64_t	vg_dr1;			/* 0xa8 */
781 	uint64_t	vg_dr2;			/* 0xb0 */
782 	uint64_t	vg_dr3;			/* 0xb8 */
783 	uint64_t	vg_dr6;			/* 0xc0 */
784 };
785 
786 /*
787  * Virtual CPU
788  *
789  * Methods used to vcpu struct members:
790  *	a	atomic operations
791  *	I	immutable operations
792  *	K	kernel lock
793  *	r	reference count
794  *	v	vcpu rwlock
795  *	V	vm struct's vcpu list lock (vm_vcpu_lock)
796  */
797 struct vcpu {
798 	/*
799 	 * Guest FPU state - this must remain as the first member of the struct
800 	 * to ensure 64-byte alignment (set up during vcpu_pool init)
801 	 */
802 	struct savefpu vc_g_fpu;		/* [v] */
803 
804 	/* VMCS / VMCB pointer */
805 	vaddr_t vc_control_va;			/* [I] */
806 	paddr_t vc_control_pa;			/* [I] */
807 
808 	/* VLAPIC pointer */
809 	vaddr_t vc_vlapic_va;			/* [I] */
810 	uint64_t vc_vlapic_pa;			/* [I] */
811 
812 	/* MSR bitmap address */
813 	vaddr_t vc_msr_bitmap_va;		/* [I] */
814 	uint64_t vc_msr_bitmap_pa;		/* [I] */
815 
816 	struct vm *vc_parent;			/* [I] */
817 	uint32_t vc_id;				/* [I] */
818 	uint16_t vc_vpid;			/* [I] */
819 	u_int vc_state;				/* [a] */
820 	SLIST_ENTRY(vcpu) vc_vcpu_link;		/* [V] */
821 
822 	uint8_t vc_virt_mode;			/* [I] */
823 
824 	struct rwlock vc_lock;
825 
826 	struct cpu_info *vc_curcpu;		/* [a] */
827 	struct cpu_info *vc_last_pcpu;		/* [v] */
828 	struct vm_exit vc_exit;			/* [v] */
829 
830 	uint16_t vc_intr;			/* [v] */
831 	uint8_t vc_irqready;			/* [v] */
832 
833 	uint8_t vc_fpuinited;			/* [v] */
834 
835 	uint64_t vc_h_xcr0;			/* [v] */
836 
837 	struct vcpu_gueststate vc_gueststate;	/* [v] */
838 	struct vcpu_inject_event vc_inject;	/* [v] */
839 
840 	uint32_t vc_pvclock_version;		/* [v] */
841 	paddr_t vc_pvclock_system_gpa;		/* [v] */
842 	uint32_t vc_pvclock_system_tsc_mul;	/* [v] */
843 
844 	/* Shadowed MSRs */
845 	uint64_t vc_shadow_pat;			/* [v] */
846 
847 	/* Userland Protection Keys */
848 	uint32_t vc_pkru;			/* [v] */
849 
850 	/* VMX only (all requiring [v]) */
851 	uint64_t vc_vmx_basic;
852 	uint64_t vc_vmx_entry_ctls;
853 	uint64_t vc_vmx_true_entry_ctls;
854 	uint64_t vc_vmx_exit_ctls;
855 	uint64_t vc_vmx_true_exit_ctls;
856 	uint64_t vc_vmx_pinbased_ctls;
857 	uint64_t vc_vmx_true_pinbased_ctls;
858 	uint64_t vc_vmx_procbased_ctls;
859 	uint64_t vc_vmx_true_procbased_ctls;
860 	uint64_t vc_vmx_procbased2_ctls;
861 	vaddr_t vc_vmx_msr_exit_save_va;
862 	paddr_t vc_vmx_msr_exit_save_pa;
863 	vaddr_t vc_vmx_msr_exit_load_va;
864 	paddr_t vc_vmx_msr_exit_load_pa;
865 #if 0	/* XXX currently use msr_exit_save for msr_entry_load too */
866 	vaddr_t vc_vmx_msr_entry_load_va;
867 	paddr_t vc_vmx_msr_entry_load_pa;
868 #endif
869 	uint8_t vc_vmx_vpid_enabled;
870 	uint64_t vc_vmx_cr0_fixed1;
871 	uint64_t vc_vmx_cr0_fixed0;
872 	uint32_t vc_vmx_vmcs_state;		/* [a] */
873 #define VMCS_CLEARED	0
874 #define VMCS_LAUNCHED	1
875 
876 	/* SVM only (all requiring [v]) */
877 	vaddr_t vc_svm_hsa_va;
878 	paddr_t vc_svm_hsa_pa;
879 	vaddr_t vc_svm_ioio_va;
880 	paddr_t vc_svm_ioio_pa;
881 	int vc_sev;				/* [I] */
882 };
883 
884 SLIST_HEAD(vcpu_head, vcpu);
885 
886 void	vmm_dispatch_intr(vaddr_t);
887 int	vmxon(uint64_t *);
888 int	vmxoff(void);
889 int	vmclear(paddr_t *);
890 int	vmptrld(paddr_t *);
891 int	vmptrst(paddr_t *);
892 int	vmwrite(uint64_t, uint64_t);
893 int	vmread(uint64_t, uint64_t *);
894 int	invvpid(uint64_t, struct vmx_invvpid_descriptor *);
895 int	invept(uint64_t, struct vmx_invept_descriptor *);
896 int	vmx_enter_guest(paddr_t *, struct vcpu_gueststate *, int, uint8_t);
897 int	svm_enter_guest(uint64_t, struct vcpu_gueststate *,
898     struct region_descriptor *);
899 void	start_vmm_on_cpu(struct cpu_info *);
900 void	stop_vmm_on_cpu(struct cpu_info *);
901 void	vmclear_on_cpu(struct cpu_info *);
902 void	vmm_attach_machdep(struct device *, struct device *, void *);
903 void	vmm_activate_machdep(struct device *, int);
904 int	vmmioctl_machdep(dev_t, u_long, caddr_t, int, struct proc *);
905 int	pledge_ioctl_vmm_machdep(struct proc *, long);
906 int	vmm_start(void);
907 int	vmm_stop(void);
908 int	vm_impl_init(struct vm *, struct proc *);
909 void	vm_impl_deinit(struct vm *);
910 int	vcpu_init(struct vcpu *, struct vm_create_params *);
911 void	vcpu_deinit(struct vcpu *);
912 int	vm_rwregs(struct vm_rwregs_params *, int);
913 int	vcpu_reset_regs(struct vcpu *, struct vcpu_reg_state *);
914 
915 #endif /* _KERNEL */
916 
917 #endif /* ! _MACHINE_VMMVAR_H_ */
918