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