xref: /openbsd/sys/arch/amd64/include/vmmvar.h (revision 172bac09)
1*172bac09Smlarkin /*	$OpenBSD: vmmvar.h,v 1.16 2016/09/01 14:45:36 mlarkin Exp $	*/
277d6d4a2Smlarkin /*
377d6d4a2Smlarkin  * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
477d6d4a2Smlarkin  *
577d6d4a2Smlarkin  * Permission to use, copy, modify, and distribute this software for any
677d6d4a2Smlarkin  * purpose with or without fee is hereby granted, provided that the above
777d6d4a2Smlarkin  * copyright notice and this permission notice appear in all copies.
877d6d4a2Smlarkin  *
977d6d4a2Smlarkin  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1077d6d4a2Smlarkin  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1177d6d4a2Smlarkin  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1277d6d4a2Smlarkin  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1377d6d4a2Smlarkin  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1477d6d4a2Smlarkin  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1577d6d4a2Smlarkin  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1677d6d4a2Smlarkin  */
1777d6d4a2Smlarkin 
1877d6d4a2Smlarkin /*
1977d6d4a2Smlarkin  * CPU capabilities for VMM operation
2077d6d4a2Smlarkin  */
2177d6d4a2Smlarkin #ifndef _MACHINE_VMMVAR_H_
2277d6d4a2Smlarkin #define _MACHINE_VMMVAR_H_
2377d6d4a2Smlarkin 
2477d6d4a2Smlarkin #define VMM_HV_SIGNATURE 	"OpenBSDVMM58"
2577d6d4a2Smlarkin 
2640a3b6a0Sstefan #define VMM_MAX_MEM_RANGES	16
2777d6d4a2Smlarkin #define VMM_MAX_DISKS_PER_VM	2
2877d6d4a2Smlarkin #define VMM_MAX_PATH_DISK	128
2977d6d4a2Smlarkin #define VMM_MAX_NAME_LEN	32
3077d6d4a2Smlarkin #define VMM_MAX_KERNEL_PATH	128
3177d6d4a2Smlarkin #define VMM_MAX_VCPUS_PER_VM	64
3277d6d4a2Smlarkin #define VMM_MAX_VM_MEM_SIZE	(512 * 1024)
3377d6d4a2Smlarkin #define VMM_MAX_NICS_PER_VM	2
3477d6d4a2Smlarkin 
3577d6d4a2Smlarkin #define VMM_PCI_MMIO_BAR_BASE	0xF0000000
3677d6d4a2Smlarkin #define VMM_PCI_MMIO_BAR_END	0xF0FFFFFF
3777d6d4a2Smlarkin #define VMM_PCI_MMIO_BAR_SIZE	0x00010000
3877d6d4a2Smlarkin #define VMM_PCI_IO_BAR_BASE	0x1000
3977d6d4a2Smlarkin #define VMM_PCI_IO_BAR_END	0xFFFF
4077d6d4a2Smlarkin #define VMM_PCI_IO_BAR_SIZE	0x1000
4177d6d4a2Smlarkin 
4277d6d4a2Smlarkin /* VMX: Basic Exit Reasons */
4377d6d4a2Smlarkin #define VMX_EXIT_NMI				0
4477d6d4a2Smlarkin #define VMX_EXIT_EXTINT				1
4577d6d4a2Smlarkin #define VMX_EXIT_TRIPLE_FAULT			2
4677d6d4a2Smlarkin #define VMX_EXIT_INIT				3
4777d6d4a2Smlarkin #define VMX_EXIT_SIPI				4
4877d6d4a2Smlarkin #define VMX_EXIT_IO_SMI				5
4977d6d4a2Smlarkin #define VMX_EXIT_OTHER_SMI			6
5077d6d4a2Smlarkin #define VMX_EXIT_INT_WINDOW			7
5177d6d4a2Smlarkin #define VMX_EXIT_NMI_WINDOW			8
5277d6d4a2Smlarkin #define VMX_EXIT_TASK_SWITCH			9
5377d6d4a2Smlarkin #define VMX_EXIT_CPUID				10
5477d6d4a2Smlarkin #define VMX_EXIT_GETSEC				11
5577d6d4a2Smlarkin #define VMX_EXIT_HLT				12
5677d6d4a2Smlarkin #define VMX_EXIT_INVD				13
5777d6d4a2Smlarkin #define VMX_EXIT_INVLPG				14
5877d6d4a2Smlarkin #define VMX_EXIT_RDPMC				15
5977d6d4a2Smlarkin #define VMX_EXIT_RDTSC				16
6077d6d4a2Smlarkin #define VMX_EXIT_RSM				17
6177d6d4a2Smlarkin #define VMX_EXIT_VMCALL				18
6277d6d4a2Smlarkin #define VMX_EXIT_VMCLEAR			19
6377d6d4a2Smlarkin #define VMX_EXIT_VMLAUNCH			20
6477d6d4a2Smlarkin #define VMX_EXIT_VMPTRLD			21
6577d6d4a2Smlarkin #define VMX_EXIT_VMPTRST			22
6677d6d4a2Smlarkin #define VMX_EXIT_VMREAD				23
6777d6d4a2Smlarkin #define VMX_EXIT_VMRESUME			24
6877d6d4a2Smlarkin #define VMX_EXIT_VMWRITE			25
6977d6d4a2Smlarkin #define VMX_EXIT_VMXOFF				26
7077d6d4a2Smlarkin #define VMX_EXIT_VMXON				27
7177d6d4a2Smlarkin #define VMX_EXIT_CR_ACCESS			28
7277d6d4a2Smlarkin #define VMX_EXIT_MOV_DR				29
7377d6d4a2Smlarkin #define VMX_EXIT_IO				30
7477d6d4a2Smlarkin #define VMX_EXIT_RDMSR				31
7577d6d4a2Smlarkin #define VMX_EXIT_WRMSR				32
7677d6d4a2Smlarkin #define VMX_EXIT_ENTRY_FAILED_GUEST_STATE	33
7777d6d4a2Smlarkin #define VMX_EXIT_ENTRY_FAILED_MSR_LOAD		34
7877d6d4a2Smlarkin #define VMX_EXIT_MWAIT				36
7977d6d4a2Smlarkin #define VMX_EXIT_MTF				37
8077d6d4a2Smlarkin #define VMX_EXIT_MONITOR			39
8177d6d4a2Smlarkin #define VMX_EXIT_PAUSE				40
8277d6d4a2Smlarkin #define VMX_EXIT_ENTRY_FAILED_MCE		41
8377d6d4a2Smlarkin #define VMX_EXIT_TPR_BELOW_THRESHOLD		43
8477d6d4a2Smlarkin #define VMX_EXIT_APIC_ACCESS			44
8577d6d4a2Smlarkin #define VMX_EXIT_VIRTUALIZED_EOI		45
8677d6d4a2Smlarkin #define VMX_EXIT_GDTR_IDTR			46
8777d6d4a2Smlarkin #define	VMX_EXIT_LDTR_TR			47
8877d6d4a2Smlarkin #define VMX_EXIT_EPT_VIOLATION			48
8977d6d4a2Smlarkin #define VMX_EXIT_EPT_MISCONFIGURATION		49
9077d6d4a2Smlarkin #define VMX_EXIT_INVEPT				50
9177d6d4a2Smlarkin #define VMX_EXIT_RDTSCP				51
9277d6d4a2Smlarkin #define VMX_EXIT_VMX_PREEMPTION_TIMER_EXPIRED	52
9377d6d4a2Smlarkin #define VMX_EXIT_INVVPID			53
9477d6d4a2Smlarkin #define VMX_EXIT_WBINVD				54
9577d6d4a2Smlarkin #define VMX_EXIT_XSETBV				55
9677d6d4a2Smlarkin #define VMX_EXIT_APIC_WRITE			56
9777d6d4a2Smlarkin #define VMX_EXIT_RDRAND				57
9877d6d4a2Smlarkin #define VMX_EXIT_INVPCID			58
9977d6d4a2Smlarkin #define VMX_EXIT_VMFUNC				59
1009f12662aSmlarkin #define VMX_EXIT_RDSEED				61
1019f12662aSmlarkin #define VMX_EXIT_XSAVES				63
1029f12662aSmlarkin #define VMX_EXIT_XRSTORS			64
10377d6d4a2Smlarkin 
10477d6d4a2Smlarkin #define VM_EXIT_TERMINATED			0xFFFE
10577d6d4a2Smlarkin #define VM_EXIT_NONE				0xFFFF
10677d6d4a2Smlarkin 
1071180136eSmlarkin /*
1081180136eSmlarkin  * VCPU state values. Note that there is a conversion function in vmm.c
1091180136eSmlarkin  * (vcpu_state_decode) that converts these to human readable strings,
1101180136eSmlarkin  * so this enum and vcpu_state_decode should be kept in sync.
1111180136eSmlarkin  */
11277d6d4a2Smlarkin enum {
11377d6d4a2Smlarkin 	VCPU_STATE_STOPPED,
11477d6d4a2Smlarkin 	VCPU_STATE_RUNNING,
115e0c038edSmlarkin 	VCPU_STATE_REQTERM,
116e0c038edSmlarkin 	VCPU_STATE_TERMINATED,
117e0c038edSmlarkin 	VCPU_STATE_UNKNOWN,
11877d6d4a2Smlarkin };
11977d6d4a2Smlarkin 
12077d6d4a2Smlarkin enum {
12177d6d4a2Smlarkin 	VEI_DIR_OUT,
12277d6d4a2Smlarkin 	VEI_DIR_IN
12377d6d4a2Smlarkin };
12477d6d4a2Smlarkin 
12577d6d4a2Smlarkin /*
12677d6d4a2Smlarkin  * vm exit data
12777d6d4a2Smlarkin  *  vm_exit_inout		: describes an IN/OUT exit
12877d6d4a2Smlarkin  */
12977d6d4a2Smlarkin struct vm_exit_inout {
13077d6d4a2Smlarkin 	uint8_t			vei_size;	/* Size of access */
13177d6d4a2Smlarkin 	uint8_t			vei_dir;	/* Direction */
13277d6d4a2Smlarkin 	uint8_t			vei_rep;	/* REP prefix? */
13377d6d4a2Smlarkin 	uint8_t			vei_string;	/* string variety? */
13477d6d4a2Smlarkin 	uint8_t			vei_encoding;	/* operand encoding */
13577d6d4a2Smlarkin 	uint16_t		vei_port;	/* port */
13677d6d4a2Smlarkin 	uint32_t		vei_data;	/* data (for IN insns) */
13777d6d4a2Smlarkin };
13877d6d4a2Smlarkin 
13977d6d4a2Smlarkin union vm_exit {
14077d6d4a2Smlarkin 	struct vm_exit_inout	vei;		/* IN/OUT exit */
14177d6d4a2Smlarkin };
14277d6d4a2Smlarkin 
1433475ba91Smlarkin /*
1443475ba91Smlarkin  * struct vcpu_segment_info describes a segment + selector set, used
1453475ba91Smlarkin  * in constructing the initial vcpu register content
1463475ba91Smlarkin  */
1473475ba91Smlarkin struct vcpu_segment_info {
1483475ba91Smlarkin 	uint16_t vsi_sel;
1493475ba91Smlarkin 	uint32_t vsi_limit;
1503475ba91Smlarkin 	uint32_t vsi_ar;
1513475ba91Smlarkin 	uint64_t vsi_base;
1523475ba91Smlarkin };
1533475ba91Smlarkin 
1543475ba91Smlarkin /*
1553475ba91Smlarkin  * struct vcpu_init_state describes the set of vmd-settable registers
1563475ba91Smlarkin  * that the VM's vcpus will be set to during VM boot or reset. Certain
1573475ba91Smlarkin  * registers are always set to 0 (eg, the GP regs) and certain registers
1583475ba91Smlarkin  * have fixed values based on hardware requirements and calculated by
1593475ba91Smlarkin  * vmm (eg, CR0/CR4)
1603475ba91Smlarkin  */
1613475ba91Smlarkin struct vcpu_init_state {
1623475ba91Smlarkin 	uint64_t			vis_rflags;
1633475ba91Smlarkin 	uint64_t			vis_rip;
1643475ba91Smlarkin 	uint64_t			vis_rsp;
165532c6190Sstefan 	uint64_t			vis_cr0;
1663475ba91Smlarkin 	uint64_t			vis_cr3;
1673475ba91Smlarkin 
1683475ba91Smlarkin 	struct vcpu_segment_info	vis_cs;
1693475ba91Smlarkin 	struct vcpu_segment_info	vis_ds;
1703475ba91Smlarkin 	struct vcpu_segment_info	vis_es;
1713475ba91Smlarkin 	struct vcpu_segment_info	vis_fs;
1723475ba91Smlarkin 	struct vcpu_segment_info	vis_gs;
1733475ba91Smlarkin 	struct vcpu_segment_info	vis_ss;
1743475ba91Smlarkin 	struct vcpu_segment_info	vis_gdtr;
1753475ba91Smlarkin 	struct vcpu_segment_info	vis_idtr;
1763475ba91Smlarkin 	struct vcpu_segment_info	vis_ldtr;
1773475ba91Smlarkin 	struct vcpu_segment_info	vis_tr;
1783475ba91Smlarkin };
17977d6d4a2Smlarkin 
18040a3b6a0Sstefan struct vm_mem_range {
18140a3b6a0Sstefan 	paddr_t	vmr_gpa;
1820d6cfffcSstefan 	vaddr_t vmr_va;
18340a3b6a0Sstefan 	size_t	vmr_size;
18440a3b6a0Sstefan };
18540a3b6a0Sstefan 
18677d6d4a2Smlarkin struct vm_create_params {
18777d6d4a2Smlarkin 	/* Input parameters to VMM_IOC_CREATE */
18840a3b6a0Sstefan 	size_t			vcp_nmemranges;
18977d6d4a2Smlarkin 	size_t			vcp_ncpus;
19077d6d4a2Smlarkin 	size_t			vcp_ndisks;
19177d6d4a2Smlarkin 	size_t			vcp_nnics;
19240a3b6a0Sstefan 	struct vm_mem_range	vcp_memranges[VMM_MAX_MEM_RANGES];
19377d6d4a2Smlarkin 	char			vcp_disks[VMM_MAX_DISKS_PER_VM][VMM_MAX_PATH_DISK];
19477d6d4a2Smlarkin 	char			vcp_name[VMM_MAX_NAME_LEN];
19577d6d4a2Smlarkin 	char			vcp_kernel[VMM_MAX_KERNEL_PATH];
19677d6d4a2Smlarkin 	uint8_t			vcp_macs[VMM_MAX_NICS_PER_VM][6];
19777d6d4a2Smlarkin 
19877d6d4a2Smlarkin 	/* Output parameter from VMM_IOC_CREATE */
19977d6d4a2Smlarkin 	uint32_t	vcp_id;
20077d6d4a2Smlarkin };
20177d6d4a2Smlarkin 
20277d6d4a2Smlarkin struct vm_run_params {
20377d6d4a2Smlarkin 	/* Input parameters to VMM_IOC_RUN */
20477d6d4a2Smlarkin 	uint32_t	vrp_vm_id;
20577d6d4a2Smlarkin 	uint32_t	vrp_vcpu_id;
20677d6d4a2Smlarkin 	uint8_t		vrp_continue;		/* Continuing from an exit */
207*172bac09Smlarkin 	uint16_t	vrp_irq;		/* IRQ to inject */
20877d6d4a2Smlarkin 
20977d6d4a2Smlarkin 	/* Input/output parameter to VMM_IOC_RUN */
21077d6d4a2Smlarkin 	union vm_exit	*vrp_exit;		/* updated exit data */
21177d6d4a2Smlarkin 
21277d6d4a2Smlarkin 	/* Output parameter from VMM_IOC_RUN */
21377d6d4a2Smlarkin 	uint16_t	vrp_exit_reason;	/* exit reason */
214*172bac09Smlarkin 	uint8_t		vrp_irqready;		/* ready for IRQ on entry */
21577d6d4a2Smlarkin };
21677d6d4a2Smlarkin 
21777d6d4a2Smlarkin struct vm_info_result {
21877d6d4a2Smlarkin 	/* Output parameters from VMM_IOC_INFO */
21977d6d4a2Smlarkin 	size_t		vir_memory_size;
220d5b14089Smlarkin 	size_t		vir_used_size;
22177d6d4a2Smlarkin 	size_t		vir_ncpus;
22277d6d4a2Smlarkin 	uint8_t		vir_vcpu_state[VMM_MAX_VCPUS_PER_VM];
22377d6d4a2Smlarkin 	pid_t		vir_creator_pid;
22477d6d4a2Smlarkin 	uint32_t	vir_id;
22577d6d4a2Smlarkin 	char		vir_name[VMM_MAX_NAME_LEN];
22677d6d4a2Smlarkin };
22777d6d4a2Smlarkin 
22877d6d4a2Smlarkin struct vm_info_params {
22977d6d4a2Smlarkin 	/* Input parameters to VMM_IOC_INFO */
23077d6d4a2Smlarkin 	size_t			vip_size;	/* Output buffer size */
23177d6d4a2Smlarkin 
23277d6d4a2Smlarkin 	/* Output Parameters from VMM_IOC_INFO */
23377d6d4a2Smlarkin 	size_t			 vip_info_ct;	/* # of entries returned */
23477d6d4a2Smlarkin 	struct vm_info_result	*vip_info;	/* Output buffer */
23577d6d4a2Smlarkin };
23677d6d4a2Smlarkin 
23777d6d4a2Smlarkin struct vm_terminate_params {
23877d6d4a2Smlarkin 	/* Input parameters to VMM_IOC_TERM */
23977d6d4a2Smlarkin 	uint32_t		vtp_vm_id;
24077d6d4a2Smlarkin };
24177d6d4a2Smlarkin 
24298df751cSmlarkin struct vm_resetcpu_params {
24398df751cSmlarkin 	/* Input parameters to VMM_IOC_RESETCPU */
24498df751cSmlarkin 	uint32_t		vrp_vm_id;
24598df751cSmlarkin 	uint32_t		vrp_vcpu_id;
2463475ba91Smlarkin 	struct vcpu_init_state	vrp_init_state;
24798df751cSmlarkin };
24898df751cSmlarkin 
249f3757d05Smlarkin struct vm_intr_params {
250f3757d05Smlarkin 	/* Input parameters to VMM_IOC_INTR */
251f3757d05Smlarkin 	uint32_t		vip_vm_id;
252f3757d05Smlarkin 	uint32_t		vip_vcpu_id;
2531180136eSmlarkin 	uint16_t		vip_intr;
254f3757d05Smlarkin };
255f3757d05Smlarkin 
25677d6d4a2Smlarkin /* IOCTL definitions */
257a940fe28Sreyk #define VMM_IOC_CREATE _IOWR('V', 1, struct vm_create_params) /* Create VM */
258a940fe28Sreyk #define VMM_IOC_RUN _IOWR('V', 2, struct vm_run_params) /* Run VCPU */
259a940fe28Sreyk #define VMM_IOC_INFO _IOWR('V', 3, struct vm_info_params) /* Get VM Info */
260a940fe28Sreyk #define VMM_IOC_TERM _IOW('V', 4, struct vm_terminate_params) /* Terminate VM */
2619d87b43bSstefan #define VMM_IOC_RESETCPU _IOW('V', 5, struct vm_resetcpu_params) /* Reset */
2629d87b43bSstefan #define VMM_IOC_INTR _IOW('V', 6, struct vm_intr_params) /* Intr pending */
26377d6d4a2Smlarkin 
26477d6d4a2Smlarkin #ifdef _KERNEL
26577d6d4a2Smlarkin 
26677d6d4a2Smlarkin #define VMX_FAIL_LAUNCH_UNKNOWN 1
26777d6d4a2Smlarkin #define VMX_FAIL_LAUNCH_INVALID_VMCS 2
26877d6d4a2Smlarkin #define VMX_FAIL_LAUNCH_VALID_VMCS 3
26977d6d4a2Smlarkin 
270efc4a465Smlarkin #define VMX_NUM_MSR_STORE 7
271efc4a465Smlarkin 
27277d6d4a2Smlarkin enum {
27377d6d4a2Smlarkin 	VMM_MODE_UNKNOWN,
27477d6d4a2Smlarkin 	VMM_MODE_VMX,
27577d6d4a2Smlarkin 	VMM_MODE_EPT,
27677d6d4a2Smlarkin 	VMM_MODE_SVM,
27777d6d4a2Smlarkin 	VMM_MODE_RVI
27877d6d4a2Smlarkin };
27977d6d4a2Smlarkin 
28077d6d4a2Smlarkin enum {
28177d6d4a2Smlarkin 	VMM_MEM_TYPE_REGULAR,
28277d6d4a2Smlarkin 	VMM_MEM_TYPE_UNKNOWN
28377d6d4a2Smlarkin };
28477d6d4a2Smlarkin 
28577d6d4a2Smlarkin /* Forward declarations */
28677d6d4a2Smlarkin struct vm;
28777d6d4a2Smlarkin 
28877d6d4a2Smlarkin /*
28977d6d4a2Smlarkin  * Implementation-specific cpu state
29077d6d4a2Smlarkin  */
29177d6d4a2Smlarkin struct vmcb {
29277d6d4a2Smlarkin };
29377d6d4a2Smlarkin 
29477d6d4a2Smlarkin struct vmcs {
29577d6d4a2Smlarkin 	uint32_t	vmcs_revision;
29677d6d4a2Smlarkin };
29777d6d4a2Smlarkin 
29877d6d4a2Smlarkin struct vmx_invvpid_descriptor
29977d6d4a2Smlarkin {
30077d6d4a2Smlarkin 	uint64_t	vid_vpid; // : 16;
30177d6d4a2Smlarkin 	uint64_t	vid_addr;
30277d6d4a2Smlarkin };
30377d6d4a2Smlarkin 
30477d6d4a2Smlarkin struct vmx_invept_descriptor
30577d6d4a2Smlarkin {
30677d6d4a2Smlarkin 	uint64_t	vid_eptp;
30777d6d4a2Smlarkin 	uint64_t	vid_reserved;
30877d6d4a2Smlarkin };
30977d6d4a2Smlarkin 
31077d6d4a2Smlarkin struct vmx_msr_store
31177d6d4a2Smlarkin {
31277d6d4a2Smlarkin 	uint64_t	vms_index : 32;
31377d6d4a2Smlarkin 	uint64_t	vms_data;
31477d6d4a2Smlarkin };
31577d6d4a2Smlarkin 
31677d6d4a2Smlarkin /*
31777d6d4a2Smlarkin  * Storage for guest registers not preserved in VMCS and various exit
31877d6d4a2Smlarkin  * information.
31977d6d4a2Smlarkin  *
32077d6d4a2Smlarkin  * Note that vmx_enter_guest depends on the layout of this struct for
32177d6d4a2Smlarkin  * field access.
32277d6d4a2Smlarkin  */
32377d6d4a2Smlarkin struct vmx_gueststate
32477d6d4a2Smlarkin {
32577d6d4a2Smlarkin 	/* %rsi should be first */
32677d6d4a2Smlarkin 	uint64_t	vg_rsi;			/* 0x00 */
32777d6d4a2Smlarkin 	uint64_t	vg_rax;			/* 0x08 */
32877d6d4a2Smlarkin 	uint64_t	vg_rbx;			/* 0x10 */
32977d6d4a2Smlarkin 	uint64_t	vg_rcx;			/* 0x18 */
33077d6d4a2Smlarkin 	uint64_t	vg_rdx;			/* 0x20 */
33177d6d4a2Smlarkin 	uint64_t	vg_rdi;			/* 0x28 */
33277d6d4a2Smlarkin 	uint64_t	vg_rbp;			/* 0x30 */
33377d6d4a2Smlarkin 	uint64_t	vg_r8;			/* 0x38 */
33477d6d4a2Smlarkin 	uint64_t	vg_r9;			/* 0x40 */
33577d6d4a2Smlarkin 	uint64_t	vg_r10;			/* 0x48 */
33677d6d4a2Smlarkin 	uint64_t	vg_r11;			/* 0x50 */
33777d6d4a2Smlarkin 	uint64_t	vg_r12;			/* 0x58 */
33877d6d4a2Smlarkin 	uint64_t	vg_r13;			/* 0x60 */
33977d6d4a2Smlarkin 	uint64_t	vg_r14;			/* 0x68 */
34077d6d4a2Smlarkin 	uint64_t	vg_r15;			/* 0x70 */
34177d6d4a2Smlarkin 	uint64_t	vg_cr2;			/* 0x78 */
34277d6d4a2Smlarkin 	uint64_t	vg_rip;			/* 0x80 */
34377d6d4a2Smlarkin 	uint32_t	vg_exit_reason;		/* 0x88 */
344*172bac09Smlarkin 	uint64_t	vg_rflags;		/* 0x90 */
34577d6d4a2Smlarkin };
34677d6d4a2Smlarkin 
34777d6d4a2Smlarkin /*
3480dd28945Smpi  * Virtual Machine
3490dd28945Smpi  */
3500dd28945Smpi struct vm;
3510dd28945Smpi 
3520dd28945Smpi /*
35377d6d4a2Smlarkin  * Virtual CPU
35477d6d4a2Smlarkin  */
35577d6d4a2Smlarkin struct vcpu {
35677d6d4a2Smlarkin 	/* VMCS / VMCB pointer */
35777d6d4a2Smlarkin 	vaddr_t vc_control_va;
35877d6d4a2Smlarkin 	uint64_t vc_control_pa;
35977d6d4a2Smlarkin 
36077d6d4a2Smlarkin 	/* VLAPIC pointer */
36177d6d4a2Smlarkin 	vaddr_t vc_vlapic_va;
36277d6d4a2Smlarkin 	uint64_t vc_vlapic_pa;
36377d6d4a2Smlarkin 
36477d6d4a2Smlarkin 	/* MSR bitmap address */
36577d6d4a2Smlarkin 	vaddr_t vc_msr_bitmap_va;
36677d6d4a2Smlarkin 	uint64_t vc_msr_bitmap_pa;
36777d6d4a2Smlarkin 
36877d6d4a2Smlarkin 	struct vm *vc_parent;
36977d6d4a2Smlarkin 	uint32_t vc_id;
370e0c038edSmlarkin 	u_int vc_state;
37177d6d4a2Smlarkin 	SLIST_ENTRY(vcpu) vc_vcpu_link;
37277d6d4a2Smlarkin 	vaddr_t vc_hsa_stack_va;
37377d6d4a2Smlarkin 
37477d6d4a2Smlarkin 	uint8_t vc_virt_mode;
37577d6d4a2Smlarkin 
37677d6d4a2Smlarkin 	struct cpu_info *vc_last_pcpu;
37777d6d4a2Smlarkin 	union vm_exit vc_exit;
37877d6d4a2Smlarkin 
3791180136eSmlarkin 	uint16_t vc_intr;
380*172bac09Smlarkin 	uint8_t vc_irqready;
381f3757d05Smlarkin 
38277d6d4a2Smlarkin 	/* VMX only */
38377d6d4a2Smlarkin 	uint64_t vc_vmx_basic;
38477d6d4a2Smlarkin 	uint64_t vc_vmx_entry_ctls;
38577d6d4a2Smlarkin 	uint64_t vc_vmx_true_entry_ctls;
38677d6d4a2Smlarkin 	uint64_t vc_vmx_exit_ctls;
38777d6d4a2Smlarkin 	uint64_t vc_vmx_true_exit_ctls;
38877d6d4a2Smlarkin 	uint64_t vc_vmx_pinbased_ctls;
38977d6d4a2Smlarkin 	uint64_t vc_vmx_true_pinbased_ctls;
39077d6d4a2Smlarkin 	uint64_t vc_vmx_procbased_ctls;
39177d6d4a2Smlarkin 	uint64_t vc_vmx_true_procbased_ctls;
39277d6d4a2Smlarkin 	uint64_t vc_vmx_procbased2_ctls;
39377d6d4a2Smlarkin 	struct vmx_gueststate vc_gueststate;
39477d6d4a2Smlarkin 	vaddr_t vc_vmx_msr_exit_save_va;
39577d6d4a2Smlarkin 	paddr_t vc_vmx_msr_exit_save_pa;
39677d6d4a2Smlarkin 	vaddr_t vc_vmx_msr_exit_load_va;
39777d6d4a2Smlarkin 	paddr_t vc_vmx_msr_exit_load_pa;
39877d6d4a2Smlarkin 	vaddr_t vc_vmx_msr_entry_load_va;
39977d6d4a2Smlarkin 	paddr_t vc_vmx_msr_entry_load_pa;
40077d6d4a2Smlarkin };
40177d6d4a2Smlarkin 
40277d6d4a2Smlarkin SLIST_HEAD(vcpu_head, vcpu);
40377d6d4a2Smlarkin 
40477d6d4a2Smlarkin void	vmm_dispatch_intr(vaddr_t);
40577d6d4a2Smlarkin int	vmxon(uint64_t *);
40677d6d4a2Smlarkin int	vmxoff(void);
40777d6d4a2Smlarkin int	vmclear(uint64_t *);
40877d6d4a2Smlarkin int	vmptrld(uint64_t *);
40977d6d4a2Smlarkin int	vmptrst(uint64_t *);
41077d6d4a2Smlarkin int	vmwrite(uint64_t, uint64_t);
41177d6d4a2Smlarkin int	vmread(uint64_t, uint64_t *);
41277d6d4a2Smlarkin void	invvpid(uint64_t, struct vmx_invvpid_descriptor *);
41377d6d4a2Smlarkin void	invept(uint64_t, struct vmx_invept_descriptor *);
41477d6d4a2Smlarkin int	vmx_enter_guest(uint64_t *, struct vmx_gueststate *, int);
41577d6d4a2Smlarkin void	start_vmm_on_cpu(struct cpu_info *);
41677d6d4a2Smlarkin void	stop_vmm_on_cpu(struct cpu_info *);
41777d6d4a2Smlarkin 
41877d6d4a2Smlarkin #endif /* _KERNEL */
41977d6d4a2Smlarkin 
42077d6d4a2Smlarkin #endif /* ! _MACHINE_VMMVAR_H_ */
421