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

/*
 * HAX common code for both Windows and Darwin
 * Some portion of code from KVM is used in this file.
 */

#include "hw/hw.h"
#include "target-i386/hax-i386.h"

#define HAX_EMUL_ONE    0x1
#define HAX_EMUL_REAL   0x2
#define HAX_EMUL_HLT    0x4
#define HAX_EMUL_EXITLOOP    0x5

#define HAX_EMULATE_STATE_MMIO  0x1
#define HAX_EMULATE_STATE_REAL  0x2
#define HAX_EMULATE_STATE_NONE  0x3
#define HAX_EMULATE_STATE_INITIAL       0x4

struct hax_state hax_global;

int hax_support = -1;

/* Called after hax_init */
int hax_enabled()
{
    return (!hax_disabled && hax_support);
}

/* Currently non-PG modes are emulated by QEMU */
int hax_vcpu_emulation_mode(CPUState *cpu)
{
    CPUX86State *env = cpu->env_ptr;
    return !(env->cr[0] & CR0_PG_MASK);
}

static int hax_prepare_emulation(CPUX86State *env)
{
    /* Flush all emulation states */
    tlb_flush(env, 1);
    tb_flush(env);
    /* Sync the vcpu state from hax kernel module */
    hax_vcpu_sync_state(ENV_GET_CPU(env), 0);
    return 0;
}

/*
 * Check whether to break the translation block loop
 * Break tbloop after one MMIO emulation, or after finish emulation mode
 */
static int hax_stop_tbloop(CPUState *cpu)
{
    switch (cpu->hax_vcpu->emulation_state)
    {
        case HAX_EMULATE_STATE_MMIO:
            return 1;
        case HAX_EMULATE_STATE_INITIAL:
        case HAX_EMULATE_STATE_REAL:
            if (!hax_vcpu_emulation_mode(cpu))
                return 1;
            break;
        default:
            dprint("Invalid emulation state in hax_sto_tbloop state %x\n",
              cpu->hax_vcpu->emulation_state);
            break;
    }

    return 0;
}

int hax_stop_emulation(CPUState *cpu)
{
    if (hax_stop_tbloop(cpu))
    {
        cpu->hax_vcpu->emulation_state =  HAX_EMULATE_STATE_NONE;
        /*
         * QEMU emulation changes vcpu state,
         * Sync the vcpu state to HAX kernel module
         */
        hax_vcpu_sync_state(cpu, 1);
        return 1;
    }

    return 0;
}

int hax_stop_translate(CPUState *cpu)
{
    struct hax_vcpu_state *vstate;

    vstate = cpu->hax_vcpu;
    assert(vstate->emulation_state);
    if (vstate->emulation_state == HAX_EMULATE_STATE_MMIO )
        return 1;

    return 0;
}

int valid_hax_tunnel_size(uint16_t size)
{
    return size >= sizeof(struct hax_tunnel);
}

hax_fd hax_vcpu_get_fd(CPUState *cpu)
{
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
    if (!vcpu)
        return HAX_INVALID_FD;
    return vcpu->fd;
}

/* Current version */
uint32_t hax_cur_version = 0x2;
/* Least HAX kernel version */
uint32_t hax_lest_version = 0x1;

static int hax_get_capability(struct hax_state *hax)
{
    int ret;
    struct hax_capabilityinfo capinfo, *cap = &capinfo;

    ret = hax_capability(hax, cap);
    if (ret)
        return -ENOSYS;

    if ( ((cap->wstatus & HAX_CAP_WORKSTATUS_MASK) ==
          HAX_CAP_STATUS_NOTWORKING ))
    {
        if (cap->winfo & HAX_CAP_FAILREASON_VT)
            dprint("VT feature is not enabled, HAXM not working.\n");
        else if (cap->winfo & HAX_CAP_FAILREASON_NX)
            dprint("NX feature is not enabled, HAXM not working.\n");
        return -ENXIO;
    }

    if (cap->wstatus & HAX_CAP_MEMQUOTA)
    {
        if (cap->mem_quota < hax->mem_quota)
        {
            dprint("The memory needed by this VM exceeds the driver limit.\n");
            return -ENOSPC;
        }
    }

    return 0;
}

