vmm.h revision 223621
1321369Sdim/*-
2303231Sdim * Copyright (c) 2011 NetApp, Inc.
3353358Sdim * All rights reserved.
4353358Sdim *
5353358Sdim * Redistribution and use in source and binary forms, with or without
6303231Sdim * modification, are permitted provided that the following conditions
7303231Sdim * are met:
8303231Sdim * 1. Redistributions of source code must retain the above copyright
9303231Sdim *    notice, this list of conditions and the following disclaimer.
10303231Sdim * 2. Redistributions in binary form must reproduce the above copyright
11303231Sdim *    notice, this list of conditions and the following disclaimer in the
12303231Sdim *    documentation and/or other materials provided with the distribution.
13303231Sdim *
14327952Sdim * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15321369Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16321369Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17321369Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18321369Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19321369Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20321369Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21321369Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22327952Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23321369Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24321369Sdim * SUCH DAMAGE.
25321369Sdim *
26303231Sdim * $FreeBSD: vmm.h 482 2011-05-09 21:22:43Z grehan $
27321369Sdim */
28321369Sdim
29321369Sdim#ifndef _VMM_H_
30321369Sdim#define	_VMM_H_
31321369Sdim
32321369Sdim#ifdef _KERNEL
33344779Sdim
34321369Sdim#define	VM_MAX_NAMELEN	32
35321369Sdim
36321369Sdimstruct vm;
37321369Sdimstruct vm_memory_segment;
38327952Sdimstruct seg_desc;
39327952Sdimstruct vm_exit;
40327952Sdimstruct vm_run;
41321369Sdimstruct vlapic;
42303231Sdim
43303231Sdimtypedef int	(*vmm_init_func_t)(void);
44353358Sdimtypedef int	(*vmm_cleanup_func_t)(void);
45327952Sdimtypedef void *	(*vmi_init_func_t)(struct vm *vm); /* instance specific apis */
46321369Sdimtypedef int	(*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
47344779Sdim				  struct vm_exit *vmexit);
48303231Sdimtypedef void	(*vmi_cleanup_func_t)(void *vmi);
49303231Sdimtypedef int	(*vmi_mmap_func_t)(void *vmi, vm_paddr_t gpa, vm_paddr_t hpa,
50314564Sdim				   size_t length, vm_memattr_t attr,
51303231Sdim				   int prot, boolean_t superpages_ok);
52303231Sdimtypedef int	(*vmi_get_register_t)(void *vmi, int vcpu, int num,
53321369Sdim				      uint64_t *retval);
54353358Sdimtypedef int	(*vmi_set_register_t)(void *vmi, int vcpu, int num,
55303231Sdim				      uint64_t val);
56321369Sdimtypedef int	(*vmi_get_desc_t)(void *vmi, int vcpu, int num,
57321369Sdim				  struct seg_desc *desc);
58321369Sdimtypedef int	(*vmi_set_desc_t)(void *vmi, int vcpu, int num,
59321369Sdim				  struct seg_desc *desc);
60321369Sdimtypedef int	(*vmi_inject_event_t)(void *vmi, int vcpu,
61321369Sdim				      int type, int vector,
62321369Sdim				      uint32_t code, int code_valid);
63321369Sdimtypedef	int	(*vmi_inject_nmi_t)(void *vmi, int vcpu);
64314564Sdimtypedef int	(*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval);
65321369Sdimtypedef int	(*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val);
66303231Sdim
67321369Sdimstruct vmm_ops {
68303231Sdim	vmm_init_func_t		init;		/* module wide initialization */
69321369Sdim	vmm_cleanup_func_t	cleanup;
70321369Sdim
71353358Sdim	vmi_init_func_t		vminit;		/* vm-specific initialization */
72321369Sdim	vmi_run_func_t		vmrun;
73327952Sdim	vmi_cleanup_func_t	vmcleanup;
74321369Sdim	vmi_mmap_func_t		vmmmap;
75321369Sdim	vmi_get_register_t	vmgetreg;
76321369Sdim	vmi_set_register_t	vmsetreg;
77321369Sdim	vmi_get_desc_t		vmgetdesc;
78327952Sdim	vmi_set_desc_t		vmsetdesc;
79344779Sdim	vmi_inject_event_t	vminject;
80327952Sdim	vmi_inject_nmi_t	vmnmi;
81303231Sdim	vmi_get_cap_t		vmgetcap;
82341825Sdim	vmi_set_cap_t		vmsetcap;
83321369Sdim};
84321369Sdim
85321369Sdimextern struct vmm_ops vmm_ops_intel;
86321369Sdimextern struct vmm_ops vmm_ops_amd;
87321369Sdim
88321369Sdimstruct vm *vm_create(const char *name);
89321369Sdimvoid vm_destroy(struct vm *vm);
90321369Sdimconst char *vm_name(struct vm *vm);
91321369Sdimint vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t *ret_hpa);
92321369Sdimint vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
93321369Sdimint vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len);
94303231Sdimvm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size);
95303231Sdimint vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase,
96303231Sdim	      struct vm_memory_segment *seg);
97303231Sdimint vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval);
98353358Sdimint vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val);
99353358Sdimint vm_get_seg_desc(struct vm *vm, int vcpu, int reg,
100353358Sdim		    struct seg_desc *ret_desc);
101360784Sdimint vm_set_seg_desc(struct vm *vm, int vcpu, int reg,
102360784Sdim		    struct seg_desc *desc);
103353358Sdimint vm_get_pinning(struct vm *vm, int vcpu, int *cpuid);
104353358Sdimint vm_set_pinning(struct vm *vm, int vcpu, int cpuid);
105353358Sdimint vm_run(struct vm *vm, struct vm_run *vmrun);
106353358Sdimint vm_inject_event(struct vm *vm, int vcpu, int type,
107353358Sdim		    int vector, uint32_t error_code, int error_code_valid);
108353358Sdimint vm_inject_nmi(struct vm *vm, int vcpu);
109353358Sdimuint64_t *vm_guest_msrs(struct vm *vm, int cpu);
110353358Sdimstruct vlapic *vm_lapic(struct vm *vm, int cpu);
111353358Sdimint vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
112353358Sdimint vm_set_capability(struct vm *vm, int vcpu, int type, int val);
113353358Sdimvoid vm_activate_cpu(struct vm *vm, int vcpu);
114360784Sdimcpuset_t vm_active_cpus(struct vm *vm);
115360784Sdim
116360784Sdim/*
117360784Sdim * Return 1 if device indicated by bus/slot/func is supposed to be a
118360784Sdim * pci passthrough device.
119360784Sdim *
120360784Sdim * Return 0 otherwise.
121360784Sdim */
122360784Sdimint vmm_is_pptdev(int bus, int slot, int func);
123360784Sdim
124360784Sdimvoid *vm_iommu_domain(struct vm *vm);
125360784Sdim
126360784Sdim#define	VCPU_STOPPED	0
127360784Sdim#define	VCPU_RUNNING	1
128360784Sdimvoid vm_set_run_state(struct vm *vm, int vcpu, int running);
129353358Sdimint vm_get_run_state(struct vm *vm, int vcpu, int *hostcpu);
130353358Sdim
131360784Sdimvoid *vcpu_stats(struct vm *vm, int vcpu);
132353358Sdim
133353358Sdimstatic int __inline
134353358Sdimvcpu_is_running(struct vm *vm, int vcpu, int *hostcpu)
135344779Sdim{
136344779Sdim	return (vm_get_run_state(vm, vcpu, hostcpu) == VCPU_RUNNING);
137344779Sdim}
138344779Sdim
139344779Sdim#endif	/* KERNEL */
140344779Sdim
141344779Sdim#define	VM_MAXCPU	8			/* maximum virtual cpus */
142344779Sdim
143344779Sdim/*
144344779Sdim * Identifiers for events that can be injected into the VM
145344779Sdim */
146344779Sdimenum vm_event_type {
147344779Sdim	VM_EVENT_NONE,
148344779Sdim	VM_HW_INTR,
149327952Sdim	VM_NMI,
150303231Sdim	VM_HW_EXCEPTION,
151321369Sdim	VM_SW_INTR,
152303231Sdim	VM_PRIV_SW_EXCEPTION,
153303231Sdim	VM_SW_EXCEPTION,
154303231Sdim	VM_EVENT_MAX
155303231Sdim};
156303231Sdim
157344779Sdim/*
158303231Sdim * Identifiers for architecturally defined registers.
159303231Sdim */
160303231Sdimenum vm_reg_name {
161303231Sdim	VM_REG_GUEST_RAX,
162344779Sdim	VM_REG_GUEST_RBX,
163344779Sdim	VM_REG_GUEST_RCX,
164344779Sdim	VM_REG_GUEST_RDX,
165344779Sdim	VM_REG_GUEST_RSI,
166344779Sdim	VM_REG_GUEST_RDI,
167344779Sdim	VM_REG_GUEST_RBP,
168344779Sdim	VM_REG_GUEST_R8,
169344779Sdim	VM_REG_GUEST_R9,
170344779Sdim	VM_REG_GUEST_R10,
171344779Sdim	VM_REG_GUEST_R11,
172303231Sdim	VM_REG_GUEST_R12,
173303231Sdim	VM_REG_GUEST_R13,
174303231Sdim	VM_REG_GUEST_R14,
175303231Sdim	VM_REG_GUEST_R15,
176303231Sdim	VM_REG_GUEST_CR0,
177303231Sdim	VM_REG_GUEST_CR3,
178303231Sdim	VM_REG_GUEST_CR4,
179303231Sdim	VM_REG_GUEST_DR7,
180303231Sdim	VM_REG_GUEST_RSP,
181341825Sdim	VM_REG_GUEST_RIP,
182341825Sdim	VM_REG_GUEST_RFLAGS,
183344779Sdim	VM_REG_GUEST_ES,
184344779Sdim	VM_REG_GUEST_CS,
185344779Sdim	VM_REG_GUEST_SS,
186341825Sdim	VM_REG_GUEST_DS,
187341825Sdim	VM_REG_GUEST_FS,
188341825Sdim	VM_REG_GUEST_GS,
189341825Sdim	VM_REG_GUEST_LDTR,
190341825Sdim	VM_REG_GUEST_TR,
191341825Sdim	VM_REG_GUEST_IDTR,
192341825Sdim	VM_REG_GUEST_GDTR,
193303231Sdim	VM_REG_GUEST_EFER,
194303231Sdim	VM_REG_LAST
195303231Sdim};
196303231Sdim
197303231Sdim/*
198303231Sdim * Identifiers for optional vmm capabilities
199303231Sdim */
200303231Sdimenum vm_cap_type {
201303231Sdim	VM_CAP_HALT_EXIT,
202303231Sdim	VM_CAP_MTRAP_EXIT,
203303231Sdim	VM_CAP_PAUSE_EXIT,
204303231Sdim	VM_CAP_UNRESTRICTED_GUEST,
205303231Sdim	VM_CAP_MAX
206303231Sdim};
207303231Sdim
208303231Sdim/*
209303231Sdim * The 'access' field has the format specified in Table 21-2 of the Intel
210303231Sdim * Architecture Manual vol 3b.
211303231Sdim *
212303231Sdim * XXX The contents of the 'access' field are architecturally defined except
213303231Sdim * bit 16 - Segment Unusable.
214303231Sdim */
215303231Sdimstruct seg_desc {
216303231Sdim	uint64_t	base;
217303231Sdim	uint32_t	limit;
218303231Sdim	uint32_t	access;
219303231Sdim};
220303231Sdim
221303231Sdimenum vm_exitcode {
222303231Sdim	VM_EXITCODE_INOUT,
223303231Sdim	VM_EXITCODE_VMX,
224303231Sdim	VM_EXITCODE_BOGUS,
225303231Sdim	VM_EXITCODE_RDMSR,
226303231Sdim	VM_EXITCODE_WRMSR,
227303231Sdim	VM_EXITCODE_HLT,
228303231Sdim	VM_EXITCODE_MTRAP,
229303231Sdim	VM_EXITCODE_PAUSE,
230303231Sdim	VM_EXITCODE_MAX,
231303231Sdim};
232303231Sdim
233303231Sdimstruct vm_exit {
234303231Sdim	enum vm_exitcode	exitcode;
235303231Sdim	int			inst_length;	/* 0 means unknown */
236303231Sdim	uint64_t		rip;
237303231Sdim	union {
238303231Sdim		struct {
239327952Sdim			uint16_t	bytes:3;	/* 1 or 2 or 4 */
240303231Sdim			uint16_t	in:1;		/* out is 0, in is 1 */
241327952Sdim			uint16_t	string:1;
242303231Sdim			uint16_t	rep:1;
243303231Sdim			uint16_t	port;
244341825Sdim			uint32_t	eax;		/* valid for out */
245341825Sdim		} inout;
246341825Sdim		/*
247341825Sdim		 * VMX specific payload. Used when there is no "better"
248341825Sdim		 * exitcode to represent the VM-exit.
249341825Sdim		 */
250341825Sdim		struct {
251341825Sdim			int		error;		/* vmx inst error */
252341825Sdim			uint32_t	exit_reason;
253341825Sdim			uint64_t	exit_qualification;
254341825Sdim		} vmx;
255341825Sdim		struct {
256341825Sdim			uint32_t	code;		/* ecx value */
257327952Sdim			uint64_t	wval;
258341825Sdim		} msr;
259314564Sdim	} u;
260314564Sdim};
261303231Sdim
262303231Sdim#endif	/* _VMM_H_ */
263303231Sdim