/*
** 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