static int hax_version_support(struct hax_state *hax)
{
    int ret;
    struct hax_module_version version;

    ret = hax_mod_version(hax, &version);
    if (ret < 0)
        return 0;

    if ( (hax_lest_version > version.cur_version) ||
         (hax_cur_version < version.compat_version) )
        return 0;

    return 1;
}

int hax_vcpu_create(int id)
{
    struct hax_vcpu_state *vcpu = NULL;
    int ret;

    if (!hax_global.vm)
    {
        dprint("vcpu %x created failed, vm is null\n", id);
        return -1;
    }

    if (hax_global.vm->vcpus[id])
    {
        dprint("vcpu %x allocated already\n", id);
        return 0;
    }

    vcpu = g_malloc(sizeof(struct hax_vcpu_state));
    if (!vcpu)
    {
        dprint("Failed to alloc vcpu state\n");
        return -ENOMEM;
    }

    memset(vcpu, 0, sizeof(struct hax_vcpu_state));

    ret = hax_host_create_vcpu(hax_global.vm->fd, id);
    if (ret)
    {
        dprint("Failed to create vcpu %x\n", id);
        goto error;
    }

    vcpu->fd = hax_host_open_vcpu(hax_global.vm->id, id);
    if (hax_invalid_fd(vcpu->fd))
    {
        dprint("Failed to open the vcpu\n");
        ret = -ENODEV;
        goto error;
    }

    hax_global.vm->vcpus[id] = vcpu;

    ret = hax_host_setup_vcpu_channel(vcpu);
    if (ret)
    {
        dprint("Invalid HAX tunnel size \n");
        ret = -EINVAL;
        goto error;
    }
    return 0;

error:
    /* vcpu and tunnel will be closed automatically */
    if (vcpu && !hax_invalid_fd(vcpu->fd))
        hax_close_fd(vcpu->fd);

    hax_global.vm->vcpus[id] = NULL;
    g_free(vcpu);
    return -1;
}

int hax_vcpu_destroy(CPUState *cpu)
{
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;

    if (!hax_global.vm)
    {
        dprint("vcpu %x destroy failed, vm is null\n", vcpu->vcpu_id);
        return -1;
    }

    if (!vcpu)
        return 0;

    /*
     * 1. The hax_tunnel is also destroyed at vcpu_destroy
     * 2. hax_close_fd will require the HAX kernel module to free vcpu
     */
    hax_close_fd(vcpu->fd);
    hax_global.vm->vcpus[vcpu->vcpu_id] = NULL;
    g_free(vcpu);
    return 0;
}

int hax_init_vcpu(CPUState *cpu)
{
    int ret;

    ret = hax_vcpu_create(cpu->cpu_index);
    if (ret < 0)
    {
        dprint("Failed to create HAX vcpu\n");
        exit(-1);
    }

    cpu->hax_vcpu = hax_global.vm->vcpus[cpu->cpu_index];
    cpu->hax_vcpu->emulation_state = HAX_EMULATE_STATE_INITIAL;

    return ret;
}

struct hax_vm *hax_vm_create(struct hax_state *hax)
{
    struct hax_vm *vm;
    int vm_id = 0, ret;
    char *vm_name = NULL;

    if (hax_invalid_fd(hax->fd))
        return NULL;

    if (hax->vm)
        return hax->vm;

    vm = g_malloc(sizeof(struct hax_vm));
    if (!vm)
        return NULL;
    memset(vm, 0, sizeof(struct hax_vm));
    ret = hax_host_create_vm(hax, &vm_id);
    if (ret) {
        dprint("Failed to create vm %x\n", ret);
        goto error;
    }
    vm->id = vm_id;
    vm->fd = hax_host_open_vm(hax, vm_id);
    if (hax_invalid_fd(vm->fd))
    {
        dprint("Open vm device error:%s\n", vm_name);
        goto error;
    }

    hax->vm = vm;
    return vm;

error:
    g_free(vm);
    hax->vm = NULL;
    return NULL;
}

