/* ** Copyright (c) 2011, Intel Corporation ** ** This software is licensed under the terms of the GNU General Public ** License version 2, as published by the Free Software Foundation, and ** may be copied, distributed, and modified under those terms. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. */ #ifndef _HAX_INTERFACE_H #define _HAX_INTERFACE_H /* * Common data structure for HAX interface on both Mac and Windows * The IOCTL is defined in hax-darwin.h and hax-windows.h */ /* fx_layout according to Intel SDM */ struct fx_layout { uint16_t fcw; uint16_t fsw; uint8 ftw; uint8 res1; uint16_t fop; union { struct { uint32 fip; uint16_t fcs; uint16_t res2; }; uint64 fpu_ip; }; union { struct { uint32 fdp; uint16_t fds; uint16_t res3; }; uint64 fpu_dp; }; uint32 mxcsr; uint32 mxcsr_mask; uint8 st_mm[8][16]; uint8 mmx_1[8][16]; uint8 mmx_2[8][16]; uint8 pad[96]; }; struct vmx_msr { uint64 entry; uint64 value; }; /* * Use fixed-size array to make Mac OS X support efficient by avoiding * use memory map or copy-in routines. */ #define HAX_MAX_MSR_ARRAY 0x20 struct hax_msr_data { uint16_t nr_msr; uint16_t done; uint16_t pad[2]; struct vmx_msr entries[HAX_MAX_MSR_ARRAY]; }; union interruptibility_state_t { uint32 raw; struct { uint32 sti_blocking : 1; uint32 movss_blocking : 1; uint32 smi_blocking : 1; uint32 nmi_blocking : 1; uint32 reserved : 28; }; uint64_t pad; }; typedef union interruptibility_state_t interruptibility_state_t; // Segment descriptor struct segment_desc_t { uint16_t selector; uint16_t _dummy; uint32 limit; uint64 base; union { struct { uint32 type : 4; uint32 desc : 1; uint32 dpl : 2; uint32 present : 1; uint32 : 4; uint32 available : 1; uint32 long_mode : 1; uint32 operand_size : 1; uint32 granularity : 1; uint32 null : 1; uint32 : 15; }; uint32 ar; }; uint32 ipad; }; typedef struct segment_desc_t segment_desc_t; struct vcpu_state_t { union { uint64 _regs[16]; struct { union { struct { uint8 _al, _ah; }; uint16_t _ax; uint32 _eax; uint64 _rax; }; union { struct { uint8 _cl, _ch; }; uint16_t _cx; uint32 _ecx; uint64 _rcx; }; union { struct { uint8 _dl, _dh; }; uint16_t _dx; uint32 _edx; uint64 _rdx; }; union { struct { uint8 _bl, _bh; }; uint16_t _bx; uint32 _ebx; uint64 _rbx; }; union { uint16_t _sp; uint32 _esp; uint64 _rsp; }; union { uint16_t _bp; uint32 _ebp; uint64 _rbp; }; union { uint16_t _si; uint32 _esi; uint64 _rsi; }; union { uint16_t _di; uint32 _edi; uint64 _rdi; }; uint64 _r8; uint64 _r9; uint64 _r10; uint64 _r11; uint64 _r12; uint64 _r13; uint64 _r14; uint64 _r15; }; }; union { uint32 _eip; uint64 _rip; }; union { uint32 _eflags; uint64 _rflags; }; segment_desc_t _cs; segment_desc_t _ss; segment_desc_t _ds; segment_desc_t _es; segment_desc_t _fs; segment_desc_t _gs; segment_desc_t _ldt; segment_desc_t _tr; segment_desc_t _gdt; segment_desc_t _idt; uint64 _cr0; uint64 _cr2; uint64 _cr3; uint64 _cr4; uint64 _dr0; uint64 _dr1; uint64 _dr2; uint64 _dr3; uint64 _dr6; uint64 _dr7; uint64 _pde; uint32 _efer; uint32 _sysenter_cs; uint64 _sysenter_eip; uint64 _sysenter_esp; uint32 _activity_state; uint32 pad; interruptibility_state_t _interruptibility_state; }; /* * HAX tunnel is a per-vCPU shared memory between QEMU and HAX driver * It is used to pass information between QEMU and HAX driver, like KVM_RUN * * In HAX_VCPU_IOCTL_SETUP_TUNNEL ioctl, HAX driver allocats the memory, maps * it to QEMU virtual address space and returns the virtual address and size to * QEMU through hax_tunnel_info structure */ struct hax_tunnel { uint32_t _exit_reason; uint32_t _exit_flag; uint32_t _exit_status; uint32_t user_event_pending; int ready_for_interrupt_injection; int request_interrupt_window; union { struct { /* 0: read, 1: write */ #define HAX_EXIT_IO_IN 1 #define HAX_EXIT_IO_OUT 0 uint8_t _direction; uint8_t _df; uint16_t _size; uint16_t _port; uint16_t _count; uint8_t _flags; uint8_t _pad0; uint16_t _pad1; uint32_t _pad2; uint64_t _vaddr; } pio; struct { uint64_t gla; } mmio; struct { } state; }; }; struct hax_tunnel_info { uint64_t va; uint64_t io_va; uint16_t size; uint16_t pad[3]; }; /* The exit reason in HAX tunnel for HAX_VCPU_IOCTL_RUN IOCTL */ enum exit_status { /* IO port emulation request */ HAX_EXIT_IO = 1, /* MMIO instruction emulation request * QEMU emulates MMIO instruction in following step: * 1. When guest accesses MMIO address, it is trapped to HAX driver * 2. HAX driver return back to QEMU with the instruction pointer address * 3. QEMU sync the vcpu state with HAX driver * 4. QEMU emulates this instruction * 5. QEMU sync the vcpu state to HAX driver * 6. HAX driver continuous run the guest through HAX_VCPU_IOCTL_RUN */ HAX_EXIT_MMIO, /* * QEMU emulation mode request * QEMU emulates guest instruction when guest is running in * real mode or protected mode */ HAX_EXIT_REAL, /* * Interrupt window open, qemu can inject an interrupt now. * Also used to indicate a signal is pending to QEMU */ HAX_EXIT_INTERRUPT, /* Unknown vmexit, mostly trigger reboot */ HAX_EXIT_UNKNOWN_VMEXIT, /* * Halt in guest * When guest executes HLT instruction with interrupt enabled, HAX * return back to QEMU. */ HAX_EXIT_HLT, /* Reboot request, like because of tripple fault in guest */ HAX_EXIT_STATECHANGE, /* * The VCPU is paused * Now the vcpu is only paused when to be destroid, so simply return to hax */ HAX_EXIT_PAUSED, /* from API 2.0 */ /* * In API 1.0, HAXM driver utilizes QEMU to decode and emulate MMIO * operations. * From 2.0, HAXM driver will decode some MMIO instructions to improve * MMIO handling performance, especially for GLES hardware acceleration */ HAX_EXIT_FAST_MMIO, }; /* * The API version between QEMU and HAX driver * Compat_version defines the oldest API version the HAX driver can support */ struct hax_module_version { uint32_t compat_version; uint32_t cur_version; }; /* This interface is support only after API version 2 */ struct hax_qemu_version { /* Current API version in QEMU*/ uint32_t cur_version; /* The least API version supported by QEMU */ uint32_t least_version; }; /* See comments for HAX_VM_IOCTL_ALLOC_RAM ioctl */ struct hax_alloc_ram_info { uint32_t size; uint32_t pad; uint64_t va; }; /* See comments for HAX_VM_IOCTL_SET_RAM ioctl */ #define HAX_RAM_INFO_ROM 0x1 struct hax_set_ram_info { uint64_t pa_start; uint32_t size; uint8_t flags; uint8_t pad[3]; uint64_t va; }; /* * We need to load the HAXM (HAX Manager) to tell if the host system has the * required capabilities to operate, and we use hax_capabilityinfo to get such * info from HAXM. * * To prevent HAXM from over-consuming RAM, we set the maximum amount of RAM * that can be used for guests at HAX installation time. Once the quota is * reached, HAXM will no longer attempt to allocate memory for guests. * Detect that HAXM is out of quota can take the emulator to non-HAXM model */ struct hax_capabilityinfo { /* bit 0: 1 - HAXM is working * 0 - HAXM is not working possibly because VT/NX is disabled NX means Non-eXecution, aks. XD (eXecution Disable) * bit 1: 1 - HAXM has hard limit on how many RAM can be used as guest RAM * 0 - HAXM has no memory limitation */ #define HAX_CAP_STATUS_WORKING 0x1 #define HAX_CAP_STATUS_NOTWORKING 0x0 #define HAX_CAP_WORKSTATUS_MASK 0x1 #define HAX_CAP_MEMQUOTA 0x2 uint16_t wstatus; /* * valid when HAXM is not working * bit 0: HAXM is not working because VT is not enabeld * bit 1: HAXM is not working because NX not enabled */ #define HAX_CAP_FAILREASON_VT 0x1 #define HAX_CAP_FAILREASON_NX 0x2 uint16_t winfo; uint32_t pad; uint64_t mem_quota; }; /* API 2.0 */ struct hax_fastmmio { uint64_t gpa; uint64_t value; uint8_t size; uint8_t direction; uint16_t reg_index; uint32_t pad0; uint64_t _cr0; uint64_t _cr2; uint64_t _cr3; uint64_t _cr4; }; #endif