]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/amd64/include/vmm.h
MFC @ r266724
[FreeBSD/FreeBSD.git] / sys / amd64 / include / vmm.h
1 /*-
2  * Copyright (c) 2011 NetApp, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #ifndef _VMM_H_
30 #define _VMM_H_
31
32 enum vm_suspend_how {
33         VM_SUSPEND_NONE,
34         VM_SUSPEND_RESET,
35         VM_SUSPEND_POWEROFF,
36         VM_SUSPEND_HALT,
37         VM_SUSPEND_LAST
38 };
39
40 #ifdef _KERNEL
41
42 #define VM_MAX_NAMELEN  32
43
44 struct vm;
45 struct vm_exception;
46 struct vm_memory_segment;
47 struct seg_desc;
48 struct vm_exit;
49 struct vm_run;
50 struct vhpet;
51 struct vioapic;
52 struct vlapic;
53 struct vmspace;
54 struct vm_object;
55 struct pmap;
56
57 enum vm_reg_name;
58 enum x2apic_state;
59
60 typedef int     (*vmm_init_func_t)(int ipinum);
61 typedef int     (*vmm_cleanup_func_t)(void);
62 typedef void    (*vmm_resume_func_t)(void);
63 typedef void *  (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap);
64 typedef int     (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
65                                   struct pmap *pmap, void *rendezvous_cookie,
66                                   void *suspend_cookie);
67 typedef void    (*vmi_cleanup_func_t)(void *vmi);
68 typedef int     (*vmi_get_register_t)(void *vmi, int vcpu, int num,
69                                       uint64_t *retval);
70 typedef int     (*vmi_set_register_t)(void *vmi, int vcpu, int num,
71                                       uint64_t val);
72 typedef int     (*vmi_get_desc_t)(void *vmi, int vcpu, int num,
73                                   struct seg_desc *desc);
74 typedef int     (*vmi_set_desc_t)(void *vmi, int vcpu, int num,
75                                   struct seg_desc *desc);
76 typedef int     (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval);
77 typedef int     (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val);
78 typedef struct vmspace * (*vmi_vmspace_alloc)(vm_offset_t min, vm_offset_t max);
79 typedef void    (*vmi_vmspace_free)(struct vmspace *vmspace);
80 typedef struct vlapic * (*vmi_vlapic_init)(void *vmi, int vcpu);
81 typedef void    (*vmi_vlapic_cleanup)(void *vmi, struct vlapic *vlapic);
82
83 struct vmm_ops {
84         vmm_init_func_t         init;           /* module wide initialization */
85         vmm_cleanup_func_t      cleanup;
86         vmm_resume_func_t       resume;
87
88         vmi_init_func_t         vminit;         /* vm-specific initialization */
89         vmi_run_func_t          vmrun;
90         vmi_cleanup_func_t      vmcleanup;
91         vmi_get_register_t      vmgetreg;
92         vmi_set_register_t      vmsetreg;
93         vmi_get_desc_t          vmgetdesc;
94         vmi_set_desc_t          vmsetdesc;
95         vmi_get_cap_t           vmgetcap;
96         vmi_set_cap_t           vmsetcap;
97         vmi_vmspace_alloc       vmspace_alloc;
98         vmi_vmspace_free        vmspace_free;
99         vmi_vlapic_init         vlapic_init;
100         vmi_vlapic_cleanup      vlapic_cleanup;
101 };
102
103 extern struct vmm_ops vmm_ops_intel;
104 extern struct vmm_ops vmm_ops_amd;
105
106 int vm_create(const char *name, struct vm **retvm);
107 void vm_destroy(struct vm *vm);
108 const char *vm_name(struct vm *vm);
109 int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len);
110 int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
111 int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len);
112 void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot,
113                   void **cookie);
114 void vm_gpa_release(void *cookie);
115 int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase,
116               struct vm_memory_segment *seg);
117 int vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len,
118                   vm_offset_t *offset, struct vm_object **object);
119 boolean_t vm_mem_allocated(struct vm *vm, vm_paddr_t gpa);
120 int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval);
121 int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val);
122 int vm_get_seg_desc(struct vm *vm, int vcpu, int reg,
123                     struct seg_desc *ret_desc);
124 int vm_set_seg_desc(struct vm *vm, int vcpu, int reg,
125                     struct seg_desc *desc);
126 int vm_run(struct vm *vm, struct vm_run *vmrun);
127 int vm_suspend(struct vm *vm, enum vm_suspend_how how);
128 int vm_inject_nmi(struct vm *vm, int vcpu);
129 int vm_nmi_pending(struct vm *vm, int vcpuid);
130 void vm_nmi_clear(struct vm *vm, int vcpuid);
131 int vm_inject_extint(struct vm *vm, int vcpu);
132 int vm_extint_pending(struct vm *vm, int vcpuid);
133 void vm_extint_clear(struct vm *vm, int vcpuid);
134 uint64_t *vm_guest_msrs(struct vm *vm, int cpu);
135 struct vlapic *vm_lapic(struct vm *vm, int cpu);
136 struct vioapic *vm_ioapic(struct vm *vm);
137 struct vhpet *vm_hpet(struct vm *vm);
138 int vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
139 int vm_set_capability(struct vm *vm, int vcpu, int type, int val);
140 int vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state);
141 int vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state);
142 int vm_apicid2vcpuid(struct vm *vm, int apicid);
143 void vm_activate_cpu(struct vm *vm, int vcpu);
144 cpuset_t vm_active_cpus(struct vm *vm);
145 struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
146 void vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip);
147
148 /*
149  * Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'.
150  * The rendezvous 'func(arg)' is not allowed to do anything that will
151  * cause the thread to be put to sleep.
152  *
153  * If the rendezvous is being initiated from a vcpu context then the
154  * 'vcpuid' must refer to that vcpu, otherwise it should be set to -1.
155  *
156  * The caller cannot hold any locks when initiating the rendezvous.
157  *
158  * The implementation of this API may cause vcpus other than those specified
159  * by 'dest' to be stalled. The caller should not rely on any vcpus making
160  * forward progress when the rendezvous is in progress.
161  */
162 typedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg);
163 void vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest,
164     vm_rendezvous_func_t func, void *arg);
165
166 static __inline int
167 vcpu_rendezvous_pending(void *rendezvous_cookie)
168 {
169
170         return (*(uintptr_t *)rendezvous_cookie != 0);
171 }
172
173 static __inline int
174 vcpu_suspended(void *suspend_cookie)
175 {
176
177         return (*(int *)suspend_cookie);
178 }
179
180 /*
181  * Return 1 if device indicated by bus/slot/func is supposed to be a
182  * pci passthrough device.
183  *
184  * Return 0 otherwise.
185  */
186 int vmm_is_pptdev(int bus, int slot, int func);
187
188 void *vm_iommu_domain(struct vm *vm);
189
190 enum vcpu_state {
191         VCPU_IDLE,
192         VCPU_FROZEN,
193         VCPU_RUNNING,
194         VCPU_SLEEPING,
195 };
196
197 int vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state,
198     bool from_idle);
199 enum vcpu_state vcpu_get_state(struct vm *vm, int vcpu, int *hostcpu);
200
201 static int __inline
202 vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu)
203 {
204         return (vcpu_get_state(vm, vcpu, hostcpu) == VCPU_RUNNING);
205 }
206
207 void *vcpu_stats(struct vm *vm, int vcpu);
208 void vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr);
209 struct vmspace *vm_get_vmspace(struct vm *vm);
210 int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func);
211 int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func);
212 struct vatpic *vm_atpic(struct vm *vm);
213 struct vatpit *vm_atpit(struct vm *vm);
214
215 /*
216  * Inject exception 'vme' into the guest vcpu. This function returns 0 on
217  * success and non-zero on failure.
218  *
219  * Wrapper functions like 'vm_inject_gp()' should be preferred to calling
220  * this function directly because they enforce the trap-like or fault-like
221  * behavior of an exception.
222  *
223  * This function should only be called in the context of the thread that is
224  * executing this vcpu.
225  */
226 int vm_inject_exception(struct vm *vm, int vcpuid, struct vm_exception *vme);
227
228 /*
229  * Returns 0 if there is no exception pending for this vcpu. Returns 1 if an
230  * exception is pending and also updates 'vme'. The pending exception is
231  * cleared when this function returns.
232  *
233  * This function should only be called in the context of the thread that is
234  * executing this vcpu.
235  */
236 int vm_exception_pending(struct vm *vm, int vcpuid, struct vm_exception *vme);
237
238 void vm_inject_gp(struct vm *vm, int vcpuid); /* general protection fault */
239 void vm_inject_ud(struct vm *vm, int vcpuid); /* undefined instruction fault */
240 void vm_inject_pf(struct vm *vm, int vcpuid, int error_code, uint64_t cr2);
241
242 enum vm_reg_name vm_segment_name(int seg_encoding);
243
244 #endif  /* KERNEL */
245
246 #define VM_MAXCPU       16                      /* maximum virtual cpus */
247
248 /*
249  * Identifiers for architecturally defined registers.
250  */
251 enum vm_reg_name {
252         VM_REG_GUEST_RAX,
253         VM_REG_GUEST_RBX,
254         VM_REG_GUEST_RCX,
255         VM_REG_GUEST_RDX,
256         VM_REG_GUEST_RSI,
257         VM_REG_GUEST_RDI,
258         VM_REG_GUEST_RBP,
259         VM_REG_GUEST_R8,
260         VM_REG_GUEST_R9,
261         VM_REG_GUEST_R10,
262         VM_REG_GUEST_R11,
263         VM_REG_GUEST_R12,
264         VM_REG_GUEST_R13,
265         VM_REG_GUEST_R14,
266         VM_REG_GUEST_R15,
267         VM_REG_GUEST_CR0,
268         VM_REG_GUEST_CR3,
269         VM_REG_GUEST_CR4,
270         VM_REG_GUEST_DR7,
271         VM_REG_GUEST_RSP,
272         VM_REG_GUEST_RIP,
273         VM_REG_GUEST_RFLAGS,
274         VM_REG_GUEST_ES,
275         VM_REG_GUEST_CS,
276         VM_REG_GUEST_SS,
277         VM_REG_GUEST_DS,
278         VM_REG_GUEST_FS,
279         VM_REG_GUEST_GS,
280         VM_REG_GUEST_LDTR,
281         VM_REG_GUEST_TR,
282         VM_REG_GUEST_IDTR,
283         VM_REG_GUEST_GDTR,
284         VM_REG_GUEST_EFER,
285         VM_REG_GUEST_CR2,
286         VM_REG_LAST
287 };
288
289 /*
290  * Identifiers for optional vmm capabilities
291  */
292 enum vm_cap_type {
293         VM_CAP_HALT_EXIT,
294         VM_CAP_MTRAP_EXIT,
295         VM_CAP_PAUSE_EXIT,
296         VM_CAP_UNRESTRICTED_GUEST,
297         VM_CAP_ENABLE_INVPCID,
298         VM_CAP_MAX
299 };
300
301 enum x2apic_state {
302         X2APIC_DISABLED,
303         X2APIC_ENABLED,
304         X2APIC_STATE_LAST
305 };
306
307 enum vm_intr_trigger {
308         EDGE_TRIGGER,
309         LEVEL_TRIGGER
310 };
311         
312 /*
313  * The 'access' field has the format specified in Table 21-2 of the Intel
314  * Architecture Manual vol 3b.
315  *
316  * XXX The contents of the 'access' field are architecturally defined except
317  * bit 16 - Segment Unusable.
318  */
319 struct seg_desc {
320         uint64_t        base;
321         uint32_t        limit;
322         uint32_t        access;
323 };
324 #define SEG_DESC_TYPE(desc)             ((desc)->access & 0x001f)
325 #define SEG_DESC_PRESENT(desc)          ((desc)->access & 0x0080)
326 #define SEG_DESC_DEF32(desc)            ((desc)->access & 0x4000)
327 #define SEG_DESC_GRANULARITY(desc)      ((desc)->access & 0x8000)
328 #define SEG_DESC_UNUSABLE(desc)         ((desc)->access & 0x10000)
329
330 enum vm_cpu_mode {
331         CPU_MODE_COMPATIBILITY,         /* IA-32E mode (CS.L = 0) */
332         CPU_MODE_64BIT,                 /* IA-32E mode (CS.L = 1) */
333 };
334
335 enum vm_paging_mode {
336         PAGING_MODE_FLAT,
337         PAGING_MODE_32,
338         PAGING_MODE_PAE,
339         PAGING_MODE_64,
340 };
341
342 struct vm_guest_paging {
343         uint64_t        cr3;
344         int             cpl;
345         enum vm_cpu_mode cpu_mode;
346         enum vm_paging_mode paging_mode;
347 };
348
349 /*
350  * The data structures 'vie' and 'vie_op' are meant to be opaque to the
351  * consumers of instruction decoding. The only reason why their contents
352  * need to be exposed is because they are part of the 'vm_exit' structure.
353  */
354 struct vie_op {
355         uint8_t         op_byte;        /* actual opcode byte */
356         uint8_t         op_type;        /* type of operation (e.g. MOV) */
357         uint16_t        op_flags;
358 };
359
360 #define VIE_INST_SIZE   15
361 struct vie {
362         uint8_t         inst[VIE_INST_SIZE];    /* instruction bytes */
363         uint8_t         num_valid;              /* size of the instruction */
364         uint8_t         num_processed;
365
366         uint8_t         rex_w:1,                /* REX prefix */
367                         rex_r:1,
368                         rex_x:1,
369                         rex_b:1,
370                         rex_present:1;
371
372         uint8_t         mod:2,                  /* ModRM byte */
373                         reg:4,
374                         rm:4;
375
376         uint8_t         ss:2,                   /* SIB byte */
377                         index:4,
378                         base:4;
379
380         uint8_t         disp_bytes;
381         uint8_t         imm_bytes;
382
383         uint8_t         scale;
384         int             base_register;          /* VM_REG_GUEST_xyz */
385         int             index_register;         /* VM_REG_GUEST_xyz */
386
387         int64_t         displacement;           /* optional addr displacement */
388         int64_t         immediate;              /* optional immediate operand */
389
390         uint8_t         decoded;        /* set to 1 if successfully decoded */
391
392         struct vie_op   op;                     /* opcode description */
393 };
394
395 enum vm_exitcode {
396         VM_EXITCODE_INOUT,
397         VM_EXITCODE_VMX,
398         VM_EXITCODE_BOGUS,
399         VM_EXITCODE_RDMSR,
400         VM_EXITCODE_WRMSR,
401         VM_EXITCODE_HLT,
402         VM_EXITCODE_MTRAP,
403         VM_EXITCODE_PAUSE,
404         VM_EXITCODE_PAGING,
405         VM_EXITCODE_INST_EMUL,
406         VM_EXITCODE_SPINUP_AP,
407         VM_EXITCODE_DEPRECATED1,        /* used to be SPINDOWN_CPU */
408         VM_EXITCODE_RENDEZVOUS,
409         VM_EXITCODE_IOAPIC_EOI,
410         VM_EXITCODE_SUSPENDED,
411         VM_EXITCODE_INOUT_STR,
412         VM_EXITCODE_MAX
413 };
414
415 struct vm_inout {
416         uint16_t        bytes:3;        /* 1 or 2 or 4 */
417         uint16_t        in:1;
418         uint16_t        string:1;
419         uint16_t        rep:1;
420         uint16_t        port;
421         uint32_t        eax;            /* valid for out */
422 };
423
424 struct vm_inout_str {
425         struct vm_inout inout;          /* must be the first element */
426         struct vm_guest_paging paging;
427         uint64_t        rflags;
428         uint64_t        cr0;
429         uint64_t        index;
430         uint64_t        count;          /* rep=1 (%rcx), rep=0 (1) */
431         int             addrsize;
432         enum vm_reg_name seg_name;
433         struct seg_desc seg_desc;
434 };
435
436 struct vm_exit {
437         enum vm_exitcode        exitcode;
438         int                     inst_length;    /* 0 means unknown */
439         uint64_t                rip;
440         union {
441                 struct vm_inout inout;
442                 struct vm_inout_str inout_str;
443                 struct {
444                         uint64_t        gpa;
445                         int             fault_type;
446                 } paging;
447                 struct {
448                         uint64_t        gpa;
449                         uint64_t        gla;
450                         struct vm_guest_paging paging;
451                         struct vie      vie;
452                 } inst_emul;
453                 /*
454                  * VMX specific payload. Used when there is no "better"
455                  * exitcode to represent the VM-exit.
456                  */
457                 struct {
458                         int             status;         /* vmx inst status */
459                         /*
460                          * 'exit_reason' and 'exit_qualification' are valid
461                          * only if 'status' is zero.
462                          */
463                         uint32_t        exit_reason;
464                         uint64_t        exit_qualification;
465                         /*
466                          * 'inst_error' and 'inst_type' are valid
467                          * only if 'status' is non-zero.
468                          */
469                         int             inst_type;
470                         int             inst_error;
471                 } vmx;
472                 struct {
473                         uint32_t        code;           /* ecx value */
474                         uint64_t        wval;
475                 } msr;
476                 struct {
477                         int             vcpu;
478                         uint64_t        rip;
479                 } spinup_ap;
480                 struct {
481                         uint64_t        rflags;
482                 } hlt;
483                 struct {
484                         int             vector;
485                 } ioapic_eoi;
486                 struct {
487                         enum vm_suspend_how how;
488                 } suspended;
489         } u;
490 };
491
492 #endif  /* _VMM_H_ */