int hax_vm_destroy(struct hax_vm *vm)
{
    int i;

    for (i = 0; i < HAX_MAX_VCPU; i++)
        if (vm->vcpus[i])
        {
            dprint("VCPU should be cleaned before vm clean\n");
            return -1;
        }
    hax_close_fd(vm->fd);
    g_free(vm);
    hax_global.vm = NULL;
    return 0;
}

int hax_set_ramsize(uint64_t ramsize)
{
    struct hax_state *hax = &hax_global;

    memset(hax, 0, sizeof(struct hax_state));
    hax->mem_quota = ram_size;

    return 0;
}

int hax_init(int smp_cpus)
{
    struct hax_state *hax = NULL;
    struct hax_qemu_version qversion;
    int ret;

    hax_support = 0;

    hax = &hax_global;

    hax->fd = hax_mod_open();
    if (hax_invalid_fd(hax->fd))
    {
        hax->fd = 0;
        ret = -ENODEV;
        goto error;
    }

    ret = hax_get_capability(hax);
    /* In case HAXM have no such capability support */
    if (ret && (ret != -ENOSYS))
    {
        ret = -EINVAL;
        goto error;
    }

    if (!hax_version_support(hax))
    {
        dprint("Incompatible HAX version. Qemu current version %x ", hax_cur_version );
        dprint("requires least HAX version %x\n", hax_lest_version);
        ret = -EINVAL;
        goto error;
    }

    hax->vm = hax_vm_create(hax);
    if (!hax->vm)
    {
        dprint("Failed to create HAX VM\n");
        ret = -EINVAL;
        goto error;
    }

    qversion.cur_version = hax_cur_version;
    qversion.least_version = hax_lest_version;
    hax_notify_qemu_version(hax->vm->fd, &qversion);
    hax_support = 1;
    qemu_register_reset( hax_reset_vcpu_state, NULL);

    return 0;
error:
    if (hax->vm)
        hax_vm_destroy(hax->vm);
    if (hax->fd)
        hax_mod_close(hax);

    return ret;
}

int  hax_handle_fastmmio(CPUX86State *env, struct hax_fastmmio *hft)
{
    uint64_t buf = 0;

    /*
     * With fast MMIO, QEMU need not sync vCPU state with HAXM
     * driver because it will only invoke MMIO handler
     * However, some MMIO operations utilize virtual address like qemu_pipe
     * Thus we need to sync the CR0, CR3 and CR4 so that QEMU
     * can translate the guest virtual address to guest physical
     * address
     */
    env->cr[0] = hft->_cr0;
    env->cr[2] = hft->_cr2;
    env->cr[3] = hft->_cr3;
    env->cr[4] = hft->_cr4;

    buf = hft->value;
    cpu_physical_memory_rw(hft->gpa, &buf, hft->size, hft->direction);
    if (hft->direction == 0)
        hft->value = buf;

    return 0;
}

int hax_handle_io(CPUX86State *env, uint32_t df, uint16_t port, int direction,
  int size, int count, void *buffer)
{
    uint8_t *ptr;
    int i;

    if (!df)
        ptr = (uint8_t *)buffer;
    else
        ptr = buffer + size * count - size;
    for (i = 0; i < count; i++)
    {
        if (direction == HAX_EXIT_IO_IN) {
            switch (size) {
                case 1:
                    stb_p(ptr, cpu_inb(port));
                    break;
                case 2:
                    stw_p(ptr, cpu_inw(port));
                    break;
                case 4:
                    stl_p(ptr, cpu_inl(port));
                    break;
            }
        } else {
            switch (size) {
                case 1:
                    cpu_outb(port, ldub_p(ptr));
                    break;
                case 2:
                    cpu_outw(port, lduw_p(ptr));
                    break;
                case 4:
                    cpu_outl(port, ldl_p(ptr));
                    break;
            }
        }
        if (!df)
            ptr += size;
        else
            ptr -= size;
    }

    return 0;
}

