cpu_single_env is a global variable, so there is an assumption that only 
one vcpu can execute QEMU at the same time.

Provide a get_cpu_env() wrapper allowing KVM to use its thread local storage
vcpu info. It simplifies IO thread handling.


Index: kvm-userspace.io/qemu/block-raw-posix.c
===================================================================
--- kvm-userspace.io.orig/qemu/block-raw-posix.c
+++ kvm-userspace.io/qemu/block-raw-posix.c
@@ -247,7 +247,7 @@ static int aio_initialized = 0;
 static void aio_signal_handler(int signum)
 {
 #ifndef QEMU_IMG
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     if (env) {
         /* stop the currently executing cpu because a timer occured */
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
Index: kvm-userspace.io/qemu/cpu-all.h
===================================================================
--- kvm-userspace.io.orig/qemu/cpu-all.h
+++ kvm-userspace.io/qemu/cpu-all.h
@@ -741,7 +741,8 @@ void cpu_abort(CPUState *env, const char
     __attribute__ ((__format__ (__printf__, 2, 3)))
     __attribute__ ((__noreturn__));
 extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
+CPUState *get_cpu_env(void);
+void set_cpu_env(CPUState *env);
 extern int code_copy_enabled;
 
 #define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */
Index: kvm-userspace.io/qemu/cpu-exec.c
===================================================================
--- kvm-userspace.io.orig/qemu/cpu-exec.c
+++ kvm-userspace.io/qemu/cpu-exec.c
@@ -306,7 +306,7 @@ int cpu_exec(CPUState *env1)
     if (cpu_halted(env1) == EXCP_HALTED)
         return EXCP_HALTED;
 
-    cpu_single_env = env1;
+    set_cpu_env(env1);
 
     /* first we save global registers */
 #define SAVE_HOST_REGS 1
@@ -743,7 +743,7 @@ int cpu_exec(CPUState *env1)
 #include "hostregs_helper.h"
 
     /* fail safe : never use cpu_single_env outside cpu_exec() */
-    cpu_single_env = NULL;
+    set_cpu_env(NULL);
     return ret;
 }
 
Index: kvm-userspace.io/qemu/exec-all.h
===================================================================
--- kvm-userspace.io.orig/qemu/exec-all.h
+++ kvm-userspace.io/qemu/exec-all.h
@@ -472,7 +472,6 @@ void tlb_fill(target_ulong addr, int is_
 
 #define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
-#define env cpu_single_env
 
 #define DATA_SIZE 1
 #include "softmmu_header.h"
Index: kvm-userspace.io/qemu/exec.c
===================================================================
--- kvm-userspace.io.orig/qemu/exec.c
+++ kvm-userspace.io/qemu/exec.c
@@ -108,9 +108,20 @@ static int in_migration;
 static ram_addr_t phys_ram_alloc_offset = 0;
 
 CPUState *first_cpu;
-/* current CPU in the current thread. It is only valid inside
-   cpu_exec() */
-CPUState *cpu_single_env;
+/* env holder for single threaded SMP emulation */
+static CPUState *curr_cpu_env;
+
+/* get the environment of the current executing CPU */
+__attribute__((weak)) CPUState *get_cpu_env(void)
+{
+    return curr_cpu_env;
+}
+
+__attribute__((weak)) void set_cpu_env(CPUState *env)
+{
+    curr_cpu_env = env;
+}
+
 
 typedef struct PageDesc {
     /* list of TBs intersecting this ram page */
@@ -686,7 +697,7 @@ void tb_invalidate_phys_page_range(targe
                                    int is_cpu_write_access)
 {
     int n, current_tb_modified, current_tb_not_found, current_flags;
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     PageDesc *p;
     TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
     target_ulong tb_start, tb_end;
@@ -832,7 +843,7 @@ static void tb_invalidate_phys_page(targ
     PageDesc *p;
     TranslationBlock *tb, *current_tb;
 #ifdef TARGET_HAS_PRECISE_SMC
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 #endif
 
     addr &= TARGET_PAGE_MASK;
@@ -1244,17 +1255,19 @@ void cpu_interrupt(CPUState *env, int ma
     TranslationBlock *tb;
     static int interrupt_lock;
 
-    env->interrupt_request |= mask;
-    if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel())
-       kvm_update_interrupt_request(env);
-
-    /* if the cpu is currently executing code, we must unlink it and
-       all the potentially executing TB */
-    tb = env->current_tb;
-    if (tb && !testandset(&interrupt_lock)) {
-        env->current_tb = NULL;
-        tb_reset_jump_recursive(tb);
-        interrupt_lock = 0;
+    if (env) {
+        env->interrupt_request |= mask;
+            if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel())
+               kvm_update_interrupt_request(env);
+
+        /* if the cpu is currently executing code, we must unlink it and
+        all the potentially executing TB */
+        tb = env->current_tb;
+        if (tb && !testandset(&interrupt_lock)) {
+            env->current_tb = NULL;
+            tb_reset_jump_recursive(tb);
+            interrupt_lock = 0;
+        }
     }
 }
 
@@ -1834,7 +1847,7 @@ int page_unprotect(target_ulong addr, un
            addr, vp->phys_addr, vp->prot);
 #endif
     if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
-        cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
+        cpu_abort(get_cpu_env(), "error mprotect addr=0x%lx prot=%d\n",
                   (unsigned long)addr, vp->prot);
     /* set the dirty bit */
     phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
@@ -2191,6 +2204,8 @@ static void notdirty_mem_writeb(void *op
     int dirty_flags;
     ram_addr = addr - (unsigned long)phys_ram_base;
     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    CPUState *env = get_cpu_env();
+
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 1);
@@ -2199,16 +2214,16 @@ static void notdirty_mem_writeb(void *op
     }
     stb_p((uint8_t *)(long)addr, val);
 #ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
+    if (env->kqemu_enabled &&
         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
+        kqemu_modify_page(env, ram_addr);
 #endif
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
-        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
+        tlb_set_dirty(env, addr, env->mem_write_vaddr);
 }
 
 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, 
uint32_t val)
@@ -2217,6 +2232,7 @@ static void notdirty_mem_writew(void *op
     int dirty_flags;
     ram_addr = addr - (unsigned long)phys_ram_base;
     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    CPUState *env = get_cpu_env();
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 2);
@@ -2225,16 +2241,16 @@ static void notdirty_mem_writew(void *op
     }
     stw_p((uint8_t *)(long)addr, val);
 #ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
+    if (env->kqemu_enabled &&
         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
+        kqemu_modify_page(env, ram_addr);
 #endif
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
-        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
+        tlb_set_dirty(env, addr, env->mem_write_vaddr);
 }
 
 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
@@ -2243,6 +2259,7 @@ static void notdirty_mem_writel(void *op
     int dirty_flags;
     ram_addr = addr - (unsigned long)phys_ram_base;
     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    CPUState *env = get_cpu_env();
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 4);
@@ -2251,16 +2268,16 @@ static void notdirty_mem_writel(void *op
     }
     stl_p((uint8_t *)(long)addr, val);
 #ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
+    if (env->kqemu_enabled &&
         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
+        kqemu_modify_page(env, ram_addr);
 #endif
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
-        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
+        tlb_set_dirty(env, addr, env->mem_write_vaddr);
 }
 
 static CPUReadMemoryFunc *error_mem_read[3] = {
@@ -2299,7 +2316,7 @@ static uint32_t watch_mem_readl(void *op
    address in case of a RAM location.  */
 static target_ulong check_watchpoint(target_phys_addr_t addr)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     target_ulong watch;
     target_ulong retaddr;
     int i;
@@ -2310,8 +2327,8 @@ static target_ulong check_watchpoint(tar
         if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) {
             retaddr = addr - env->watchpoint[i].addend;
             if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) {
-                cpu_single_env->watchpoint_hit = i + 1;
-                cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG);
+                env->watchpoint_hit = i + 1;
+                cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
                 break;
             }
         }
@@ -3100,7 +3117,6 @@ void dump_exec_info(FILE *f,
 
 #define MMUSUFFIX _cmmu
 #define GETPC() NULL
-#define env cpu_single_env
 #define SOFTMMU_CODE_ACCESS
 
 #define SHIFT 0
Index: kvm-userspace.io/qemu/hw/apic.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/apic.c
+++ kvm-userspace.io/qemu/hw/apic.c
@@ -592,7 +592,7 @@ static uint32_t apic_mem_readl(void *opa
     uint32_t val;
     int index;
 
-    env = cpu_single_env;
+    env = get_cpu_env();
     if (!env)
         return 0;
     s = env->apic_state;
@@ -671,7 +671,7 @@ static void apic_mem_writel(void *opaque
     APICState *s;
     int index;
 
-    env = cpu_single_env;
+    env = get_cpu_env();
     if (!env)
         return;
     s = env->apic_state;
Index: kvm-userspace.io/qemu/hw/dma.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/dma.c
+++ kvm-userspace.io/qemu/hw/dma.c
@@ -428,9 +428,7 @@ int DMA_write_memory (int nchan, void *b
 /* request the emulator to transfer a new DMA memory block ASAP */
 void DMA_schedule(int nchan)
 {
-    CPUState *env = cpu_single_env;
-    if (env)
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+    cpu_interrupt(get_cpu_env(), CPU_INTERRUPT_EXIT);
 }
 
 static void dma_reset(void *opaque)
Index: kvm-userspace.io/qemu/hw/vmmouse.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vmmouse.c
+++ kvm-userspace.io/qemu/hw/vmmouse.c
@@ -167,7 +167,7 @@ static void vmmouse_data(VMMouseState *s
 
 static void vmmouse_get_data(uint32_t *data)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
     data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
     data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
@@ -179,7 +179,7 @@ static void vmmouse_get_data(uint32_t *d
 
 static void vmmouse_set_data(const uint32_t *data)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
     DPRINTF("set_data = {%x, %x, %x, %x, %x, %x}\n",
             data[0], data[1], data[2], data[3], data[4], data[5]);
Index: kvm-userspace.io/qemu/hw/vmport.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vmport.c
+++ kvm-userspace.io/qemu/hw/vmport.c
@@ -54,7 +54,7 @@ void vmport_register(unsigned char comma
 static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
 {
     VMPortState *s = opaque;
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     unsigned char command;
     uint32_t eax;
     uint32_t ret;
@@ -85,14 +85,14 @@ static uint32_t vmport_ioport_read(void 
 
 static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     env->regs[R_EBX] = VMPORT_MAGIC;
     return 6;
 }
 
 static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     env->regs[R_EBX] = 0x1177;
     return ram_size;
 }
Index: kvm-userspace.io/qemu/qemu-kvm-x86.c
===================================================================
--- kvm-userspace.io.orig/qemu/qemu-kvm-x86.c
+++ kvm-userspace.io/qemu/qemu-kvm-x86.c
@@ -584,7 +584,7 @@ int kvm_arch_qemu_init_env(CPUState *cen
 
 int kvm_arch_halt(void *opaque, int vcpu)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
     if (!((env->interrupt_request & CPU_INTERRUPT_HARD) &&
          (env->eflags & IF_MASK))) {
@@ -596,7 +596,7 @@ int kvm_arch_halt(void *opaque, int vcpu
 
 void kvm_arch_pre_kvm_run(void *opaque, int vcpu)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
     if (!kvm_irqchip_in_kernel(kvm_context))
        kvm_set_cr8(kvm_context, vcpu, cpu_get_apic_tpr(env));
@@ -604,8 +604,7 @@ void kvm_arch_pre_kvm_run(void *opaque, 
 
 void kvm_arch_post_kvm_run(void *opaque, int vcpu)
 {
-    CPUState *env = qemu_kvm_cpu_env(vcpu);
-    cpu_single_env = env;
+    CPUState *env = get_cpu_env();
 
     env->eflags = kvm_get_interrupt_flag(kvm_context, vcpu)
        ? env->eflags | IF_MASK : env->eflags & ~IF_MASK;
@@ -626,7 +625,7 @@ int kvm_arch_has_work(CPUState *env)
 
 int kvm_arch_try_push_interrupts(void *opaque)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     int r, irq;
 
     if (env->ready_for_interrupt_injection &&
@@ -657,6 +656,6 @@ void kvm_arch_update_regs_for_sipi(CPUSt
 int handle_tpr_access(void *opaque, int vcpu,
                             uint64_t rip, int is_write)
 {
-    kvm_tpr_access_report(cpu_single_env, rip, is_write);
+    kvm_tpr_access_report(get_cpu_env(), rip, is_write);
     return 0;
 }
Index: kvm-userspace.io/qemu/qemu-kvm.c
===================================================================
--- kvm-userspace.io.orig/qemu/qemu-kvm.c
+++ kvm-userspace.io/qemu/qemu-kvm.c
@@ -66,6 +66,40 @@ CPUState *qemu_kvm_cpu_env(int index)
     return vcpu_info[index].env;
 }
 
+CPUState *kvm_get_cpu_env(void)
+{
+    CPUState *env = NULL;
+
+    if (vcpu)
+        env = vcpu->env;
+
+    return env;
+}
+
+void kvm_set_cpu_env(CPUState *env)
+{
+    if (vcpu)
+        vcpu->env = env;
+}
+
+static CPUState *curr_cpu_env;
+
+void set_cpu_env(CPUState *env)
+{
+    if (kvm_enabled())
+        kvm_set_cpu_env(env);
+    else
+        curr_cpu_env = env;
+}
+
+CPUState *get_cpu_env(void)
+{
+    if (kvm_enabled())
+        return kvm_get_cpu_env();
+    else
+        return curr_cpu_env;
+}
+
 static void sig_ipi_handler(int n)
 {
 }
@@ -195,8 +229,6 @@ static int kvm_eat_signal(struct qemu_kv
        return 0;
     e = errno;
     pthread_mutex_lock(&qemu_mutex);
-    if (env && vcpu)
-        cpu_single_env = vcpu->env;
     if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
        printf("sigtimedwait: %s\n", strerror(e));
        exit(1);
@@ -235,7 +267,6 @@ static void kvm_main_loop_wait(CPUState 
     pthread_mutex_unlock(&qemu_mutex);
     kvm_eat_signals(env, timeout);
     pthread_mutex_lock(&qemu_mutex);
-    cpu_single_env = env;
     vcpu_info[env->cpu_index].signalled = 0;
 }
 
@@ -316,7 +347,6 @@ static int kvm_main_loop_cpu(CPUState *e
     kvm_tpr_vcpu_start(env);
 #endif
 
-    cpu_single_env = env;
     while (1) {
        while (!has_work(env))
            kvm_main_loop_wait(env, 10);
@@ -428,9 +458,10 @@ int kvm_main_loop(void)
     io_thread = pthread_self();
     pthread_mutex_unlock(&qemu_mutex);
     while (1) {
+        if (get_cpu_env())
+            hw_error("io thread has valid env\n");
         kvm_eat_signal(&io_signal_table, NULL, 1000);
         pthread_mutex_lock(&qemu_mutex);
-        cpu_single_env = NULL;
         main_loop_wait(0);
         if (qemu_shutdown_requested())
             break;
@@ -449,7 +480,7 @@ int kvm_main_loop(void)
 
 static int kvm_debug(void *opaque, int vcpu)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
     env->exception_index = EXCP_DEBUG;
     return 1;
@@ -579,7 +610,7 @@ static struct kvm_callbacks qemu_kvm_ops
 int kvm_qemu_init()
 {
     /* Try to initialize kvm */
-    kvm_context = kvm_init(&qemu_kvm_ops, cpu_single_env);
+    kvm_context = kvm_init(&qemu_kvm_ops, get_cpu_env());
     if (!kvm_context) {
        return -1;
     }
@@ -798,17 +829,16 @@ void qemu_kvm_aio_wait_start(void)
 
 void qemu_kvm_aio_wait(void)
 {
-    CPUState *cpu_single = cpu_single_env;
+    CPUState *env = get_cpu_env();
 
-    if (!cpu_single_env) {
+    /* io thread */
+    if (!env) {
         pthread_mutex_unlock(&qemu_mutex);
         kvm_eat_signal(&io_signal_table, NULL, 1000);
         pthread_mutex_lock(&qemu_mutex);
-        cpu_single_env = NULL;
-    } else {
+    /* vcpu thread */
+    } else
         pthread_cond_wait(&qemu_aio_cond, &qemu_mutex);
-        cpu_single_env = cpu_single;
-    }
 }
 
 void qemu_kvm_aio_wait_end(void)
Index: kvm-userspace.io/qemu/softmmu_header.h
===================================================================
--- kvm-userspace.io.orig/qemu/softmmu_header.h
+++ kvm-userspace.io/qemu/softmmu_header.h
@@ -46,12 +46,12 @@
 
 #elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(get_cpu_env()))
 #define MMUSUFFIX _mmu
 
 #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(get_cpu_env()))
 #define MMUSUFFIX _cmmu
 
 #else
@@ -227,6 +227,7 @@ static inline RES_TYPE glue(glue(ld, USU
     target_ulong addr;
     unsigned long physaddr;
     int mmu_idx;
+    CPUState *env = get_cpu_env();
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -248,6 +249,7 @@ static inline int glue(glue(lds, SUFFIX)
     target_ulong addr;
     unsigned long physaddr;
     int mmu_idx;
+    CPUState *env = get_cpu_env();
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -273,6 +275,7 @@ static inline void glue(glue(st, SUFFIX)
     target_ulong addr;
     unsigned long physaddr;
     int mmu_idx;
+    CPUState *env = get_cpu_env();
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
Index: kvm-userspace.io/qemu/target-i386/helper.c
===================================================================
--- kvm-userspace.io.orig/qemu/target-i386/helper.c
+++ kvm-userspace.io/qemu/target-i386/helper.c
@@ -3933,7 +3933,7 @@ void tlb_fill(target_ulong addr, int is_
     /* XXX: hack to restore env in all cases, even if not called from
        generated code */
     saved_env = env;
-    env = cpu_single_env;
+    env = get_cpu_env();
 
     ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
Index: kvm-userspace.io/qemu/vl.c
===================================================================
--- kvm-userspace.io.orig/qemu/vl.c
+++ kvm-userspace.io/qemu/vl.c
@@ -7577,7 +7577,7 @@ int qemu_bh_poll(void)
 
 void qemu_bh_schedule(QEMUBH *bh)
 {
-    CPUState *env = cpu_single_env;
+    CPUState *env = get_cpu_env();
     if (bh->scheduled)
         return;
     bh->scheduled = 1;
@@ -7585,9 +7585,8 @@ void qemu_bh_schedule(QEMUBH *bh)
     first_bh = bh;
 
     /* stop the currently executing CPU to execute the BH ASAP */
-    if (env) {
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-    }
+    cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+
     if (kvm_enabled())
         qemu_kvm_notify_work();
 }
@@ -7795,22 +7794,20 @@ void qemu_system_reset_request(void)
     } else {
         reset_requested = 1;
     }
-    if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+    cpu_interrupt(get_cpu_env(), CPU_INTERRUPT_EXIT);
 }
 
 void qemu_system_shutdown_request(void)
 {
     shutdown_requested = 1;
-    if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+
+    cpu_interrupt(get_cpu_env(), CPU_INTERRUPT_EXIT);
 }
 
 void qemu_system_powerdown_request(void)
 {
     powerdown_requested = 1;
-    if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+    cpu_interrupt(get_cpu_env(), CPU_INTERRUPT_EXIT);
 }
 
 void main_loop_wait(int timeout)
Index: kvm-userspace.io/qemu/softmmu_template.h
===================================================================
--- kvm-userspace.io.orig/qemu/softmmu_template.h
+++ kvm-userspace.io/qemu/softmmu_template.h
@@ -55,6 +55,9 @@ static inline DATA_TYPE glue(io_read, SU
 {
     DATA_TYPE res;
     int index;
+#ifdef USE_KQEMU
+    CPUState *env = get_cpu_env();
+#endif
 
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 #if SHIFT <= 2
@@ -83,6 +86,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX
     target_ulong tlb_addr;
     target_phys_addr_t physaddr;
     void *retaddr;
+    CPUState *env = get_cpu_env();
 
     /* test if there is match for unaligned or IO access */
     /* XXX: could done more in memory macro in a non portable way */
@@ -137,6 +141,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
     int index, shift;
     target_phys_addr_t physaddr;
     target_ulong tlb_addr, addr1, addr2;
+    CPUState *env = get_cpu_env();
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
@@ -189,6 +194,7 @@ static inline void glue(io_write, SUFFIX
                                           void *retaddr)
 {
     int index;
+    CPUState *env = get_cpu_env();
 
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     env->mem_write_vaddr = tlb_addr;
@@ -217,6 +223,7 @@ void REGPARM glue(glue(__st, SUFFIX), MM
     target_ulong tlb_addr;
     void *retaddr;
     int index;
+    CPUState *env = get_cpu_env();
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
@@ -268,6 +275,7 @@ static void glue(glue(slow_st, SUFFIX), 
     target_phys_addr_t physaddr;
     target_ulong tlb_addr;
     int index, i;
+    CPUState *env = get_cpu_env();
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:

-- 


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to