vmm.h revision 268777
1139749Simp/*- 2117632Sharti * Copyright (c) 2011 NetApp, Inc. 3117632Sharti * All rights reserved. 4117632Sharti * 5117632Sharti * Redistribution and use in source and binary forms, with or without 6117632Sharti * modification, are permitted provided that the following conditions 7117632Sharti * are met: 8117632Sharti * 1. Redistributions of source code must retain the above copyright 9117632Sharti * notice, this list of conditions and the following disclaimer. 10117632Sharti * 2. Redistributions in binary form must reproduce the above copyright 11117632Sharti * notice, this list of conditions and the following disclaimer in the 12117632Sharti * documentation and/or other materials provided with the distribution. 13117632Sharti * 14117632Sharti * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15117632Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16117632Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17117632Sharti * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18117632Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19117632Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20117632Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21117632Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22117632Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23117632Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24117632Sharti * SUCH DAMAGE. 25117632Sharti * 26117632Sharti * $FreeBSD: head/sys/amd64/include/vmm.h 268777 2014-07-16 21:26:26Z neel $ 27117632Sharti */ 28117632Sharti 29117632Sharti#ifndef _VMM_H_ 30117632Sharti#define _VMM_H_ 31119418Sobrien 32117632Shartienum vm_suspend_how { 33117632Sharti VM_SUSPEND_NONE, 34117632Sharti VM_SUSPEND_RESET, 35117632Sharti VM_SUSPEND_POWEROFF, 36117632Sharti VM_SUSPEND_HALT, 37117632Sharti VM_SUSPEND_LAST 38117632Sharti}; 39117632Sharti 40117632Sharti/* 41117632Sharti * Identifiers for architecturally defined registers. 42117632Sharti */ 43117632Shartienum vm_reg_name { 44117632Sharti VM_REG_GUEST_RAX, 45117632Sharti VM_REG_GUEST_RBX, 46117632Sharti VM_REG_GUEST_RCX, 47117632Sharti VM_REG_GUEST_RDX, 48117632Sharti VM_REG_GUEST_RSI, 49117632Sharti VM_REG_GUEST_RDI, 50117632Sharti VM_REG_GUEST_RBP, 51117632Sharti VM_REG_GUEST_R8, 52117632Sharti VM_REG_GUEST_R9, 53117632Sharti VM_REG_GUEST_R10, 54117632Sharti VM_REG_GUEST_R11, 55117632Sharti VM_REG_GUEST_R12, 56117632Sharti VM_REG_GUEST_R13, 57117632Sharti VM_REG_GUEST_R14, 58117632Sharti VM_REG_GUEST_R15, 59117632Sharti VM_REG_GUEST_CR0, 60117632Sharti VM_REG_GUEST_CR3, 61117632Sharti VM_REG_GUEST_CR4, 62117632Sharti VM_REG_GUEST_DR7, 63117632Sharti VM_REG_GUEST_RSP, 64117632Sharti VM_REG_GUEST_RIP, 65117632Sharti VM_REG_GUEST_RFLAGS, 66117632Sharti VM_REG_GUEST_ES, 67117632Sharti VM_REG_GUEST_CS, 68117632Sharti VM_REG_GUEST_SS, 69117632Sharti VM_REG_GUEST_DS, 70117632Sharti VM_REG_GUEST_FS, 71117632Sharti VM_REG_GUEST_GS, 72117632Sharti VM_REG_GUEST_LDTR, 73117632Sharti VM_REG_GUEST_TR, 74117632Sharti VM_REG_GUEST_IDTR, 75117632Sharti VM_REG_GUEST_GDTR, 76117632Sharti VM_REG_GUEST_EFER, 77117632Sharti VM_REG_GUEST_CR2, 78117632Sharti VM_REG_GUEST_PDPTE0, 79117632Sharti VM_REG_GUEST_PDPTE1, 80117632Sharti VM_REG_GUEST_PDPTE2, 81117632Sharti VM_REG_GUEST_PDPTE3, 82117632Sharti VM_REG_LAST 83117632Sharti}; 84117632Sharti 85117632Shartienum x2apic_state { 86117632Sharti X2APIC_DISABLED, 87117632Sharti X2APIC_ENABLED, 88117632Sharti X2APIC_STATE_LAST 89117632Sharti}; 90117632Sharti 91117632Sharti#ifdef _KERNEL 92117632Sharti 93117632Sharti#define VM_MAX_NAMELEN 32 94117632Sharti 95117632Shartistruct vm; 96117632Shartistruct vm_exception; 97117632Shartistruct vm_memory_segment; 98117632Shartistruct seg_desc; 99117632Shartistruct vm_exit; 100117632Shartistruct vm_run; 101117632Shartistruct vhpet; 102117632Shartistruct vioapic; 103117632Shartistruct vlapic; 104117632Shartistruct vmspace; 105117632Shartistruct vm_object; 106117632Shartistruct pmap; 107117632Sharti 108117632Shartitypedef int (*vmm_init_func_t)(int ipinum); 109117632Shartitypedef int (*vmm_cleanup_func_t)(void); 110117632Shartitypedef void (*vmm_resume_func_t)(void); 111117632Shartitypedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap); 112117632Shartitypedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip, 113117632Sharti struct pmap *pmap, void *rendezvous_cookie, 114117632Sharti void *suspend_cookie); 115117632Shartitypedef void (*vmi_cleanup_func_t)(void *vmi); 116117632Shartitypedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, 117117632Sharti uint64_t *retval); 118117632Shartitypedef int (*vmi_set_register_t)(void *vmi, int vcpu, int num, 119117632Sharti uint64_t val); 120117632Shartitypedef int (*vmi_get_desc_t)(void *vmi, int vcpu, int num, 121117632Sharti struct seg_desc *desc); 122117632Shartitypedef int (*vmi_set_desc_t)(void *vmi, int vcpu, int num, 123117632Sharti struct seg_desc *desc); 124117632Shartitypedef int (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval); 125117632Shartitypedef int (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val); 126117632Shartitypedef struct vmspace * (*vmi_vmspace_alloc)(vm_offset_t min, vm_offset_t max); 127117632Shartitypedef void (*vmi_vmspace_free)(struct vmspace *vmspace); 128117632Shartitypedef struct vlapic * (*vmi_vlapic_init)(void *vmi, int vcpu); 129117632Shartitypedef void (*vmi_vlapic_cleanup)(void *vmi, struct vlapic *vlapic); 130117632Sharti 131117632Shartistruct vmm_ops { 132117632Sharti vmm_init_func_t init; /* module wide initialization */ 133117632Sharti vmm_cleanup_func_t cleanup; 134117632Sharti vmm_resume_func_t resume; 135117632Sharti 136117632Sharti vmi_init_func_t vminit; /* vm-specific initialization */ 137117632Sharti vmi_run_func_t vmrun; 138117632Sharti vmi_cleanup_func_t vmcleanup; 139117632Sharti vmi_get_register_t vmgetreg; 140117632Sharti vmi_set_register_t vmsetreg; 141117632Sharti vmi_get_desc_t vmgetdesc; 142117632Sharti vmi_set_desc_t vmsetdesc; 143117632Sharti vmi_get_cap_t vmgetcap; 144117632Sharti vmi_set_cap_t vmsetcap; 145117632Sharti vmi_vmspace_alloc vmspace_alloc; 146117632Sharti vmi_vmspace_free vmspace_free; 147117632Sharti vmi_vlapic_init vlapic_init; 148117632Sharti vmi_vlapic_cleanup vlapic_cleanup; 149117632Sharti}; 150117632Sharti 151117632Shartiextern struct vmm_ops vmm_ops_intel; 152117632Shartiextern struct vmm_ops vmm_ops_amd; 153117632Sharti 154117632Shartiint vm_create(const char *name, struct vm **retvm); 155117632Shartivoid vm_destroy(struct vm *vm); 156117632Shartiint vm_reinit(struct vm *vm); 157117632Sharticonst char *vm_name(struct vm *vm); 158117632Shartiint vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); 159117632Shartiint vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); 160117632Shartiint vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); 161117632Shartivoid *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, 162117632Sharti void **cookie); 163117632Shartivoid vm_gpa_release(void *cookie); 164117632Shartiint vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, 165117632Sharti struct vm_memory_segment *seg); 166117632Shartiint vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, 167117632Sharti vm_offset_t *offset, struct vm_object **object); 168117632Shartiboolean_t vm_mem_allocated(struct vm *vm, vm_paddr_t gpa); 169117632Shartiint vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); 170117632Shartiint vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); 171117632Shartiint vm_get_seg_desc(struct vm *vm, int vcpu, int reg, 172117632Sharti struct seg_desc *ret_desc); 173117632Shartiint vm_set_seg_desc(struct vm *vm, int vcpu, int reg, 174117632Sharti struct seg_desc *desc); 175117632Shartiint vm_run(struct vm *vm, struct vm_run *vmrun); 176117632Shartiint vm_suspend(struct vm *vm, enum vm_suspend_how how); 177117632Shartiint vm_inject_nmi(struct vm *vm, int vcpu); 178117632Shartiint vm_nmi_pending(struct vm *vm, int vcpuid); 179117632Shartivoid vm_nmi_clear(struct vm *vm, int vcpuid); 180117632Shartiint vm_inject_extint(struct vm *vm, int vcpu); 181117632Shartiint vm_extint_pending(struct vm *vm, int vcpuid); 182117632Shartivoid vm_extint_clear(struct vm *vm, int vcpuid); 183117632Shartiuint64_t *vm_guest_msrs(struct vm *vm, int cpu); 184117632Shartistruct vlapic *vm_lapic(struct vm *vm, int cpu); 185117632Shartistruct vioapic *vm_ioapic(struct vm *vm); 186117632Shartistruct vhpet *vm_hpet(struct vm *vm); 187117632Shartiint vm_get_capability(struct vm *vm, int vcpu, int type, int *val); 188117632Shartiint vm_set_capability(struct vm *vm, int vcpu, int type, int val); 189117632Shartiint vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state); 190117632Shartiint vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state); 191117632Shartiint vm_apicid2vcpuid(struct vm *vm, int apicid); 192117632Shartiint vm_activate_cpu(struct vm *vm, int vcpu); 193117632Sharticpuset_t vm_active_cpus(struct vm *vm); 194117632Sharticpuset_t vm_suspended_cpus(struct vm *vm); 195117632Shartistruct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid); 196117632Shartivoid vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip); 197117632Shartivoid vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip); 198117632Shartivoid vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip); 199117632Sharti 200117632Sharti/* 201117632Sharti * Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'. 202117632Sharti * The rendezvous 'func(arg)' is not allowed to do anything that will 203117632Sharti * cause the thread to be put to sleep. 204117632Sharti * 205117632Sharti * If the rendezvous is being initiated from a vcpu context then the 206117632Sharti * 'vcpuid' must refer to that vcpu, otherwise it should be set to -1. 207148887Srwatson * 208117632Sharti * The caller cannot hold any locks when initiating the rendezvous. 209117632Sharti * 210117632Sharti * The implementation of this API may cause vcpus other than those specified 211117632Sharti * by 'dest' to be stalled. The caller should not rely on any vcpus making 212117632Sharti * forward progress when the rendezvous is in progress. 213117632Sharti */ 214118158Shartitypedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg); 215118601Shartivoid vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest, 216118601Sharti vm_rendezvous_func_t func, void *arg); 217118601Sharti 218118601Shartistatic __inline int 219147256Sbrooksvcpu_rendezvous_pending(void *rendezvous_cookie) 220118158Sharti{ 221117632Sharti 222117632Sharti return (*(uintptr_t *)rendezvous_cookie != 0); 223117632Sharti} 224117632Sharti 225117632Shartistatic __inline int 226117632Shartivcpu_suspended(void *suspend_cookie) 227117632Sharti{ 228117632Sharti 229117632Sharti return (*(int *)suspend_cookie); 230117632Sharti} 231117632Sharti 232117632Sharti/* 233117632Sharti * Return 1 if device indicated by bus/slot/func is supposed to be a 234117632Sharti * pci passthrough device. 235117632Sharti * 236117632Sharti * Return 0 otherwise. 237117632Sharti */ 238117632Shartiint vmm_is_pptdev(int bus, int slot, int func); 239117632Sharti 240117632Shartivoid *vm_iommu_domain(struct vm *vm); 241117632Sharti 242117632Shartienum vcpu_state { 243117632Sharti VCPU_IDLE, 244117632Sharti VCPU_FROZEN, 245117632Sharti VCPU_RUNNING, 246117632Sharti VCPU_SLEEPING, 247117632Sharti}; 248148887Srwatson 249117632Shartiint vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state, 250117632Sharti bool from_idle); 251117632Shartienum vcpu_state vcpu_get_state(struct vm *vm, int vcpu, int *hostcpu); 252117632Sharti 253117632Shartistatic int __inline 254117632Shartivcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) 255117632Sharti{ 256117632Sharti return (vcpu_get_state(vm, vcpu, hostcpu) == VCPU_RUNNING); 257117632Sharti} 258117632Sharti 259117632Shartivoid *vcpu_stats(struct vm *vm, int vcpu); 260117632Shartivoid vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr); 261117632Shartistruct vmspace *vm_get_vmspace(struct vm *vm); 262117632Shartiint vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); 263117632Shartiint vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); 264117632Shartistruct vatpic *vm_atpic(struct vm *vm); 265117632Shartistruct vatpit *vm_atpit(struct vm *vm); 266117632Sharti 267117632Sharti/* 268148887Srwatson * Inject exception 'vme' into the guest vcpu. This function returns 0 on 269117632Sharti * success and non-zero on failure. 270126396Sscottl * 271117632Sharti * Wrapper functions like 'vm_inject_gp()' should be preferred to calling 272117632Sharti * this function directly because they enforce the trap-like or fault-like 273117632Sharti * behavior of an exception. 274117632Sharti * 275117632Sharti * This function should only be called in the context of the thread that is 276117632Sharti * executing this vcpu. 277117632Sharti */ 278117632Shartiint vm_inject_exception(struct vm *vm, int vcpuid, struct vm_exception *vme); 279117632Sharti 280117632Sharti/* 281117632Sharti * Returns 0 if there is no exception pending for this vcpu. Returns 1 if an 282117632Sharti * exception is pending and also updates 'vme'. The pending exception is 283117632Sharti * cleared when this function returns. 284117632Sharti * 285117632Sharti * This function should only be called in the context of the thread that is 286117632Sharti * executing this vcpu. 287117632Sharti */ 288117632Shartiint vm_exception_pending(struct vm *vm, int vcpuid, struct vm_exception *vme); 289118601Sharti 290117632Shartivoid vm_inject_gp(struct vm *vm, int vcpuid); /* general protection fault */ 291118601Shartivoid vm_inject_ud(struct vm *vm, int vcpuid); /* undefined instruction fault */ 292118601Shartivoid vm_inject_pf(struct vm *vm, int vcpuid, int error_code, uint64_t cr2); 293118601Sharti 294117632Shartienum vm_reg_name vm_segment_name(int seg_encoding); 295118601Sharti 296118601Sharti#endif /* KERNEL */ 297117632Sharti 298117632Sharti#define VM_MAXCPU 16 /* maximum virtual cpus */ 299117632Sharti 300118601Sharti/* 301118601Sharti * Identifiers for optional vmm capabilities 302118601Sharti */ 303118601Shartienum vm_cap_type { 304117632Sharti VM_CAP_HALT_EXIT, 305117632Sharti VM_CAP_MTRAP_EXIT, 306117632Sharti VM_CAP_PAUSE_EXIT, 307117632Sharti VM_CAP_UNRESTRICTED_GUEST, 308117632Sharti VM_CAP_ENABLE_INVPCID, 309117632Sharti VM_CAP_MAX 310117632Sharti}; 311117632Sharti 312117632Shartienum vm_intr_trigger { 313117632Sharti EDGE_TRIGGER, 314117632Sharti LEVEL_TRIGGER 315117632Sharti}; 316117632Sharti 317117632Sharti/* 318117632Sharti * The 'access' field has the format specified in Table 21-2 of the Intel 319117632Sharti * Architecture Manual vol 3b. 320117632Sharti * 321117632Sharti * XXX The contents of the 'access' field are architecturally defined except 322254804Sandre * bit 16 - Segment Unusable. 323117632Sharti */ 324117632Shartistruct seg_desc { 325117632Sharti uint64_t base; 326117632Sharti uint32_t limit; 327117632Sharti uint32_t access; 328117632Sharti}; 329117632Sharti#define SEG_DESC_TYPE(access) ((access) & 0x001f) 330117632Sharti#define SEG_DESC_DPL(access) (((access) >> 5) & 0x3) 331117632Sharti#define SEG_DESC_PRESENT(access) (((access) & 0x0080) ? 1 : 0) 332117632Sharti#define SEG_DESC_DEF32(access) (((access) & 0x4000) ? 1 : 0) 333117632Sharti#define SEG_DESC_GRANULARITY(access) (((access) & 0x8000) ? 1 : 0) 334117632Sharti#define SEG_DESC_UNUSABLE(access) (((access) & 0x10000) ? 1 : 0) 335117632Sharti 336117632Shartienum vm_cpu_mode { 337118158Sharti CPU_MODE_REAL, 338147256Sbrooks CPU_MODE_PROTECTED, 339118158Sharti CPU_MODE_COMPATIBILITY, /* IA-32E mode (CS.L = 0) */ 340117632Sharti CPU_MODE_64BIT, /* IA-32E mode (CS.L = 1) */ 341117632Sharti}; 342117632Sharti 343117632Shartienum vm_paging_mode { 344117632Sharti PAGING_MODE_FLAT, 345117632Sharti PAGING_MODE_32, 346117632Sharti PAGING_MODE_PAE, 347117632Sharti PAGING_MODE_64, 348117632Sharti}; 349117632Sharti 350117632Shartistruct vm_guest_paging { 351117632Sharti uint64_t cr3; 352117632Sharti int cpl; 353117632Sharti enum vm_cpu_mode cpu_mode; 354117632Sharti enum vm_paging_mode paging_mode; 355117632Sharti}; 356117632Sharti 357117632Sharti/* 358117632Sharti * The data structures 'vie' and 'vie_op' are meant to be opaque to the 359117632Sharti * consumers of instruction decoding. The only reason why their contents 360117632Sharti * need to be exposed is because they are part of the 'vm_exit' structure. 361117632Sharti */ 362117632Shartistruct vie_op { 363117632Sharti uint8_t op_byte; /* actual opcode byte */ 364117632Sharti uint8_t op_type; /* type of operation (e.g. MOV) */ 365117632Sharti uint16_t op_flags; 366117632Sharti}; 367117632Sharti 368117632Sharti#define VIE_INST_SIZE 15 369117632Shartistruct vie { 370117632Sharti uint8_t inst[VIE_INST_SIZE]; /* instruction bytes */ 371117632Sharti uint8_t num_valid; /* size of the instruction */ 372117632Sharti uint8_t num_processed; 373117632Sharti 374117632Sharti uint8_t addrsize:4, opsize:4; /* address and operand sizes */ 375117632Sharti uint8_t rex_w:1, /* REX prefix */ 376117632Sharti rex_r:1, 377117632Sharti rex_x:1, 378117632Sharti rex_b:1, 379117632Sharti rex_present:1, 380117632Sharti opsize_override:1, /* Operand size override */ 381117632Sharti addrsize_override:1; /* Address size override */ 382117632Sharti 383117632Sharti uint8_t mod:2, /* ModRM byte */ 384117632Sharti reg:4, 385117632Sharti rm:4; 386117632Sharti 387117632Sharti uint8_t ss:2, /* SIB byte */ 388117632Sharti index:4, 389117632Sharti base:4; 390117632Sharti 391117632Sharti uint8_t disp_bytes; 392117632Sharti uint8_t imm_bytes; 393117632Sharti 394117632Sharti uint8_t scale; 395117632Sharti int base_register; /* VM_REG_GUEST_xyz */ 396117632Sharti int index_register; /* VM_REG_GUEST_xyz */ 397117632Sharti 398117632Sharti int64_t displacement; /* optional addr displacement */ 399117632Sharti int64_t immediate; /* optional immediate operand */ 400147256Sbrooks 401117632Sharti uint8_t decoded; /* set to 1 if successfully decoded */ 402117632Sharti 403117632Sharti struct vie_op op; /* opcode description */ 404117632Sharti}; 405117632Sharti 406117632Shartienum vm_exitcode { 407117632Sharti VM_EXITCODE_INOUT, 408117632Sharti VM_EXITCODE_VMX, 409117632Sharti VM_EXITCODE_BOGUS, 410117632Sharti VM_EXITCODE_RDMSR, 411117632Sharti VM_EXITCODE_WRMSR, 412117632Sharti VM_EXITCODE_HLT, 413117632Sharti VM_EXITCODE_MTRAP, 414117632Sharti VM_EXITCODE_PAUSE, 415117632Sharti VM_EXITCODE_PAGING, 416117632Sharti VM_EXITCODE_INST_EMUL, 417117632Sharti VM_EXITCODE_SPINUP_AP, 418117632Sharti VM_EXITCODE_DEPRECATED1, /* used to be SPINDOWN_CPU */ 419117632Sharti VM_EXITCODE_RENDEZVOUS, 420117632Sharti VM_EXITCODE_IOAPIC_EOI, 421117632Sharti VM_EXITCODE_SUSPENDED, 422117632Sharti VM_EXITCODE_INOUT_STR, 423117632Sharti VM_EXITCODE_TASK_SWITCH, 424117632Sharti VM_EXITCODE_MAX 425117632Sharti}; 426117632Sharti 427117632Shartistruct vm_inout { 428117632Sharti uint16_t bytes:3; /* 1 or 2 or 4 */ 429117632Sharti uint16_t in:1; 430117632Sharti uint16_t string:1; 431117632Sharti uint16_t rep:1; 432117632Sharti uint16_t port; 433117632Sharti uint32_t eax; /* valid for out */ 434117632Sharti}; 435117632Sharti 436117632Shartistruct vm_inout_str { 437117632Sharti struct vm_inout inout; /* must be the first element */ 438117632Sharti struct vm_guest_paging paging; 439117632Sharti uint64_t rflags; 440117632Sharti uint64_t cr0; 441117632Sharti uint64_t index; 442117632Sharti uint64_t count; /* rep=1 (%rcx), rep=0 (1) */ 443117632Sharti int addrsize; 444117632Sharti enum vm_reg_name seg_name; 445117632Sharti struct seg_desc seg_desc; 446117632Sharti}; 447117632Sharti 448117632Shartienum task_switch_reason { 449117632Sharti TSR_CALL, 450117632Sharti TSR_IRET, 451117632Sharti TSR_JMP, 452117632Sharti TSR_IDT_GATE, /* task gate in IDT */ 453117632Sharti}; 454117632Sharti 455117632Shartistruct vm_task_switch { 456117632Sharti uint16_t tsssel; /* new TSS selector */ 457117632Sharti int ext; /* task switch due to external event */ 458117632Sharti uint32_t errcode; 459117632Sharti int errcode_valid; /* push 'errcode' on the new stack */ 460117632Sharti enum task_switch_reason reason; 461117632Sharti struct vm_guest_paging paging; 462117632Sharti}; 463117632Sharti 464117632Shartistruct vm_exit { 465117632Sharti enum vm_exitcode exitcode; 466117632Sharti int inst_length; /* 0 means unknown */ 467117632Sharti uint64_t rip; 468117632Sharti union { 469117632Sharti struct vm_inout inout; 470117632Sharti struct vm_inout_str inout_str; 471117632Sharti struct { 472117632Sharti uint64_t gpa; 473117632Sharti int fault_type; 474117632Sharti } paging; 475117632Sharti struct { 476117632Sharti uint64_t gpa; 477117632Sharti uint64_t gla; 478117632Sharti int cs_d; /* CS.D */ 479117632Sharti struct vm_guest_paging paging; 480117632Sharti struct vie vie; 481117632Sharti } inst_emul; 482117632Sharti /* 483117632Sharti * VMX specific payload. Used when there is no "better" 484117632Sharti * exitcode to represent the VM-exit. 485117632Sharti */ 486117632Sharti struct { 487117632Sharti int status; /* vmx inst status */ 488117632Sharti /* 489117632Sharti * 'exit_reason' and 'exit_qualification' are valid 490117632Sharti * only if 'status' is zero. 491117632Sharti */ 492117632Sharti uint32_t exit_reason; 493117632Sharti uint64_t exit_qualification; 494117632Sharti /* 495117632Sharti * 'inst_error' and 'inst_type' are valid 496117632Sharti * only if 'status' is non-zero. 497117632Sharti */ 498117632Sharti int inst_type; 499117632Sharti int inst_error; 500117632Sharti } vmx; 501117632Sharti struct { 502117632Sharti uint32_t code; /* ecx value */ 503117632Sharti uint64_t wval; 504117632Sharti } msr; 505117632Sharti struct { 506117632Sharti int vcpu; 507117632Sharti uint64_t rip; 508117632Sharti } spinup_ap; 509117632Sharti struct { 510117632Sharti uint64_t rflags; 511117632Sharti } hlt; 512 struct { 513 int vector; 514 } ioapic_eoi; 515 struct { 516 enum vm_suspend_how how; 517 } suspended; 518 struct vm_task_switch task_switch; 519 } u; 520}; 521 522#endif /* _VMM_H_ */ 523