static int hax_vcpu_interrupt(CPUState *cpu)
{
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
    struct hax_tunnel *ht = vcpu->tunnel;
    CPUX86State *env = cpu->env_ptr;

    /*
     * Try to inject an interrupt if the guest can accept it
     * Unlike KVM, the HAX kernel module checks the eflags, instead.
     */
    if (ht->ready_for_interrupt_injection &&
      (cpu->interrupt_request & CPU_INTERRUPT_HARD))
    {
        int irq;

        cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
        irq = cpu_get_pic_interrupt(env);
        if (irq >= 0) {
            hax_inject_interrupt(cpu, irq);
        }
    }

    /*
     * If we have an interrupt pending but the guest is not ready to
     * receive it, request an interrupt window exit.  This will cause
     * a return to userspace as soon as the guest is ready to receive
     * an interrupt.
     */
    if ((cpu->interrupt_request & CPU_INTERRUPT_HARD))
        ht->request_interrupt_window = 1;
    else
        ht->request_interrupt_window = 0;
    return 0;
}

void hax_raise_event(CPUState *cpu)
{
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;

    if (!vcpu)
        return;
    vcpu->tunnel->user_event_pending = 1;
}

/*
 * Request the HAX kernel module to run the CPU for us until one of
 * the following occurs:
 * 1. Guest crashes or is shut down
 * 2. We need QEMU's emulation like when the guest executes a MMIO
 *    instruction or guest enters emulation mode (non-PG mode)
 * 3. Guest executes HLT
 * 4. Qemu has Signal/event pending
 * 5. An unknown VMX-exit happens
 */
