vmm.h revision 266339
18549Sjkh/*- 28549Sjkh * Copyright (c) 2011 NetApp, Inc. 38549Sjkh * All rights reserved. 48549Sjkh * 58549Sjkh * Redistribution and use in source and binary forms, with or without 68549Sjkh * modification, are permitted provided that the following conditions 715440Sjkh * are met: 88549Sjkh * 1. Redistributions of source code must retain the above copyright 98549Sjkh * notice, this list of conditions and the following disclaimer. 108549Sjkh * 2. Redistributions in binary form must reproduce the above copyright 118549Sjkh * notice, this list of conditions and the following disclaimer in the 128549Sjkh * documentation and/or other materials provided with the distribution. 138549Sjkh * 148549Sjkh * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 158549Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168881Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 178881Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 188549Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 198549Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 208549Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 218549Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 228549Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 238549Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 248549Sjkh * SUCH DAMAGE. 258549Sjkh * 268549Sjkh * $FreeBSD: stable/10/sys/amd64/include/vmm.h 266339 2014-05-17 19:11:08Z jhb $ 278549Sjkh */ 288549Sjkh 298549Sjkh#ifndef _VMM_H_ 308549Sjkh#define _VMM_H_ 318549Sjkh 328549Sjkh#ifdef _KERNEL 338549Sjkh 348549Sjkh#define VM_MAX_NAMELEN 32 358549Sjkh 368549Sjkhstruct vm; 378549Sjkhstruct vm_memory_segment; 388549Sjkhstruct seg_desc; 398549Sjkhstruct vm_exit; 4010882Speterstruct vm_run; 4110882Speterstruct vhpet; 428549Sjkhstruct vioapic; 438549Sjkhstruct vlapic; 448549Sjkhstruct vmspace; 458549Sjkhstruct vm_object; 468549Sjkhstruct pmap; 478549Sjkh 488549Sjkhenum x2apic_state; 498549Sjkh 508549Sjkhtypedef int (*vmm_init_func_t)(int ipinum); 518549Sjkhtypedef int (*vmm_cleanup_func_t)(void); 528622Sjkhtypedef void (*vmm_resume_func_t)(void); 538549Sjkhtypedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap); 548549Sjkhtypedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip, 558702Sjkh struct pmap *pmap, void *rendezvous_cookie); 568549Sjkhtypedef void (*vmi_cleanup_func_t)(void *vmi); 578672Sjkhtypedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, 5812661Speter uint64_t *retval); 598549Sjkhtypedef int (*vmi_set_register_t)(void *vmi, int vcpu, int num, 6012661Speter uint64_t val); 6112661Spetertypedef int (*vmi_get_desc_t)(void *vmi, int vcpu, int num, 6212661Speter struct seg_desc *desc); 6312661Spetertypedef int (*vmi_set_desc_t)(void *vmi, int vcpu, int num, 6412661Speter struct seg_desc *desc); 6512661Spetertypedef int (*vmi_inject_event_t)(void *vmi, int vcpu, 6612661Speter int type, int vector, 6712661Speter uint32_t code, int code_valid); 6812661Spetertypedef int (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval); 6915440Sjkhtypedef int (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val); 7015440Sjkhtypedef struct vmspace * (*vmi_vmspace_alloc)(vm_offset_t min, vm_offset_t max); 7115440Sjkhtypedef void (*vmi_vmspace_free)(struct vmspace *vmspace); 7215440Sjkhtypedef struct vlapic * (*vmi_vlapic_init)(void *vmi, int vcpu); 738549Sjkhtypedef void (*vmi_vlapic_cleanup)(void *vmi, struct vlapic *vlapic); 748549Sjkh 758549Sjkhstruct vmm_ops { 768549Sjkh vmm_init_func_t init; /* module wide initialization */ 778549Sjkh vmm_cleanup_func_t cleanup; 788549Sjkh vmm_resume_func_t resume; 798549Sjkh 8015440Sjkh vmi_init_func_t vminit; /* vm-specific initialization */ 8115440Sjkh vmi_run_func_t vmrun; 8215440Sjkh vmi_cleanup_func_t vmcleanup; 8312661Speter vmi_get_register_t vmgetreg; 8412661Speter vmi_set_register_t vmsetreg; 8512661Speter vmi_get_desc_t vmgetdesc; 8615091Sjkh vmi_set_desc_t vmsetdesc; 8712661Speter vmi_inject_event_t vminject; 8812661Speter vmi_get_cap_t vmgetcap; 8915242Sjkh vmi_set_cap_t vmsetcap; 9015242Sjkh vmi_vmspace_alloc vmspace_alloc; 9112661Speter vmi_vmspace_free vmspace_free; 9212661Speter vmi_vlapic_init vlapic_init; 9312661Speter vmi_vlapic_cleanup vlapic_cleanup; 9412661Speter}; 9512661Speter 9612661Speterextern struct vmm_ops vmm_ops_intel; 9712661Speterextern struct vmm_ops vmm_ops_amd; 9812661Speter 9915242Sjkhint vm_create(const char *name, struct vm **retvm); 10012661Spetervoid vm_destroy(struct vm *vm); 10115242Sjkhconst char *vm_name(struct vm *vm); 10215242Sjkhint vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); 10315242Sjkhint vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); 10412661Speterint vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); 10515242Sjkhvoid *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, 10615242Sjkh void **cookie); 10715419Sjkhvoid vm_gpa_release(void *cookie); 10815242Sjkhint vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, 10912661Speter struct vm_memory_segment *seg); 11015242Sjkhint vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, 11115419Sjkh vm_offset_t *offset, struct vm_object **object); 11215242Sjkhboolean_t vm_mem_allocated(struct vm *vm, vm_paddr_t gpa); 11312661Speterint vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); 11412661Speterint vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); 11512661Speterint vm_get_seg_desc(struct vm *vm, int vcpu, int reg, 11612661Speter struct seg_desc *ret_desc); 11715091Sjkhint vm_set_seg_desc(struct vm *vm, int vcpu, int reg, 11812661Speter struct seg_desc *desc); 11912661Speterint vm_run(struct vm *vm, struct vm_run *vmrun); 12012661Speterint vm_inject_event(struct vm *vm, int vcpu, int type, 12112661Speter int vector, uint32_t error_code, int error_code_valid); 12212661Speterint vm_inject_nmi(struct vm *vm, int vcpu); 12314670Sjkhint vm_nmi_pending(struct vm *vm, int vcpuid); 12414670Sjkhvoid vm_nmi_clear(struct vm *vm, int vcpuid); 12515242Sjkhuint64_t *vm_guest_msrs(struct vm *vm, int cpu); 12614670Sjkhstruct vlapic *vm_lapic(struct vm *vm, int cpu); 12712661Speterstruct vioapic *vm_ioapic(struct vm *vm); 12812661Speterstruct vhpet *vm_hpet(struct vm *vm); 12915242Sjkhint vm_get_capability(struct vm *vm, int vcpu, int type, int *val); 13012661Speterint vm_set_capability(struct vm *vm, int vcpu, int type, int val); 13112661Speterint vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state); 13215419Sjkhint vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state); 13315242Sjkhint vm_apicid2vcpuid(struct vm *vm, int apicid); 13415419Sjkhvoid vm_activate_cpu(struct vm *vm, int vcpu); 13515242Sjkhcpuset_t vm_active_cpus(struct vm *vm); 13612661Speterstruct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid); 13712661Speter 13812661Speter/* 13915242Sjkh * Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'. 14012661Speter * The rendezvous 'func(arg)' is not allowed to do anything that will 14112661Speter * cause the thread to be put to sleep. 14212661Speter * 14312661Speter * If the rendezvous is being initiated from a vcpu context then the 1448549Sjkh * 'vcpuid' must refer to that vcpu, otherwise it should be set to -1. 1458549Sjkh * 1468549Sjkh * The caller cannot hold any locks when initiating the rendezvous. 1478549Sjkh * 1488549Sjkh * The implementation of this API may cause vcpus other than those specified 1498549Sjkh * by 'dest' to be stalled. The caller should not rely on any vcpus making 1508751Sjkh * forward progress when the rendezvous is in progress. 15114793Sjoerg */ 15214793Sjoergtypedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg); 1538549Sjkhvoid vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest, 1548549Sjkh vm_rendezvous_func_t func, void *arg); 1558549Sjkh 1568549Sjkhstatic __inline int 1578549Sjkhvcpu_rendezvous_pending(void *rendezvous_cookie) 1588549Sjkh{ 1598549Sjkh 1608549Sjkh return (*(uintptr_t *)rendezvous_cookie != 0); 16112661Speter} 1628549Sjkh 1638549Sjkh/* 16412661Speter * Return 1 if device indicated by bus/slot/func is supposed to be a 1658549Sjkh * pci passthrough device. 1668549Sjkh * 1678549Sjkh * Return 0 otherwise. 1688549Sjkh */ 1698549Sjkhint vmm_is_pptdev(int bus, int slot, int func); 1708549Sjkh 1718549Sjkhvoid *vm_iommu_domain(struct vm *vm); 1728549Sjkh 1738549Sjkhenum vcpu_state { 1748549Sjkh VCPU_IDLE, 17512661Speter VCPU_FROZEN, 1768549Sjkh VCPU_RUNNING, 1778549Sjkh VCPU_SLEEPING, 1788549Sjkh}; 1798556Sjkh 1808549Sjkhint vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state); 18115440Sjkhenum vcpu_state vcpu_get_state(struct vm *vm, int vcpu, int *hostcpu); 1828549Sjkh 1838556Sjkhstatic int __inline 1848549Sjkhvcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) 1858556Sjkh{ 1868556Sjkh return (vcpu_get_state(vm, vcpu, hostcpu) == VCPU_RUNNING); 1878556Sjkh} 1888556Sjkh 1898556Sjkhvoid *vcpu_stats(struct vm *vm, int vcpu); 1908549Sjkhvoid vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr); 1918556Sjkhstruct vmspace *vm_get_vmspace(struct vm *vm); 1928556Sjkhint vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); 1938549Sjkhint vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); 1948549Sjkh#endif /* KERNEL */ 1958549Sjkh 1968549Sjkh#include <machine/vmm_instruction_emul.h> 19715440Sjkh 1988549Sjkh#define VM_MAXCPU 16 /* maximum virtual cpus */ 1998549Sjkh 2008549Sjkh/* 20112661Speter * Identifiers for events that can be injected into the VM 2028556Sjkh */ 2038556Sjkhenum vm_event_type { 2048556Sjkh VM_EVENT_NONE, 2058556Sjkh VM_HW_INTR, 2068556Sjkh VM_NMI, 2078549Sjkh VM_HW_EXCEPTION, 2088556Sjkh VM_SW_INTR, 2098549Sjkh VM_PRIV_SW_EXCEPTION, 2108549Sjkh VM_SW_EXCEPTION, 2118549Sjkh VM_EVENT_MAX 2128549Sjkh}; 2138549Sjkh 2148549Sjkh/* 2158549Sjkh * Identifiers for architecturally defined registers. 2168549Sjkh */ 2178549Sjkhenum vm_reg_name { 2188549Sjkh VM_REG_GUEST_RAX, 2198549Sjkh VM_REG_GUEST_RBX, 2208549Sjkh VM_REG_GUEST_RCX, 2218549Sjkh VM_REG_GUEST_RDX, 2228549Sjkh VM_REG_GUEST_RSI, 2238549Sjkh VM_REG_GUEST_RDI, 2248702Sjkh VM_REG_GUEST_RBP, 2258549Sjkh VM_REG_GUEST_R8, 2268549Sjkh VM_REG_GUEST_R9, 2278549Sjkh VM_REG_GUEST_R10, 2288549Sjkh VM_REG_GUEST_R11, 2298549Sjkh VM_REG_GUEST_R12, 2308549Sjkh VM_REG_GUEST_R13, 23115440Sjkh VM_REG_GUEST_R14, 23215440Sjkh VM_REG_GUEST_R15, 23315440Sjkh VM_REG_GUEST_CR0, 23415440Sjkh VM_REG_GUEST_CR3, 2358549Sjkh VM_REG_GUEST_CR4, 2368549Sjkh VM_REG_GUEST_DR7, 2378549Sjkh VM_REG_GUEST_RSP, 2388549Sjkh VM_REG_GUEST_RIP, 2398665Sphk VM_REG_GUEST_RFLAGS, 2408549Sjkh VM_REG_GUEST_ES, 2418549Sjkh VM_REG_GUEST_CS, 2429202Srgrimes VM_REG_GUEST_SS, 2438549Sjkh VM_REG_GUEST_DS, 2449202Srgrimes VM_REG_GUEST_FS, 2459202Srgrimes VM_REG_GUEST_GS, 2469202Srgrimes VM_REG_GUEST_LDTR, 2478549Sjkh VM_REG_GUEST_TR, 2488549Sjkh VM_REG_GUEST_IDTR, 24914335Sjkh VM_REG_GUEST_GDTR, 2508666Sphk VM_REG_GUEST_EFER, 2518669Sphk VM_REG_LAST 2528669Sphk}; 2538820Sjkh 2548820Sjkh/* 2558881Srgrimes * Identifiers for optional vmm capabilities 2568820Sjkh */ 2578666Sphkenum vm_cap_type { 2588666Sphk VM_CAP_HALT_EXIT, 2598665Sphk VM_CAP_MTRAP_EXIT, 2608665Sphk VM_CAP_PAUSE_EXIT, 2618549Sjkh VM_CAP_UNRESTRICTED_GUEST, 2628549Sjkh VM_CAP_ENABLE_INVPCID, 2638549Sjkh VM_CAP_MAX 2648549Sjkh}; 26512661Speter 2668589Sjkhenum x2apic_state { 2678549Sjkh X2APIC_ENABLED, 2688549Sjkh X2APIC_AVAILABLE, 2698549Sjkh X2APIC_DISABLED, 2708549Sjkh X2APIC_STATE_LAST 27114793Sjoerg}; 27214793Sjoerg 2738810Sjkh/* 2748810Sjkh * The 'access' field has the format specified in Table 21-2 of the Intel 2758810Sjkh * Architecture Manual vol 3b. 2768764Sjkh * 2778751Sjkh * XXX The contents of the 'access' field are architecturally defined except 2788751Sjkh * bit 16 - Segment Unusable. 2798751Sjkh */ 28014793Sjoergstruct seg_desc { 28114793Sjoerg uint64_t base; 2828751Sjkh uint32_t limit; 2838669Sphk uint32_t access; 2848751Sjkh}; 2858669Sphk 2868669Sphkenum vm_exitcode { 2878810Sjkh VM_EXITCODE_INOUT, 2888669Sphk VM_EXITCODE_VMX, 2898810Sjkh VM_EXITCODE_BOGUS, 2908810Sjkh VM_EXITCODE_RDMSR, 2918669Sphk VM_EXITCODE_WRMSR, 2928669Sphk VM_EXITCODE_HLT, 2938669Sphk VM_EXITCODE_MTRAP, 2948549Sjkh VM_EXITCODE_PAUSE, 2958810Sjkh VM_EXITCODE_PAGING, 2968810Sjkh VM_EXITCODE_INST_EMUL, 2978669Sphk VM_EXITCODE_SPINUP_AP, 2988669Sphk VM_EXITCODE_SPINDOWN_CPU, 2998669Sphk VM_EXITCODE_RENDEZVOUS, 3008669Sphk VM_EXITCODE_IOAPIC_EOI, 3018810Sjkh VM_EXITCODE_MAX 3028810Sjkh}; 3038669Sphk 3048669Sphkstruct vm_exit { 3058669Sphk enum vm_exitcode exitcode; 3068810Sjkh int inst_length; /* 0 means unknown */ 3078810Sjkh uint64_t rip; 3088669Sphk union { 3098810Sjkh struct { 3108810Sjkh uint16_t bytes:3; /* 1 or 2 or 4 */ 3118669Sphk uint16_t in:1; /* out is 0, in is 1 */ 3128669Sphk uint16_t string:1; 31314793Sjoerg uint16_t rep:1; 3148669Sphk uint16_t port; 3158669Sphk uint32_t eax; /* valid for out */ 3168669Sphk } inout; 3178549Sjkh struct { 3188549Sjkh uint64_t gpa; 3198549Sjkh int fault_type; 3208549Sjkh } paging; 3218549Sjkh struct { 3228549Sjkh uint64_t gpa; 3238549Sjkh uint64_t gla; 3248669Sphk uint64_t cr3; 32515440Sjkh struct vie vie; 3268669Sphk } inst_emul; 3278549Sjkh /* 3288549Sjkh * VMX specific payload. Used when there is no "better" 3298549Sjkh * exitcode to represent the VM-exit. 3308549Sjkh */ 3318549Sjkh struct { 3328549Sjkh int status; /* vmx inst status */ 3338669Sphk /* 33412661Speter * 'exit_reason' and 'exit_qualification' are valid 33512661Speter * only if 'status' is zero. 33612661Speter */ 33715440Sjkh uint32_t exit_reason; 3388669Sphk uint64_t exit_qualification; 3398549Sjkh /* 3408549Sjkh * 'inst_error' and 'inst_type' are valid 3418549Sjkh * only if 'status' is non-zero. 3428549Sjkh */ 3438549Sjkh int inst_type; 3448549Sjkh int inst_error; 3458549Sjkh } vmx; 3468549Sjkh struct { 3478549Sjkh uint32_t code; /* ecx value */ 3488549Sjkh uint64_t wval; 3498549Sjkh } msr; 3508549Sjkh struct { 3518549Sjkh int vcpu; 3528549Sjkh uint64_t rip; 3538549Sjkh } spinup_ap; 35412661Speter struct { 35512661Speter uint64_t rflags; 3568549Sjkh } hlt; 3578549Sjkh struct { 3588549Sjkh int vector; 3598549Sjkh } ioapic_eoi; 3608549Sjkh } u; 3618549Sjkh}; 3628549Sjkh 3638549Sjkh#endif /* _VMM_H_ */ 3648549Sjkh