示例#1
0
void qemu_notify_event(void)
{
    CPUOldState *env = cpu_single_env;

    if (env) {
        cpu_exit(env);
    /*
     * This is mainly for the Windows host, where the timer may be in
     * a different thread with vcpu. Thus the timer function needs to
     * notify the vcpu thread of more than simply cpu_exit.  If env is
     * not NULL, it means that the vcpu is in execute state, we need
     * only to set the flags.  If the guest is in execute state, the
     * HAX kernel module will exit to qemu.  If env is NULL, vcpu is
     * in main_loop_wait, and we need a event to notify it.
     */
#ifdef CONFIG_HAX
        if (hax_enabled())
            hax_raise_event(env);
     } else {
#ifdef _WIN32
         if(hax_enabled())
             SetEvent(qemu_event_handle);
#endif
     }
#else
     }
示例#2
0
文件: apic_common.c 项目: 8tab/qemu
static void apic_common_realize(DeviceState *dev, Error **errp)
{
    APICCommonState *s = APIC_COMMON(dev);
    APICCommonClass *info;
    static DeviceState *vapic;
    int instance_id = s->id;

    info = APIC_COMMON_GET_CLASS(s);
    info->realize(dev, errp);

    /* Note: We need at least 1M to map the VAPIC option ROM */
    if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK &&
        !hax_enabled() && ram_size >= 1024 * 1024) {
        vapic = sysbus_create_simple("kvmvapic", -1, NULL);
    }
    s->vapic = vapic;
    if (apic_report_tpr_access && info->enable_tpr_reporting) {
        info->enable_tpr_reporting(s, true);
    }

    if (s->legacy_instance_id) {
        instance_id = -1;
    }
    vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common,
                                   s, -1, 0, NULL);
}
void main_loop(void)
{
    int r;

#ifdef CONFIG_HAX
    if (hax_enabled())
        hax_sync_vcpus();
#endif

    for (;;) {
        do {
#ifdef CONFIG_PROFILER
            int64_t ti;
#endif
            tcg_cpu_exec();
#ifdef CONFIG_PROFILER
            ti = profile_getclock();
#endif
            main_loop_wait(qemu_calculate_timeout());
#ifdef CONFIG_PROFILER
            dev_time += profile_getclock() - ti;
#endif

            qemu_log_rotation_poll();

        } while (vm_can_run());

        if (qemu_debug_requested())
            vm_stop(EXCP_DEBUG);
        if (qemu_shutdown_requested()) {
            if (no_shutdown) {
                vm_stop(0);
                no_shutdown = 0;
            } else {
                if (savevm_on_exit != NULL) {
                  /* Prior to saving VM to the snapshot file, save HW config
                   * settings for that VM, so we can match them when VM gets
                   * loaded from the snapshot. */
                  snaphost_save_config(savevm_on_exit);
                  do_savevm(cur_mon, savevm_on_exit);
                }
                break;
            }
        }
        if (qemu_reset_requested()) {
            pause_all_vcpus();
            qemu_system_reset();
            resume_all_vcpus();
        }
        if (qemu_powerdown_requested())
            qemu_system_powerdown();
        if ((r = qemu_vmstop_requested()))
            vm_stop(r);
    }
    pause_all_vcpus();
}
示例#4
0
文件: hax-all.c 项目: CTU-IIG/qemu
static void hax_vcpu_sync_state(CPUArchState *env, int modified)
{
    if (hax_enabled()) {
        if (modified) {
            hax_arch_set_registers(env);
        } else {
            hax_arch_get_registers(env);
        }
    }
}
示例#5
0
void qemu_init_vcpu(void *_env)
{
    CPUOldState *env = _env;

    if (kvm_enabled())
        kvm_init_vcpu(env);
#ifdef CONFIG_HAX
    if (hax_enabled())
        hax_init_vcpu(env);
#endif
    return;
}
示例#6
0
void qemu_notify_event(void)
{
    CPUState *env = cpu_single_env;

    if (env) {
        cpu_exit(env);
#ifdef USE_KQEMU
        if (env->kqemu_enabled)
            kqemu_cpu_interrupt(env);
#endif
#ifdef CONFIG_HAX
        if (hax_enabled())
            hax_raise_event(env);
     } else {
#ifdef _WIN32
         if(hax_enabled())
             SetEvent(qemu_event_handle);
#endif
     }
#else
     }