extern void qemu_system_reset_request(void);
static int hax_vcpu_hax_exec(CPUState *cpu)
{
    int ret = 0;
    CPUX86State *env = cpu->env_ptr;
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
    struct hax_tunnel *ht = vcpu->tunnel;

    if (hax_vcpu_emulation_mode(cpu))
    {
        dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
        return  HAX_EMUL_EXITLOOP;
    }

    do {
        int hax_ret;

        if (cpu->exit_request) {
            ret = HAX_EMUL_EXITLOOP ;
            break;
        }

        hax_vcpu_interrupt(cpu);

        hax_ret = hax_vcpu_run(vcpu);

        /* Simply continue the vcpu_run if system call interrupted */
        if (hax_ret == -EINTR || hax_ret == -EAGAIN) {
            dprint("io window interrupted\n");
            continue;
        }

        if (hax_ret < 0)
        {
            dprint("vcpu run failed for vcpu  %x\n", vcpu->vcpu_id);
            abort();
        }
        switch (ht->_exit_status)
        {
            case HAX_EXIT_IO:
                {
                    ret = hax_handle_io(env, ht->pio._df, ht->pio._port,
                      ht->pio._direction,
                      ht->pio._size, ht->pio._count, vcpu->iobuf);
                }
                break;
            case HAX_EXIT_MMIO:
                ret = HAX_EMUL_ONE;
                break;
            case HAX_EXIT_FAST_MMIO:
                ret = hax_handle_fastmmio(env,
                        (struct hax_fastmmio *)vcpu->iobuf);
                break;
            case HAX_EXIT_REAL:
                ret = HAX_EMUL_REAL;
                break;
                /* Guest state changed, currently only for shutdown */
            case HAX_EXIT_STATECHANGE:
                dprint("VCPU shutdown request\n");
                qemu_system_reset_request();
                hax_prepare_emulation(env);
                cpu_dump_state(cpu, stderr, fprintf, 0);
                ret = HAX_EMUL_EXITLOOP;
                break;
            case HAX_EXIT_UNKNOWN_VMEXIT:
                dprint("Unknown VMX exit %x from guest\n", ht->_exit_reason);
                qemu_system_reset_request();
                hax_prepare_emulation(env);
                cpu_dump_state(cpu, stderr, fprintf, 0);
                ret = HAX_EMUL_EXITLOOP;
                break;
            case HAX_EXIT_HLT:
                if (!(cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
                  !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
                    /* hlt instruction with interrupt disabled is shutdown */
                    env->eflags |= IF_MASK;
                    cpu->halted = 1;
                    cpu->exception_index = EXCP_HLT;
                    ret = HAX_EMUL_HLT;
                }
                break;
                /* these situation will continue to hax module */
            case HAX_EXIT_INTERRUPT:
            case HAX_EXIT_PAUSED:
                break;
            default:
                dprint("Unknow exit %x from hax\n", ht->_exit_status);
                qemu_system_reset_request();
                hax_prepare_emulation(env);
                cpu_dump_state(cpu, stderr, fprintf, 0);
                ret = HAX_EMUL_EXITLOOP;
                break;
        }
    }while (!ret);

    if (cpu->exit_request) {
        cpu->exit_request = 0;
        cpu->exception_index = EXCP_INTERRUPT;
    }
    return ret;
}

/*
 * return 1 when need to emulate, 0 when need to exit loop
 */
int hax_vcpu_exec(CPUState *cpu)
{
    int next = 0, ret = 0;
    struct hax_vcpu_state *vcpu;
    CPUX86State *env = cpu->env_ptr;

    if (cpu->hax_vcpu->emulation_state != HAX_EMULATE_STATE_NONE)
        return 1;

    vcpu = cpu->hax_vcpu;
    next = hax_vcpu_hax_exec(cpu);
    switch (next)
    {
        case HAX_EMUL_ONE:
            ret = 1;
            vcpu->emulation_state = HAX_EMULATE_STATE_MMIO;
            hax_prepare_emulation(env);
            break;
        case HAX_EMUL_REAL:
            ret = 1;
            vcpu->emulation_state = HAX_EMULATE_STATE_REAL;
            hax_prepare_emulation(env);
            break;
        case HAX_EMUL_HLT:
        case HAX_EMUL_EXITLOOP:
            break;
        default:
            dprint("Unknown hax vcpu exec return %x\n", next);
            abort();
    }

    return ret;
}

#define HAX_RAM_INFO_ROM 0x1

static void set_v8086_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
{
    memset(lhs, 0, sizeof(struct segment_desc_t ));
    lhs->selector = rhs->selector;
    lhs->base = rhs->base;
    lhs->limit = rhs->limit;
    lhs->type = 3;
    lhs->present = 1;
    lhs->dpl = 3;
    lhs->operand_size = 0;
    lhs->desc = 1;
    lhs->long_mode = 0;
    lhs->granularity = 0;
    lhs->available = 0;
}

static void get_seg(SegmentCache *lhs, const struct segment_desc_t *rhs)
{
    lhs->selector = rhs->selector;
    lhs->base = rhs->base;
    lhs->limit = rhs->limit;
    lhs->flags =
      (rhs->type << DESC_TYPE_SHIFT)
      | (rhs->present * DESC_P_MASK)
      | (rhs->dpl << DESC_DPL_SHIFT)
      | (rhs->operand_size << DESC_B_SHIFT)
      | (rhs->desc * DESC_S_MASK)
      | (rhs->long_mode << DESC_L_SHIFT)
      | (rhs->granularity * DESC_G_MASK)
      | (rhs->available * DESC_AVL_MASK);
}

static void set_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
{
    unsigned flags = rhs->flags;

    memset(lhs, 0, sizeof(struct segment_desc_t));
    lhs->selector = rhs->selector;
    lhs->base = rhs->base;
    lhs->limit = rhs->limit;
    lhs->type = (flags >> DESC_TYPE_SHIFT) & 15;
    lhs->present = (flags & DESC_P_MASK) != 0;
    lhs->dpl = rhs->selector & 3;
    lhs->operand_size = (flags >> DESC_B_SHIFT) & 1;
    lhs->desc = (flags & DESC_S_MASK) != 0;
    lhs->long_mode = (flags >> DESC_L_SHIFT) & 1;
    lhs->granularity = (flags & DESC_G_MASK) != 0;
    lhs->available = (flags & DESC_AVL_MASK) != 0;
}

static void hax_getput_reg(uint64_t *hax_reg, target_ulong *qemu_reg, int set)
{
    target_ulong reg = *hax_reg;

    if (set)
        *hax_reg = *qemu_reg;
    else
        *qemu_reg = reg;
}

/* The sregs has been synced with HAX kernel already before this call */
static int hax_get_segments(CPUX86State *env, struct vcpu_state_t *sregs)
{
    get_seg(&env->segs[R_CS], &sregs->_cs);
    get_seg(&env->segs[R_DS], &sregs->_ds);
    get_seg(&env->segs[R_ES], &sregs->_es);
    get_seg(&env->segs[R_FS], &sregs->_fs);
    get_seg(&env->segs[R_GS], &sregs->_gs);
    get_seg(&env->segs[R_SS], &sregs->_ss);

    get_seg(&env->tr, &sregs->_tr);
    get_seg(&env->ldt, &sregs->_ldt);
    env->idt.limit = sregs->_idt.limit;
    env->idt.base = sregs->_idt.base;
    env->gdt.limit = sregs->_gdt.limit;
    env->gdt.base = sregs->_gdt.base;
    return 0;
}

static int hax_set_segments(CPUX86State *env, struct vcpu_state_t *sregs)
{
    if ((env->eflags & VM_MASK)) {
        set_v8086_seg(&sregs->_cs, &env->segs[R_CS]);
        set_v8086_seg(&sregs->_ds, &env->segs[R_DS]);
        set_v8086_seg(&sregs->_es, &env->segs[R_ES]);
        set_v8086_seg(&sregs->_fs, &env->segs[R_FS]);
        set_v8086_seg(&sregs->_gs, &env->segs[R_GS]);
        set_v8086_seg(&sregs->_ss, &env->segs[R_SS]);
    } else {
        set_seg(&sregs->_cs, &env->segs[R_CS]);
        set_seg(&sregs->_ds, &env->segs[R_DS]);
        set_seg(&sregs->_es, &env->segs[R_ES]);
        set_seg(&sregs->_fs, &env->segs[R_FS]);
        set_seg(&sregs->_gs, &env->segs[R_GS]);
        set_seg(&sregs->_ss, &env->segs[R_SS]);

        if (env->cr[0] & CR0_PE_MASK) {
            /* force ss cpl to cs cpl */
            sregs->_ss.selector = (sregs->_ss.selector & ~3) |
              (sregs->_cs.selector & 3);
            sregs->_ss.dpl = sregs->_ss.selector & 3;
        }
    }

    set_seg(&sregs->_tr, &env->tr);
    set_seg(&sregs->_ldt, &env->ldt);
    sregs->_idt.limit = env->idt.limit;
    sregs->_idt.base = env->idt.base;
    sregs->_gdt.limit = env->gdt.limit;
    sregs->_gdt.base = env->gdt.base;
    return 0;
}

/*
 * After get the state from the kernel module, some
 * qemu emulator state need be updated also
 */
static int hax_setup_qemu_emulator(CPUX86State *env)
{

#define HFLAG_COPY_MASK ~( \
  HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
  HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
  HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
  HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)

    uint32_t hflags;

    hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
    hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
    hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
      (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
    hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
    hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<
      (HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);

    if (env->efer & MSR_EFER_LMA) {
        hflags |= HF_LMA_MASK;
    }

    if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
        hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
    } else {
        hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
          (DESC_B_SHIFT - HF_CS32_SHIFT);
        hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
          (DESC_B_SHIFT - HF_SS32_SHIFT);
        if (!(env->cr[0] & CR0_PE_MASK) ||
          (env->eflags & VM_MASK) ||
          !(hflags & HF_CS32_MASK)) {
            hflags |= HF_ADDSEG_MASK;
        } else {
            hflags |= ((env->segs[R_DS].base |
                  env->segs[R_ES].base |
                  env->segs[R_SS].base) != 0) <<
              HF_ADDSEG_SHIFT;
        }
    }
    env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;
    return 0;
}

