qemu/target/i386/hax/hax-accel-ops.c
<<
>>
Prefs
   1/*
   2 * QEMU HAX support
   3 *
   4 * Copyright IBM, Corp. 2008
   5 *           Red Hat, Inc. 2008
   6 *
   7 * Authors:
   8 *  Anthony Liguori   <aliguori@us.ibm.com>
   9 *  Glauber Costa     <gcosta@redhat.com>
  10 *
  11 * Copyright (c) 2011 Intel Corporation
  12 *  Written by:
  13 *  Jiang Yunhong<yunhong.jiang@intel.com>
  14 *  Xin Xiaohui<xiaohui.xin@intel.com>
  15 *  Zhang Xiantao<xiantao.zhang@intel.com>
  16 *
  17 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  18 * See the COPYING file in the top-level directory.
  19 *
  20 */
  21
  22#include "qemu/osdep.h"
  23#include "qemu/error-report.h"
  24#include "qemu/main-loop.h"
  25#include "sysemu/runstate.h"
  26#include "sysemu/cpus.h"
  27#include "qemu/guest-random.h"
  28
  29#include "hax-accel-ops.h"
  30
  31static void *hax_cpu_thread_fn(void *arg)
  32{
  33    CPUState *cpu = arg;
  34    int r;
  35
  36    rcu_register_thread();
  37    qemu_mutex_lock_iothread();
  38    qemu_thread_get_self(cpu->thread);
  39
  40    cpu->thread_id = qemu_get_thread_id();
  41    current_cpu = cpu;
  42    hax_init_vcpu(cpu);
  43    cpu_thread_signal_created(cpu);
  44    qemu_guest_random_seed_thread_part2(cpu->random_seed);
  45
  46    do {
  47        if (cpu_can_run(cpu)) {
  48            r = hax_smp_cpu_exec(cpu);
  49            if (r == EXCP_DEBUG) {
  50                cpu_handle_guest_debug(cpu);
  51            }
  52        }
  53
  54        qemu_wait_io_event(cpu);
  55    } while (!cpu->unplug || cpu_can_run(cpu));
  56    rcu_unregister_thread();
  57    return NULL;
  58}
  59
  60static void hax_start_vcpu_thread(CPUState *cpu)
  61{
  62    char thread_name[VCPU_THREAD_NAME_SIZE];
  63
  64    cpu->thread = g_malloc0(sizeof(QemuThread));
  65    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
  66    qemu_cond_init(cpu->halt_cond);
  67
  68    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX",
  69             cpu->cpu_index);
  70    qemu_thread_create(cpu->thread, thread_name, hax_cpu_thread_fn,
  71                       cpu, QEMU_THREAD_JOINABLE);
  72#ifdef _WIN32
  73    cpu->hThread = qemu_thread_get_handle(cpu->thread);
  74#endif
  75}
  76
  77static void hax_accel_ops_class_init(ObjectClass *oc, void *data)
  78{
  79    AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
  80
  81    ops->create_vcpu_thread = hax_start_vcpu_thread;
  82    ops->kick_vcpu_thread = hax_kick_vcpu_thread;
  83
  84    ops->synchronize_post_reset = hax_cpu_synchronize_post_reset;
  85    ops->synchronize_post_init = hax_cpu_synchronize_post_init;
  86    ops->synchronize_state = hax_cpu_synchronize_state;
  87    ops->synchronize_pre_loadvm = hax_cpu_synchronize_pre_loadvm;
  88}
  89
  90static const TypeInfo hax_accel_ops_type = {
  91    .name = ACCEL_OPS_NAME("hax"),
  92
  93    .parent = TYPE_ACCEL_OPS,
  94    .class_init = hax_accel_ops_class_init,
  95    .abstract = true,
  96};
  97
  98static void hax_accel_ops_register_types(void)
  99{
 100    type_register_static(&hax_accel_ops_type);
 101}
 102type_init(hax_accel_ops_register_types);
 103