示例#7
0
文件: hax-all.c 项目: CTU-IIG/qemu
/*
 * much simpler than kvm, at least in first stage because:
 * We don't need consider the device pass-through, we don't need
 * consider the framebuffer, and we may even remove the bios at all
 */
int hax_sync_vcpus(void)
{
    if (hax_enabled()) {
        CPUState *cpu;

        cpu = first_cpu;
        if (!cpu) {
            return 0;
        }

        for (; cpu != NULL; cpu = CPU_NEXT(cpu)) {
            int ret;

            ret = hax_arch_set_registers(cpu->env_ptr);
            if (ret < 0) {
                return ret;
            }
        }
    }

    return 0;
}
示例#8
0
文件: hax-all.c 项目: CTU-IIG/qemu
/*
 * Ask hax kernel module to run the CPU for us till:
 * 1. Guest crash or shutdown
 * 2. Need QEMU's emulation like guest execute MMIO instruction
 * 3. Guest execute HLT
 * 4. QEMU have Signal/event pending
 * 5. An unknown VMX exit happens
 */
static int hax_vcpu_hax_exec(CPUArchState *env)
{
    int ret = 0;
    CPUState *cpu = ENV_GET_CPU(env);
    X86CPU *x86_cpu = X86_CPU(cpu);
    struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
    struct hax_tunnel *ht = vcpu->tunnel;

    if (!hax_enabled()) {
        DPRINTF("Trying to vcpu execute at eip:" TARGET_FMT_lx "\n", env->eip);
        return 0;
    }

    cpu->halted = 0;

    if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
        cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
        apic_poll_irq(x86_cpu->apic_state);
    }

    if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
        DPRINTF("\nhax_vcpu_hax_exec: handling INIT for %d\n",
                cpu->cpu_index);
        do_cpu_init(x86_cpu);
        hax_vcpu_sync_state(env, 1);
    }

    if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
        DPRINTF("hax_vcpu_hax_exec: handling SIPI for %d\n",
                cpu->cpu_index);
        hax_vcpu_sync_state(env, 0);
        do_cpu_sipi(x86_cpu);
        hax_vcpu_sync_state(env, 1);
    }

    do {
        int hax_ret;

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

        hax_vcpu_interrupt(env);

        qemu_mutex_unlock_iothread();
        cpu_exec_start(cpu);
        hax_ret = hax_vcpu_run(vcpu);
        cpu_exec_end(cpu);
        qemu_mutex_lock_iothread();

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

        if (hax_ret < 0) {
            fprintf(stderr, "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_FAST_MMIO:
            ret = hax_handle_fastmmio(env, (struct hax_fastmmio *) vcpu->iobuf);
            break;
        /* Guest state changed, currently only for shutdown */
        case HAX_EXIT_STATECHANGE:
            fprintf(stdout, "VCPU shutdown request\n");
            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
            hax_vcpu_sync_state(env, 0);
            ret = 1;
            break;
        case HAX_EXIT_UNKNOWN_VMEXIT:
            fprintf(stderr, "Unknown VMX exit %x from guest\n",
                    ht->_exit_reason);
            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
            hax_vcpu_sync_state(env, 0);
            cpu_dump_state(cpu, stderr, fprintf, 0);
            ret = -1;
            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 = 1;
            }
            break;
        /* these situations will continue to hax module */
        case HAX_EXIT_INTERRUPT:
        case HAX_EXIT_PAUSED:
            break;
        case HAX_EXIT_MMIO:
            /* Should not happen on UG system */
            fprintf(stderr, "HAX: unsupported MMIO emulation\n");
            ret = -1;
            break;
        case HAX_EXIT_REAL:
            /* Should not happen on UG system */
            fprintf(stderr, "HAX: unimplemented real mode emulation\n");
            ret = -1;
            break;
        default:
            fprintf(stderr, "Unknown exit %x from HAX\n", ht->_exit_status);
            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
            hax_vcpu_sync_state(env, 0);
            cpu_dump_state(cpu, stderr, fprintf, 0);
            ret = 1;
            break;
        }
    } while (!ret);

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