static int hax_sync_vcpu_register(CPUX86State *env, int set)
{
    CPUState *cpu = ENV_GET_CPU(env);
    struct vcpu_state_t regs;
    int ret;
    memset(&regs, 0, sizeof(struct vcpu_state_t));

    if (!set)
    {
        ret = hax_sync_vcpu_state(cpu, &regs, 0);
        if (ret < 0)
            return -1;
    }

    /*generic register */
    hax_getput_reg(&regs._rax, &env->regs[R_EAX], set);
    hax_getput_reg(&regs._rbx, &env->regs[R_EBX], set);
    hax_getput_reg(&regs._rcx, &env->regs[R_ECX], set);
    hax_getput_reg(&regs._rdx, &env->regs[R_EDX], set);
    hax_getput_reg(&regs._rsi, &env->regs[R_ESI], set);
    hax_getput_reg(&regs._rdi, &env->regs[R_EDI], set);
    hax_getput_reg(&regs._rsp, &env->regs[R_ESP], set);
    hax_getput_reg(&regs._rbp, &env->regs[R_EBP], set);
#ifdef TARGET_X86_64
    hax_getput_reg(&regs._r8, &env->regs[8], set);
    hax_getput_reg(&regs._r9, &env->regs[9], set);
    hax_getput_reg(&regs._r10, &env->regs[10], set);
    hax_getput_reg(&regs._r11, &env->regs[11], set);
    hax_getput_reg(&regs._r12, &env->regs[12], set);
    hax_getput_reg(&regs._r13, &env->regs[13], set);
    hax_getput_reg(&regs._r14, &env->regs[14], set);
    hax_getput_reg(&regs._r15, &env->regs[15], set);
#endif
    hax_getput_reg(&regs._rflags, &env->eflags, set);
    hax_getput_reg(&regs._rip, &env->eip, set);

    if (set)
    {

        regs._cr0 = env->cr[0];
        regs._cr2 = env->cr[2];
        regs._cr3 = env->cr[3];
        regs._cr4 = env->cr[4];
        hax_set_segments(env, &regs);
    }
    else
    {
        env->cr[0] = regs._cr0;
        env->cr[2] = regs._cr2;
        env->cr[3] = regs._cr3;
        env->cr[4] = regs._cr4;
        hax_get_segments(env, &regs);
    }

    if (set)
    {
        ret = hax_sync_vcpu_state(cpu, &regs, 1);
        if (ret < 0)
            return -1;
    }
    if (!set)
        hax_setup_qemu_emulator(env);
    return 0;
}

static void hax_msr_entry_set(struct vmx_msr *item,
  uint32_t index, uint64_t value)
{
    item->entry = index;
    item->value = value;
}

static int hax_get_msrs(CPUX86State *env)
{
    struct hax_msr_data md;
    struct vmx_msr *msrs = md.entries;
    int ret, i, n;

    n = 0;
    msrs[n++].entry = MSR_IA32_SYSENTER_CS;
    msrs[n++].entry = MSR_IA32_SYSENTER_ESP;
    msrs[n++].entry = MSR_IA32_SYSENTER_EIP;
    msrs[n++].entry = MSR_IA32_TSC;
#ifdef TARGET_X86_64
    msrs[n++].entry = MSR_STAR;
    msrs[n++].entry = MSR_LSTAR;
    msrs[n++].entry = MSR_CSTAR;
    msrs[n++].entry = MSR_FMASK;
    msrs[n++].entry = MSR_KERNELGSBASE;
#endif

    md.nr_msr = n;
    ret = hax_sync_msr(ENV_GET_CPU(env), &md, 0);
    if (ret < 0)
        return ret;

    for (i = 0; i < md.done; i++) {
        switch (msrs[i].entry) {
            case MSR_IA32_SYSENTER_CS:
                env->sysenter_cs = msrs[i].value;
                break;
            case MSR_IA32_SYSENTER_ESP:
                env->sysenter_esp = msrs[i].value;
                break;
            case MSR_IA32_SYSENTER_EIP:
                env->sysenter_eip = msrs[i].value;
                break;
            case MSR_IA32_TSC:
                env->tsc = msrs[i].value;
                break;
#ifdef TARGET_X86_64
            case MSR_STAR:
                env->star = msrs[i].value;
                break;
            case MSR_LSTAR:
                env->lstar = msrs[i].value;
                break;
            case MSR_CSTAR:
                env->cstar = msrs[i].value;
                break;
            case MSR_FMASK:
                env->fmask = msrs[i].value;
                break;
            case MSR_KERNELGSBASE:
                env->kernelgsbase = msrs[i].value;
                break;
#endif
        }
    }

    return 0;
}

static int hax_set_msrs(CPUX86State *env)
{
    struct hax_msr_data md;
    struct vmx_msr *msrs;
    msrs = md.entries;
    int n = 0;

    memset(&md, 0, sizeof(struct hax_msr_data));
    hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
    hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
    hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
    hax_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
#ifdef TARGET_X86_64
    hax_msr_entry_set(&msrs[n++], MSR_EFER, env->efer);
    hax_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
    hax_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
    hax_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
    hax_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
    hax_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
#endif

    md.nr_msr = n;
    md.done = 0;

    return hax_sync_msr(ENV_GET_CPU(env), &md, 1);

}

static int hax_get_fpu(CPUX86State *env)
{
    struct fx_layout fpu;
    int i, ret;

    ret = hax_sync_fpu(ENV_GET_CPU(env), &fpu, 0);
    if (ret < 0)
        return ret;

    env->fpstt = (fpu.fsw >> 11) & 7;
    env->fpus = fpu.fsw;
    env->fpuc = fpu.fcw;
    for (i = 0; i < 8; ++i)
        env->fptags[i] = !((fpu.ftw >> i) & 1);
    memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs));

    memcpy(env->xmm_regs, fpu.mmx_1, sizeof(fpu.mmx_1));
    memcpy((XMMReg *)(env->xmm_regs) + 8, fpu.mmx_2, sizeof(fpu.mmx_2));
    env->mxcsr = fpu.mxcsr;

    return 0;
}

static int hax_set_fpu(CPUX86State *env)
{
    struct fx_layout fpu;
    int i;

    memset(&fpu, 0, sizeof(fpu));
    fpu.fsw = env->fpus & ~(7 << 11);
    fpu.fsw |= (env->fpstt & 7) << 11;
    fpu.fcw = env->fpuc;

    for (i = 0; i < 8; ++i)
        fpu.ftw |= (!env->fptags[i]) << i;

    memcpy(fpu.st_mm, env->fpregs, sizeof (env->fpregs));
    memcpy(fpu.mmx_1, env->xmm_regs, sizeof (fpu.mmx_1));
    memcpy(fpu.mmx_2, (XMMReg *)(env->xmm_regs) + 8, sizeof (fpu.mmx_2));

    fpu.mxcsr = env->mxcsr;

    return hax_sync_fpu(ENV_GET_CPU(env), &fpu, 1);
}

int hax_arch_get_registers(CPUState *cpu)
{
    CPUX86State *env = cpu->env_ptr;
    int ret;

    ret = hax_sync_vcpu_register(env, 0);
    if (ret < 0)
        return ret;

    ret = hax_get_fpu(env);
    if (ret < 0)
        return ret;

    ret = hax_get_msrs(env);
    if (ret < 0)
        return ret;

    return 0;
}

static int hax_arch_set_registers(CPUState *cpu)
{
    int ret;
    CPUX86State *env = cpu->env_ptr;
    ret = hax_sync_vcpu_register(env, 1);

    if (ret < 0)
    {
        dprint("Failed to sync vcpu reg\n");
        return ret;
    }
    ret = hax_set_fpu(env);
    if (ret < 0)
    {
        dprint("FPU failed\n");
        return ret;
    }
    ret = hax_set_msrs(env);
    if (ret < 0)
    {
        dprint("MSR failed\n");
        return ret;
    }

    return 0;
}

void hax_vcpu_sync_state(CPUState *cpu, int modified)
{
    if (hax_enabled()) {
        if (modified)
            hax_arch_set_registers(cpu);
        else
            hax_arch_get_registers(cpu);
    }
}

/*
 * This is simpler than the one for KVM because we don't support
 * direct I/O device assignment at this point.
 */
int hax_sync_vcpus(void)
{
    if (hax_enabled()) {
        CPUState *cpu;

        CPU_FOREACH(cpu) {
            int ret = hax_arch_set_registers(cpu);
            if (ret < 0) {
                dprint("Failed to sync HAX vcpu context\n");
                exit(1);
            }
        }
    }

    return 0;
}

void hax_reset_vcpu_state(void *opaque)
{
    CPUState *cpu;
    CPU_FOREACH(cpu) {
        if (cpu->hax_vcpu) {
            cpu->hax_vcpu->emulation_state  = HAX_EMULATE_STATE_INITIAL;
            cpu->hax_vcpu->tunnel->user_event_pending = 0;
            cpu->hax_vcpu->tunnel->ready_for_interrupt_injection = 0;
        }
    }
}
