Patchwork [qom-next,59/59] cpu: Move halted and interrupt_request to CPUState

login
register
mail settings
Submitter Andreas Färber
Date May 23, 2012, 3:08 a.m.
Message ID <1337742502-28565-60-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/160834/
State New
Headers show

Comments

Andreas Färber - May 23, 2012, 3:08 a.m.
For target-cris use i32 for halted instead of tl. This effectively makes
no difference since it is 32-bit.

For Xen pass CPUState to xen_reset_vcpu().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-defs.h                |    2 -
 cpu-exec.c                |   32 +++++++++++++++-------------
 cpus.c                    |    4 +-
 exec.c                    |   34 ++++++++++++++++++++-----------
 gdbstub.c                 |    4 ++-
 hw/leon3.c                |    2 +-
 hw/omap1.c                |    4 +-
 hw/pc.c                   |    6 ++--
 hw/ppc.c                  |   10 ++++----
 hw/ppce500_mpc8544ds.c    |    4 +-
 hw/ppce500_spin.c         |    2 +-
 hw/pxa2xx_gpio.c          |    3 +-
 hw/pxa2xx_pic.c           |    2 +-
 hw/s390-virtio.c          |   14 ++++++++----
 hw/spapr.c                |    4 +-
 hw/spapr_hcall.c          |    2 +-
 hw/spapr_rtas.c           |    8 ++++--
 hw/sun4m.c                |   18 +++++++---------
 hw/sun4u.c                |    9 ++++---
 hw/xen_machine_pv.c       |    4 +--
 hw/xtensa_pic.c           |    5 ++-
 include/qemu/cpu.h        |    4 +++
 kvm-all.c                 |    2 +-
 qom/cpu.c                 |    2 +
 target-alpha/cpu.h        |    4 +--
 target-alpha/translate.c  |    3 +-
 target-arm/cpu.h          |    4 +--
 target-arm/helper.c       |    3 +-
 target-arm/op_helper.c    |    4 ++-
 target-cris/cpu.h         |    4 +--
 target-cris/translate.c   |    4 ++-
 target-i386/cpu.h         |    6 ++--
 target-i386/helper.c      |   14 +++++++-----
 target-i386/kvm.c         |   49 +++++++++++++++++++++++---------------------
 target-i386/op_helper.c   |   13 ++++++++---
 target-lm32/cpu.h         |    4 +--
 target-lm32/op_helper.c   |    4 ++-
 target-m68k/cpu.h         |    4 +--
 target-m68k/op_helper.c   |    3 +-
 target-m68k/qregs.def     |    1 -
 target-m68k/translate.c   |    6 +++++
 target-microblaze/cpu.h   |    4 +--
 target-mips/cpu.h         |    4 +-
 target-mips/op_helper.c   |   11 ++++++---
 target-mips/translate.c   |    8 +++++-
 target-ppc/cpu.h          |    2 +-
 target-ppc/helper.c       |    4 +-
 target-ppc/helper_regs.h  |    7 ++++-
 target-ppc/kvm.c          |   13 ++++++++---
 target-ppc/op_helper.c    |    8 +++++-
 target-ppc/translate.c    |    3 +-
 target-s390x/cpu.h        |    2 +-
 target-s390x/helper.c     |   10 ++++++--
 target-s390x/kvm.c        |    4 ++-
 target-sh4/cpu.h          |    4 +--
 target-sh4/helper.c       |    5 ++-
 target-sh4/op_helper.c    |    4 ++-
 target-sparc/cpu.h        |    2 +-
 target-unicore32/cpu.h    |    4 +--
 target-xtensa/op_helper.c |    4 ++-
 xen-all.c                 |   10 +++++---
 61 files changed, 244 insertions(+), 180 deletions(-)

Patch

diff --git a/cpu-defs.h b/cpu-defs.h
index d846674..bc851fd 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -162,8 +162,6 @@  typedef struct CPUWatchpoint {
                             accessed */                                 \
     target_ulong mem_io_vaddr; /* target virtual addr at which the      \
                                      memory was accessed */             \
-    uint32_t halted; /* Nonzero if the CPU is in suspend state */       \
-    uint32_t interrupt_request;                                         \
     volatile sig_atomic_t exit_request;                                 \
     CPU_COMMON_TLB                                                      \
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
diff --git a/cpu-exec.c b/cpu-exec.c
index da0c17a..5674bac 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -190,12 +190,12 @@  int cpu_exec(CPUArchState *env)
     uint8_t *tc_ptr;
     tcg_target_ulong next_tb;
 
-    if (env->halted) {
+    if (cpu->halted) {
         if (!cpu_has_work(cpu)) {
             return EXCP_HALTED;
         }
 
-        env->halted = 0;
+        cpu->halted = 0;
     }
 
     cpu_single_env = env;
@@ -264,14 +264,14 @@  int cpu_exec(CPUArchState *env)
 
             next_tb = 0; /* force lookup of first TB */
             for(;;) {
-                interrupt_request = env->interrupt_request;
+                interrupt_request = cpu->interrupt_request;
                 if (unlikely(interrupt_request)) {
                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
                         /* Mask out external interrupts for this step. */
                         interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
                     }
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
-                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                         env->exception_index = EXCP_DEBUG;
                         cpu_loop_exit(env);
                     }
@@ -279,8 +279,8 @@  int cpu_exec(CPUArchState *env)
     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
     defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
                     if (interrupt_request & CPU_INTERRUPT_HALT) {
-                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
-                        env->halted = 1;
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
+                        cpu->halted = 1;
                         env->exception_index = EXCP_HLT;
                         cpu_loop_exit(env);
                     }
@@ -297,17 +297,17 @@  int cpu_exec(CPUArchState *env)
                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                             !(env->hflags & HF_SMM_MASK)) {
                             svm_check_intercept(env, SVM_EXIT_SMI);
-                            env->interrupt_request &= ~CPU_INTERRUPT_SMI;
+                            cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
                             do_smm_enter(env);
                             next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
                                    !(env->hflags2 & HF2_NMI_MASK)) {
-                            env->interrupt_request &= ~CPU_INTERRUPT_NMI;
+                            cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
                             env->hflags2 |= HF2_NMI_MASK;
                             do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
                             next_tb = 0;
                         } else if (interrupt_request & CPU_INTERRUPT_MCE) {
-                            env->interrupt_request &= ~CPU_INTERRUPT_MCE;
+                            cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
                             do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
                             next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
@@ -318,7 +318,8 @@  int cpu_exec(CPUArchState *env)
                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
                             int intno;
                             svm_check_intercept(env, SVM_EXIT_INTR);
-                            env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
+                            cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
+                                                        CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
                             do_interrupt_x86_hardirq(env, intno, 1);
@@ -335,7 +336,7 @@  int cpu_exec(CPUArchState *env)
                             intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
                             do_interrupt_x86_hardirq(env, intno, 1);
-                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+                            cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
                             next_tb = 0;
 #endif
                         }
@@ -346,8 +347,9 @@  int cpu_exec(CPUArchState *env)
                     }
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         ppc_hw_interrupt(env);
-                        if (env->pending_interrupts == 0)
-                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                        if (env->pending_interrupts == 0) {
+                            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                        }
                         next_tb = 0;
                     }
 #elif defined(TARGET_LM32)
@@ -499,8 +501,8 @@  int cpu_exec(CPUArchState *env)
 #endif
                    /* Don't use the cached interrupt_request value,
                       do_interrupt may have updated the EXITTB flag. */
-                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
-                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
+                    if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
                         /* ensure that no TB jump will be modified as
                            the program flow was changed */
                         next_tb = 0;
diff --git a/cpus.c b/cpus.c
index a403629..227ef2f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -443,7 +443,7 @@  static bool cpu_thread_is_idle(CPUArchState *env)
     if (cpu->stopped || !runstate_is_running()) {
         return true;
     }
-    if (!env->halted || qemu_cpu_has_work(cpu) || kvm_irqchip_in_kernel()) {
+    if (!cpu->halted || qemu_cpu_has_work(cpu) || kvm_irqchip_in_kernel()) {
         return false;
     }
     return true;
@@ -1214,7 +1214,7 @@  CpuInfoList *qmp_query_cpus(Error **errp)
         info->value = g_malloc0(sizeof(*info->value));
         info->value->CPU = env->cpu_index;
         info->value->current = (env == first_cpu);
-        info->value->halted = env->halted;
+        info->value->halted = cpu->halted;
         info->value->thread_id = cpu->thread_id;
 #if defined(TARGET_I386)
         info->value->has_pc = true;
diff --git a/exec.c b/exec.c
index 8d2fa7a..f62e643 100644
--- a/exec.c
+++ b/exec.c
@@ -654,12 +654,12 @@  void cpu_exec_init_all(void)
 
 static int cpu_common_post_load(void *opaque, int version_id)
 {
-    CPUArchState *env = opaque;
+    CPUState *cpu = opaque;
 
     /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
        version_id is increased. */
-    env->interrupt_request &= ~0x01;
-    tlb_flush(env, 1);
+    cpu->interrupt_request &= ~0x01;
+    cpu_tlb_flush(cpu, true);
 
     return 0;
 }
@@ -671,8 +671,8 @@  static const VMStateDescription vmstate_cpu_common = {
     .minimum_version_id_old = 1,
     .post_load = cpu_common_post_load,
     .fields      = (VMStateField []) {
-        VMSTATE_UINT32(halted, CPUArchState),
-        VMSTATE_UINT32(interrupt_request, CPUArchState),
+        VMSTATE_UINT32(halted, CPUState),
+        VMSTATE_UINT32(interrupt_request, CPUState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -721,7 +721,7 @@  void cpu_exec_init(CPUArchState *env)
     cpu_list_unlock();
 #endif
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);
+    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, ENV_GET_CPU(env));
     register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
                     cpu_save, cpu_load, env);
 #endif
@@ -1104,6 +1104,7 @@  void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access)
 {
     TranslationBlock *tb, *tb_next, *saved_tb;
+    CPUState *cpu = NULL;
     CPUArchState *env = cpu_single_env;
     tb_page_addr_t tb_start, tb_end;
     PageDesc *p;
@@ -1117,6 +1118,10 @@  void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
     int current_flags = 0;
 #endif /* TARGET_HAS_PRECISE_SMC */
 
+    if (env != NULL) {
+        cpu = ENV_GET_CPU(env);
+    }
+
     p = page_find(start >> TARGET_PAGE_BITS);
     if (!p)
         return;
@@ -1178,8 +1183,9 @@  void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
             tb_phys_invalidate(tb, -1);
             if (env) {
                 env->current_tb = saved_tb;
-                if (env->interrupt_request && env->current_tb)
-                    cpu_interrupt(env, env->interrupt_request);
+                if (cpu->interrupt_request && env->current_tb) {
+                    cpu_interrupt(env, cpu->interrupt_request);
+                }
             }
         }
         tb = tb_next;
@@ -1740,8 +1746,8 @@  static void tcg_handle_interrupt(CPUArchState *env, int mask)
     CPUState *cpu = ENV_GET_CPU(env);
     int old_mask;
 
-    old_mask = env->interrupt_request;
-    env->interrupt_request |= mask;
+    old_mask = cpu->interrupt_request;
+    cpu->interrupt_request |= mask;
 
     /*
      * If called from iothread context, wake the target cpu in
@@ -1769,14 +1775,18 @@  CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
 
 void cpu_interrupt(CPUArchState *env, int mask)
 {
-    env->interrupt_request |= mask;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    cpu->interrupt_request |= mask;
     cpu_unlink_tb(env);
 }
 #endif /* CONFIG_USER_ONLY */
 
 void cpu_reset_interrupt(CPUArchState *env, int mask)
 {
-    env->interrupt_request &= ~mask;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    cpu->interrupt_request &= ~mask;
 }
 
 void cpu_exit(CPUArchState *env)
diff --git a/gdbstub.c b/gdbstub.c
index 6a77a66..47cbfdd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2284,10 +2284,12 @@  static int gdb_handle_packet(GDBState *s, const char *line_buf)
             thread = strtoull(p+16, (char **)&p, 16);
             env = find_cpu(thread);
             if (env != NULL) {
+                CPUState *cpu = ENV_GET_CPU(env);
+
                 cpu_synchronize_state(env);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
                                "CPU#%d [%s]", env->cpu_index,
-                               env->halted ? "halted " : "running");
+                               cpu->halted ? "halted " : "running");
                 memtohex(buf, mem_buf, len);
                 put_packet(s, buf);
             }
diff --git a/hw/leon3.c b/hw/leon3.c
index 878d3aa..8d44f83 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -53,7 +53,7 @@  static void main_cpu_reset(void *opaque)
 
     cpu_reset(CPU(s->cpu));
 
-    env->halted = 0;
+    CPU(s->cpu)->halted = 0;
     env->pc     = s->entry;
     env->npc    = s->entry + 4;
 }
diff --git a/hw/omap1.c b/hw/omap1.c
index ad60cc4..e90aed4 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -1735,7 +1735,7 @@  static uint64_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr,
 
     case 0x18:	/* DSP_SYSST */
         return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
-                (s->cpu->env.halted << 6);      /* Quite useless... */
+                (CPU(s->cpu)->halted << 6);      /* Quite useless... */
     }
 
     OMAP_BAD_REG(addr);
@@ -3752,7 +3752,7 @@  void omap_mpu_wakeup(void *opaque, int irq, int req)
 {
     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
-    if (mpu->cpu->env.halted) {
+    if (CPU(mpu->cpu)->halted) {
         cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
     }
 }
diff --git a/hw/pc.c b/hw/pc.c
index f0cbfef..c8caada 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -942,10 +942,10 @@  void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
 static void pc_cpu_reset(void *opaque)
 {
     X86CPU *cpu = opaque;
-    CPUX86State *env = &cpu->env;
+    CPUState *c = CPU(cpu);
 
-    cpu_reset(CPU(cpu));
-    env->halted = !cpu_is_bsp(cpu);
+    cpu_reset(c);
+    c->halted = !cpu_is_bsp(cpu);
 }
 
 static X86CPU *pc_new_cpu(const char *cpu_model)
diff --git a/hw/ppc.c b/hw/ppc.c
index fa7ae74..02c5e3e 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -125,7 +125,7 @@  static void ppc6xx_set_irq(void *opaque, int pin, int level)
             /* XXX: Note that the only way to restart the CPU is to reset it */
             if (level) {
                 LOG_IRQ("%s: stop the CPU\n", __func__);
-                env->halted = 1;
+                CPU(cpu)->halted = 1;
             }
             break;
         case PPC6xx_INPUT_HRESET:
@@ -202,10 +202,10 @@  static void ppc970_set_irq(void *opaque, int pin, int level)
             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
             if (level) {
                 LOG_IRQ("%s: stop the CPU\n", __func__);
-                env->halted = 1;
+                CPU(cpu)->halted = 1;
             } else {
                 LOG_IRQ("%s: restart the CPU\n", __func__);
-                env->halted = 0;
+                CPU(cpu)->halted = 0;
                 qemu_cpu_kick(CPU(cpu));
             }
             break;
@@ -331,10 +331,10 @@  static void ppc40x_set_irq(void *opaque, int pin, int level)
             /* Level sensitive - active low */
             if (level) {
                 LOG_IRQ("%s: stop the CPU\n", __func__);
-                env->halted = 1;
+                CPU(cpu)->halted = 1;
             } else {
                 LOG_IRQ("%s: restart the CPU\n", __func__);
-                env->halted = 0;
+                CPU(cpu)->halted = 0;
                 qemu_cpu_kick(CPU(cpu));
             }
             break;
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 3eb8a23..ab826de 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -203,7 +203,7 @@  static void mpc8544ds_cpu_reset_sec(void *opaque)
 
     /* Secondary CPU starts in halted state for now. Needs to change when
        implementing non-kernel boot. */
-    env->halted = 1;
+    CPU(cpu)->halted = 1;
     env->exception_index = EXCP_HLT;
 }
 
@@ -216,7 +216,7 @@  static void mpc8544ds_cpu_reset(void *opaque)
     cpu_reset(CPU(cpu));
 
     /* Set initial guest state. */
-    env->halted = 0;
+    CPU(cpu)->halted = 0;
     env->gpr[1] = (16<<20) - 8;
     env->gpr[3] = bi->dt_base;
     env->nip = bi->entry;
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
index a4b49e6..65f0b6f 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -112,7 +112,7 @@  static void spin_kick(void *data)
     map_start = ldq_p(&curspin->addr) & ~(map_size - 1);
     mmubooke_create_initial_mapping(env, 0, map_start, map_size);
 
-    env->halted = 0;
+    cpu->halted = 0;
     env->exception_index = -1;
     cpu->stopped = false;
     qemu_cpu_kick(cpu);
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 3c90c9c..5fcb992 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -118,7 +118,8 @@  static void pxa2xx_gpio_set(void *opaque, int line, int level)
         pxa2xx_gpio_irq_update(s);
 
     /* Wake-up GPIOs */
-    if (s->cpu->env.halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
+    if (CPU(s->cpu)->halted &&
+        (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
         cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB);
     }
 }
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index c560133..c8f01e8 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -47,7 +47,7 @@  static void pxa2xx_pic_update(void *opaque)
     uint32_t mask[2];
     PXA2xxPICState *s = (PXA2xxPICState *) opaque;
 
-    if (s->cpu->env.halted) {
+    if (CPU(s->cpu)->halted) {
         mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
         mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
         if (mask[0] || mask[1]) {
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 47eed35..566760e 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -132,19 +132,23 @@  static unsigned s390_running_cpus;
 
 void s390_add_running_cpu(CPUS390XState *env)
 {
-    if (env->halted) {
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    if (cpu->halted) {
         s390_running_cpus++;
-        env->halted = 0;
+        cpu->halted = 0;
         env->exception_index = -1;
     }
 }
 
 unsigned s390_del_running_cpu(CPUS390XState *env)
 {
-    if (env->halted == 0) {
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    if (cpu->halted == 0) {
         assert(s390_running_cpus >= 1);
         s390_running_cpus--;
-        env->halted = 1;
+        cpu->halted = 1;
         env->exception_index = EXCP_HLT;
     }
     return s390_running_cpus;
@@ -218,7 +222,7 @@  static void s390_init(ram_addr_t my_ram_size,
             env = tmp_env;
         }
         ipi_states[i] = cpu;
-        tmp_env->halted = 1;
+        CPU(cpu)->halted = 1;
         tmp_env->exception_index = EXCP_HLT;
         tmp_env->storage_keys = storage_keys;
     }
diff --git a/hw/spapr.c b/hw/spapr.c
index f9c3631..d553951 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -500,7 +500,7 @@  static void spapr_reset(void *opaque)
     /* Set up the entry state */
     first_cpu->gpr[3] = spapr->fdt_addr;
     first_cpu->gpr[5] = 0;
-    first_cpu->halted = 0;
+    ENV_GET_CPU(first_cpu)->halted = 0;
     first_cpu->nip = spapr->entry_point;
 
 }
@@ -732,7 +732,7 @@  static void ppc_spapr_init(ram_addr_t ram_size,
 
     /* SLOF will startup the secondary CPUs using RTAS */
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        env->halted = 1;
+        ENV_GET_CPU(env)->halted = 1;
     }
 
     /* Prepare the device tree */
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index ebb271c..7165796 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -550,7 +550,7 @@  static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     env->msr |= (1ULL << MSR_EE);
     hreg_compute_hflags(env);
     if (!cpu_has_work(CPU(cpu))) {
-        env->halted = 1;
+        CPU(cpu)->halted = 1;
     }
     return H_SUCCESS;
 }
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index a343055..d3c503c 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -131,6 +131,7 @@  static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
 {
     target_ulong id;
     CPUPPCState *env;
+    CPUState *cpu;
 
     if (nargs != 1 || nret != 2) {
         rtas_st(rets, 0, -3);
@@ -139,11 +140,12 @@  static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
 
     id = rtas_ld(args, 0);
     for (env = first_cpu; env; env = env->next_cpu) {
+        cpu = ENV_GET_CPU(env);
         if (env->cpu_index != id) {
             continue;
         }
 
-        if (env->halted) {
+        if (cpu->halted) {
             rtas_st(rets, 1, 0);
         } else {
             rtas_st(rets, 1, 2);
@@ -182,7 +184,7 @@  static void rtas_start_cpu(sPAPREnvironment *spapr,
             continue;
         }
 
-        if (!env->halted) {
+        if (!cpu->halted) {
             rtas_st(rets, 0, -1);
             return;
         }
@@ -190,7 +192,7 @@  static void rtas_start_cpu(sPAPREnvironment *spapr,
         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
         env->nip = start;
         env->gpr[3] = r3;
-        env->halted = 0;
+        cpu->halted = 0;
 
         qemu_cpu_kick(cpu);
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 4929677..7bb0bce 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -257,7 +257,7 @@  static void cpu_kick_irq(SPARCCPU *cpu)
 {
     CPUSPARCState *env = &cpu->env;
 
-    env->halted = 0;
+    CPU(cpu)->halted = 0;
     cpu_check_irqs(env);
     qemu_cpu_kick(CPU(cpu));
 }
@@ -284,20 +284,18 @@  static void dummy_cpu_set_irq(void *opaque, int irq, int level)
 
 static void main_cpu_reset(void *opaque)
 {
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
+    CPUState *cpu = CPU(opaque);
 
-    cpu_reset(CPU(cpu));
-    env->halted = 0;
+    cpu_reset(cpu);
+    cpu->halted = 0;
 }
 
 static void secondary_cpu_reset(void *opaque)
 {
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
+    CPUState *cpu = CPU(opaque);
 
-    cpu_reset(CPU(cpu));
-    env->halted = 1;
+    cpu_reset(cpu);
+    cpu->halted = 1;
 }
 
 static void cpu_halt_signal(void *opaque, int irq, int level)
@@ -829,7 +827,7 @@  static void cpu_devinit(const char *cpu_model, unsigned int id,
         qemu_register_reset(main_cpu_reset, cpu);
     } else {
         qemu_register_reset(secondary_cpu_reset, cpu);
-        env->halted = 1;
+        CPU(cpu)->halted = 1;
     }
     *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
     env->prom_addr = prom_addr;
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 56c3ddf..affd7bc 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -253,6 +253,7 @@  static uint64_t sun4u_load_kernel(const char *kernel_filename,
 
 void cpu_check_irqs(CPUSPARCState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     uint32_t pil = env->pil_in |
                   (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
 
@@ -269,7 +270,7 @@  void cpu_check_irqs(CPUSPARCState *env)
     /* The bit corresponding to psrpil is (1<< psrpil), the next bit
        is (2 << psrpil). */
     if (pil < (2 << env->psrpil)){
-        if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+        if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
             CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
                            env->interrupt_index);
             env->interrupt_index = 0;
@@ -301,7 +302,7 @@  void cpu_check_irqs(CPUSPARCState *env)
                 break;
             }
         }
-    } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+    } else if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
         CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
                        "current interrupt %x\n",
                        pil, env->pil_in, env->softint, env->interrupt_index);
@@ -314,7 +315,7 @@  static void cpu_kick_irq(SPARCCPU *cpu)
 {
     CPUSPARCState *env = &cpu->env;
 
-    env->halted = 0;
+    CPU(cpu)->halted = 0;
     cpu_check_irqs(env);
     qemu_cpu_kick(CPU(cpu));
 }
@@ -327,7 +328,7 @@  static void cpu_set_ivec_irq(void *opaque, int irq, int level)
     if (level) {
         if (!(env->ivec_status & 0x20)) {
             CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
-            env->halted = 0;
+            CPU(cpu)->halted = 0;
             env->interrupt_index = TT_IVEC;
             env->ivec_status |= 0x20;
             env->ivec_data[0] = (0x1f << 6) | irq;
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 4b72aa7..c387fdf 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -37,7 +37,6 @@  static void xen_init_pv(ram_addr_t ram_size,
 			const char *cpu_model)
 {
     X86CPU *cpu;
-    CPUX86State *env;
     DriveInfo *dinfo;
     int i;
 
@@ -50,8 +49,7 @@  static void xen_init_pv(ram_addr_t ram_size,
 #endif
     }
     cpu = cpu_x86_init(cpu_model);
-    env = &cpu->env;
-    env->halted = 1;
+    CPU(cpu)->halted = 1;
 
     /* Initialize backend core & drivers */
     if (xen_be_init() != 0) {
diff --git a/hw/xtensa_pic.c b/hw/xtensa_pic.c
index 1ec70cd..8a65b92 100644
--- a/hw/xtensa_pic.c
+++ b/hw/xtensa_pic.c
@@ -47,6 +47,7 @@  void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
 
 void check_interrupts(CPUXtensaState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int minlevel = xtensa_get_cintlevel(env);
     uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
     int level;
@@ -54,7 +55,7 @@  void check_interrupts(CPUXtensaState *env)
     /* If the CPU is halted advance CCOUNT according to the vm_clock time
      * elapsed since the moment when it was advanced last time.
      */
-    if (env->halted) {
+    if (cpu->halted) {
         int64_t now = qemu_get_clock_ns(vm_clock);
 
         xtensa_advance_ccount(env,
@@ -128,7 +129,7 @@  static void xtensa_ccompare_cb(void *opaque)
     XtensaCPU *cpu = opaque;
     CPUXtensaState *env = &cpu->env;
 
-    if (env->halted) {
+    if (CPU(cpu)->halted) {
         env->halt_clock = qemu_get_clock_ns(vm_clock);
         xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
         if (!cpu_has_work(CPU(cpu))) {
diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
index 7d03369..5399593 100644
--- a/include/qemu/cpu.h
+++ b/include/qemu/cpu.h
@@ -58,6 +58,8 @@  typedef struct CPUClass {
 /**
  * CPUState:
  * @created: Indicates whether the CPU thread has been successfully created.
+ * @interrupt_request: Indicates a pending interrupt request.
+ * @halted: Nonzero if the CPU is in suspended state.
  * @stop: Indicates a pending stop request.
  * @stopped: Indicates the CPU has been artificially stopped.
  *
@@ -77,6 +79,8 @@  struct CPUState {
     struct qemu_work_item *queued_work_first, *queued_work_last;
     bool thread_kicked;
     bool created;
+    uint32_t interrupt_request;
+    uint32_t halted;
     bool stop;
     bool stopped;
 
diff --git a/kvm-all.c b/kvm-all.c
index bbd2049..b4b8a14 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -833,7 +833,7 @@  static void kvm_handle_interrupt(CPUArchState *env, int mask)
 {
     CPUState *cpu = ENV_GET_CPU(env);
 
-    env->interrupt_request |= mask;
+    cpu->interrupt_request |= mask;
 
     if (!qemu_cpu_is_self(cpu)) {
         qemu_cpu_kick(cpu);
diff --git a/qom/cpu.c b/qom/cpu.c
index 729f4cf..9ae9a3c 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -32,6 +32,8 @@  void cpu_reset(CPUState *cpu)
 
 static void cpu_common_reset(CPUState *cpu)
 {
+    cpu->halted = 0;
+    cpu->interrupt_request = 0;
 }
 
 void cpu_tlb_flush(CPUState *cpu, bool flush_global)
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index a43fb94..3f321e2 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -501,8 +501,6 @@  static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUAlphaState *env = &ALPHA_CPU(cpu)->env;
-
     /* Here we are checking to see if the CPU should wake up from HALT.
        We will have gotten into this state only for WTINT from PALmode.  */
     /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
@@ -510,7 +508,7 @@  static inline bool cpu_has_work(CPUState *cpu)
        assume that if a CPU really wants to stay asleep, it will mask
        interrupts at the chipset level, which will prevent these bits
        from being set in the first place.  */
-    return env->interrupt_request & (CPU_INTERRUPT_HARD
+    return cpu->interrupt_request & (CPU_INTERRUPT_HARD
                                      | CPU_INTERRUPT_TIMER
                                      | CPU_INTERRUPT_SMP
                                      | CPU_INTERRUPT_MCHK);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 12de6a3..4ec7a7d 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1693,7 +1693,8 @@  static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
     case 253:
         /* WAIT */
         tmp = tcg_const_i64(1);
-        tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUAlphaState, halted));
+        tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUState, halted)
+                                     - offsetof(AlphaCPU, env));
         return gen_excp(ctx, EXCP_HLT, 0);
 
     case 252:
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index d4a19be..0cf883f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -553,9 +553,7 @@  static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUARMState *env = &ARM_CPU(cpu)->env;
-
-    return env->interrupt_request &
+    return cpu->interrupt_request &
         (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index bbb1d05..39a455d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -527,6 +527,7 @@  static void do_interrupt_v7m(CPUARMState *env)
 /* Handle a CPU exception.  */
 void do_interrupt(CPUARMState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     uint32_t addr;
     uint32_t mask;
     int new_mode;
@@ -632,7 +633,7 @@  void do_interrupt(CPUARMState *env)
     }
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
-    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+    cpu->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
 
 /* Check section/page access permissions.
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index b53369d..2714021 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -234,8 +234,10 @@  uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
 
 void HELPER(wfi)(void)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     env->exception_index = EXCP_HLT;
-    env->halted = 1;
+    cpu->halted = 1;
     cpu_loop_exit(env);
 }
 
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 2f71f63..566129c 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -285,9 +285,7 @@  void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUCRISState *env = &CRIS_CPU(cpu)->env;
-
-    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+    return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
 #include "exec-all.h"
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 1ad9ec7..14c3795 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -2895,7 +2895,9 @@  static int dec_rfe_etc(DisasContext *dc)
 	cris_cc_mask(dc, 0);
 
 	if (dc->op2 == 15) {
-		t_gen_mov_env_TN(halted, tcg_const_tl(1));
+                tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
+                               offsetof(CPUState, halted) -
+                               offsetof(CRISCPU, env));
 		tcg_gen_movi_tl(env_pc, dc->pc + 2);
 		t_gen_raise_exception(EXCP_HLT);
 		return 2;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 36e7911..1ee6e6b 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -864,7 +864,7 @@  static inline void cpu_x86_load_seg_cache_sipi(X86CPU *cpu,
                            sipi_vector << 12,
                            env->segs[R_CS].limit,
                            env->segs[R_CS].flags);
-    env->halted = 0;
+    CPU(cpu)->halted = 0;
 }
 
 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
@@ -1039,9 +1039,9 @@  static inline bool cpu_has_work(CPUState *cpu)
 {
     CPUX86State *env = &X86_CPU(cpu)->env;
 
-    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+    return ((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
             (env->eflags & IF_MASK)) ||
-           (env->interrupt_request & (CPU_INTERRUPT_NMI |
+           (cpu->interrupt_request & (CPU_INTERRUPT_NMI |
                                       CPU_INTERRUPT_INIT |
                                       CPU_INTERRUPT_SIPI |
                                       CPU_INTERRUPT_MCE));
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 2d5ca8c..9f5b3ad 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -171,6 +171,7 @@  done:
 void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int eflags, i, nb;
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
@@ -214,7 +215,7 @@  void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
                     (env->a20_mask >> 20) & 1,
                     (env->hflags >> HF_SMM_SHIFT) & 1,
-                    env->halted);
+                    cpu->halted);
     } else
 #endif
     {
@@ -241,7 +242,7 @@  void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
                     (env->a20_mask >> 20) & 1,
                     (env->hflags >> HF_SMM_SHIFT) & 1,
-                    env->halted);
+                    cpu->halted);
     }
 
     for(i = 0; i < 6; i++) {
@@ -1185,14 +1186,15 @@  X86CPU *cpu_x86_init(const char *cpu_model)
 void do_cpu_init(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
-    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
+    CPUState *c = CPU(cpu);
+    int sipi = c->interrupt_request & CPU_INTERRUPT_SIPI;
     uint64_t pat = env->pat;
 
-    cpu_reset(CPU(cpu));
-    env->interrupt_request = sipi;
+    cpu_reset(c);
+    c->interrupt_request = sipi;
     env->pat = pat;
     apic_init_reset(env->apic_state);
-    env->halted = !cpu_is_bsp(cpu);
+    c->halted = !cpu_is_bsp(cpu);
 }
 
 void do_cpu_sipi(X86CPU *cpu)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index f7651bf..088daca 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1354,7 +1354,7 @@  static int kvm_get_mp_state(X86CPU *cpu)
     }
     env->mp_state = mp_state.mp_state;
     if (kvm_irqchip_in_kernel()) {
-        env->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED);
+        CPU(cpu)->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED);
     }
     return 0;
 }
@@ -1634,11 +1634,12 @@  int kvm_arch_get_registers(CPUX86State *env)
 
 void kvm_arch_pre_run(CPUX86State *env, struct kvm_run *run)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int ret;
 
     /* Inject NMI */
-    if (env->interrupt_request & CPU_INTERRUPT_NMI) {
-        env->interrupt_request &= ~CPU_INTERRUPT_NMI;
+    if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
+        cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
         DPRINTF("injected NMI\n");
         ret = kvm_vcpu_ioctl(env, KVM_NMI);
         if (ret < 0) {
@@ -1650,18 +1651,18 @@  void kvm_arch_pre_run(CPUX86State *env, struct kvm_run *run)
     if (!kvm_irqchip_in_kernel()) {
         /* Force the VCPU out of its inner loop to process any INIT requests
          * or pending TPR access reports. */
-        if (env->interrupt_request &
+        if (cpu->interrupt_request &
             (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
             env->exit_request = 1;
         }
 
         /* Try to inject an interrupt if the guest can accept it */
         if (run->ready_for_interrupt_injection &&
-            (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+            (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
             (env->eflags & IF_MASK)) {
             int irq;
 
-            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
             irq = cpu_get_pic_interrupt(env);
             if (irq >= 0) {
                 struct kvm_interrupt intr;
@@ -1681,7 +1682,7 @@  void kvm_arch_pre_run(CPUX86State *env, struct kvm_run *run)
          * interrupt, request an interrupt window exit.  This will
          * cause a return to userspace as soon as the guest is ready to
          * receive interrupts. */
-        if ((env->interrupt_request & CPU_INTERRUPT_HARD)) {
+        if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
             run->request_interrupt_window = 1;
         } else {
             run->request_interrupt_window = 0;
@@ -1706,12 +1707,13 @@  void kvm_arch_post_run(CPUX86State *env, struct kvm_run *run)
 int kvm_arch_process_async_events(CPUX86State *env)
 {
     X86CPU *cpu = x86_env_get_cpu(env);
+    CPUState *c = CPU(cpu);
 
-    if (env->interrupt_request & CPU_INTERRUPT_MCE) {
+    if (c->interrupt_request & CPU_INTERRUPT_MCE) {
         /* We must not raise CPU_INTERRUPT_MCE if it's not supported. */
         assert(env->mcg_cap);
 
-        env->interrupt_request &= ~CPU_INTERRUPT_MCE;
+        c->interrupt_request &= ~CPU_INTERRUPT_MCE;
 
         kvm_cpu_synchronize_state(env);
 
@@ -1724,7 +1726,7 @@  int kvm_arch_process_async_events(CPUX86State *env)
         env->exception_injected = EXCP12_MCHK;
         env->has_error_code = 0;
 
-        env->halted = 0;
+        c->halted = 0;
         if (kvm_irqchip_in_kernel() && env->mp_state == KVM_MP_STATE_HALTED) {
             env->mp_state = KVM_MP_STATE_RUNNABLE;
         }
@@ -1734,37 +1736,38 @@  int kvm_arch_process_async_events(CPUX86State *env)
         return 0;
     }
 
-    if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+    if (((c->interrupt_request & CPU_INTERRUPT_HARD) &&
          (env->eflags & IF_MASK)) ||
-        (env->interrupt_request & CPU_INTERRUPT_NMI)) {
-        env->halted = 0;
+        (c->interrupt_request & CPU_INTERRUPT_NMI)) {
+        c->halted = 0;
     }
-    if (env->interrupt_request & CPU_INTERRUPT_INIT) {
+    if (c->interrupt_request & CPU_INTERRUPT_INIT) {
         kvm_cpu_synchronize_state(env);
         do_cpu_init(cpu);
     }
-    if (env->interrupt_request & CPU_INTERRUPT_SIPI) {
+    if (c->interrupt_request & CPU_INTERRUPT_SIPI) {
         kvm_cpu_synchronize_state(env);
         do_cpu_sipi(cpu);
     }
-    if (env->interrupt_request & CPU_INTERRUPT_TPR) {
-        env->interrupt_request &= ~CPU_INTERRUPT_TPR;
+    if (c->interrupt_request & CPU_INTERRUPT_TPR) {
+        c->interrupt_request &= ~CPU_INTERRUPT_TPR;
         kvm_cpu_synchronize_state(env);
         apic_handle_tpr_access_report(env->apic_state, env->eip,
                                       env->tpr_access_type);
     }
 
-    return env->halted;
+    return c->halted;
 }
 
-static int kvm_handle_halt(X86CPU *cpu)
+static int kvm_handle_halt(X86CPU *c)
 {
-    CPUX86State *env = &cpu->env;
+    CPUState *cpu = CPU(c);
+    CPUX86State *env = &c->env;
 
-    if (!((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+    if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
           (env->eflags & IF_MASK)) &&
-        !(env->interrupt_request & CPU_INTERRUPT_NMI)) {
-        env->halted = 1;
+        !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+        cpu->halted = 1;
         return EXCP_HLT;
     }
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index bc3b94e..6da14b9 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4863,8 +4863,10 @@  void helper_idivq_EAX(target_ulong t0)
 
 static void do_hlt(void)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
-    env->halted = 1;
+    cpu->halted = 1;
     env->exception_index = EXCP_HLT;
     cpu_loop_exit(env);
 }
@@ -5109,6 +5111,7 @@  static inline void svm_load_seg_cache(target_phys_addr_t addr,
 
 void helper_vmrun(int aflag, int next_eip_addend)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     target_ulong addr;
     uint32_t event_inj;
     uint32_t int_ctl;
@@ -5229,7 +5232,7 @@  void helper_vmrun(int aflag, int next_eip_addend)
     env->hflags2 |= HF2_GIF_MASK;
 
     if (int_ctl & V_IRQ_MASK) {
-        env->interrupt_request |= CPU_INTERRUPT_VIRQ;
+        cpu->interrupt_request |= CPU_INTERRUPT_VIRQ;
     }
 
     /* maybe we need to inject an event */
@@ -5487,6 +5490,7 @@  void helper_svm_check_io(uint32_t port, uint32_t param,
 /* Note: currently only 32 bits of exit_code are used */
 void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     uint32_t int_ctl;
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
@@ -5526,8 +5530,9 @@  void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
     int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
     int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
     int_ctl |= env->v_tpr & V_TPR_MASK;
-    if (env->interrupt_request & CPU_INTERRUPT_VIRQ)
+    if (cpu->interrupt_request & CPU_INTERRUPT_VIRQ) {
         int_ctl |= V_IRQ_MASK;
+    }
     stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
 
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags());
@@ -5543,7 +5548,7 @@  void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
     env->hflags &= ~HF_SVMI_MASK;
     env->intercept = 0;
     env->intercept_exceptions = 0;
-    env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+    cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
     env->tsc_offset = 0;
 
     env->gdt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base));
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 7243b4f..559890b 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -255,9 +255,7 @@  static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPULM32State *env = &LM32_CPU(cpu)->env;
-
-    return env->interrupt_request & CPU_INTERRUPT_HARD;
+    return cpu->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
 #include "exec-all.h"
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 51edc1a..7f49c2b 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -26,7 +26,9 @@  void helper_raise_exception(uint32_t index)
 
 void helper_hlt(void)
 {
-    env->halted = 1;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    cpu->halted = 1;
     env->exception_index = EXCP_HLT;
     cpu_loop_exit(env);
 }
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 780e2c9..d334352 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -259,9 +259,7 @@  static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUM68KState *env = &M68K_CPU(cpu)->env;
-
-    return env->interrupt_request & CPU_INTERRUPT_HARD;
+    return cpu->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
 #include "exec-all.h"
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 1971a57..4413b3a 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -96,6 +96,7 @@  static void do_rte(void)
 
 static void do_interrupt_all(int is_hw)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     uint32_t sp;
     uint32_t fmt;
     uint32_t retaddr;
@@ -120,7 +121,7 @@  static void do_interrupt_all(int is_hw)
                 do_m68k_semihosting(env, env->dregs[0]);
                 return;
             }
-            env->halted = 1;
+            cpu->halted = 1;
             env->exception_index = EXCP_HLT;
             cpu_loop_exit(env);
             return;
diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def
index 49400c4..4235b02 100644
--- a/target-m68k/qregs.def
+++ b/target-m68k/qregs.def
@@ -8,6 +8,5 @@  DEFO32(CC_X, cc_x)
 DEFO32(DIV1, div1)
 DEFO32(DIV2, div2)
 DEFO32(EXCEPTION, exception_index)
-DEFO32(HALTED, halted)
 DEFO32(MACSR, macsr)
 DEFO32(MAC_MASK, mac_mask)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 9fc1e31..fef0c79 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -42,6 +42,8 @@ 
 #undef DEFO64
 #undef DEFF64
 
+static TCGv QREG_HALTED;
+
 static TCGv_ptr cpu_env;
 
 static char cpu_reg_names[3*8*3 + 5*4];
@@ -76,6 +78,10 @@  void m68k_tcg_init(void)
 #undef DEFO64
 #undef DEFF64
 
+    QREG_HALTED = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, halted)
+                                                  - offsetof(M68kCPU, env),
+                                         "HALTED");
+
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
     p = cpu_reg_names;
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 6131287..e17a0db 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -371,9 +371,7 @@  void cpu_unassigned_access(CPUMBState *env1, target_phys_addr_t addr,
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUMBState *env = &MICROBLAZE_CPU(cpu)->env;
-
-    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+    return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
 #include "exec-all.h"
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 9ce53da..9ac5733 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -714,7 +714,7 @@  static inline bool cpu_has_work(CPUState *cpu)
     /* It is implementation dependent if non-enabled interrupts
        wake-up the CPU, however most of the implementations only
        check for interrupts that can be taken. */
-    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+    if ((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
         cpu_mips_hw_interrupts_pending(env)) {
         has_work = true;
     }
@@ -723,7 +723,7 @@  static inline bool cpu_has_work(CPUState *cpu)
     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
         /* The QEMU model will issue an _WAKE request whenever the CPUs
            should be woken up.  */
-        if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
+        if (cpu->interrupt_request & CPU_INTERRUPT_WAKE) {
             has_work = true;
         }
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index d26c9fb..fd4125e 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -746,10 +746,11 @@  void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
 static bool mips_vpe_is_wfi(MIPSCPU *c)
 {
     CPUMIPSState *env = &c->env;
+    CPUState *cpu = CPU(c);
 
     /* If the VPE is halted but otherwise active, it means it's waiting for
        an interrupt.  */
-    return env->halted && mips_vpe_active(env);
+    return cpu->halted && mips_vpe_active(env);
 }
 
 static inline void mips_vpe_wake(CPUMIPSState *c)
@@ -766,7 +767,7 @@  static inline void mips_vpe_sleep(MIPSCPU *cpu)
 
     /* The VPE was shut off, really go to bed.
        Reset any old _WAKE requests.  */
-    c->halted = 1;
+    CPU(cpu)->halted = 1;
     cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE);
 }
 
@@ -2286,9 +2287,11 @@  void helper_pmon (int function)
     }
 }
 
-void helper_wait (void)
+void helper_wait(void)
 {
-    env->halted = 1;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    cpu->halted = 1;
     cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE);
     helper_raise_exception(EXCP_HLT);
 }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4e15ee3..793f72b 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12716,6 +12716,10 @@  MIPSCPU *cpu_mips_init(const char *cpu_model)
 
 void cpu_state_reset(CPUMIPSState *env)
 {
+#ifndef CONFIG_USER_ONLY
+    CPUState *cpu = ENV_GET_CPU(env);
+#endif
+
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
         log_cpu_state(env, 0);
@@ -12817,7 +12821,7 @@  void cpu_state_reset(CPUMIPSState *env)
             env->tcs[i].CP0_TCHalt = 1;
         }
         env->active_tc.CP0_TCHalt = 1;
-        env->halted = 1;
+        cpu->halted = 1;
 
         if (!env->cpu_index) {
             /* VPE0 starts up enabled.  */
@@ -12825,7 +12829,7 @@  void cpu_state_reset(CPUMIPSState *env)
             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
 
             /* TC0 starts up unhalted.  */
-            env->halted = 0;
+            cpu->halted = 0;
             env->active_tc.CP0_TCHalt = 0;
             env->tcs[0].CP0_TCHalt = 0;
             /* With thread 0 active.  */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f1927d5..935c347 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2188,7 +2188,7 @@  static inline bool cpu_has_work(CPUState *cpu)
 {
     CPUPPCState *env = &POWERPC_CPU(cpu)->env;
 
-    return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+    return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD);
 }
 
 #include "exec-all.h"
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 7747674..8059654 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2573,8 +2573,8 @@  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 fprintf(stderr, "Machine check while not allowed. "
                         "Entering checkstop state\n");
             }
-            env->halted = 1;
-            env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+            CPU(cpu)->halted = 1;
+            CPU(cpu)->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
         if (0) {
             /* XXX: find a suitable condition to enable the hypervisor mode */
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 3c98850..02a7f79 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -67,6 +67,9 @@  static inline void hreg_compute_hflags(CPUPPCState *env)
 static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
                                  int alter_hv)
 {
+#if !defined(CONFIG_USER_ONLY)
+    CPUState *cpu = ENV_GET_CPU(env);
+#endif
     int excp;
 
     excp = 0;
@@ -82,7 +85,7 @@  static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
         /* Flush all tlb when changing translation mode */
         tlb_flush(env, 1);
         excp = POWERPC_EXCP_NONE;
-        env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+        cpu->interrupt_request |= CPU_INTERRUPT_EXITTB;
     }
     if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
                  ((value ^ env->msr) & (1 << MSR_TGPR)))) {
@@ -99,7 +102,7 @@  static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
 #if !defined (CONFIG_USER_ONLY)
     if (unlikely(msr_pow == 1)) {
         if ((*env->check_pow)(env)) {
-            env->halted = 1;
+            cpu->halted = 1;
             excp = EXCP_HALTED;
         }
     }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 148c095..126a018 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -471,6 +471,7 @@  int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level)
 
 void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int r;
     unsigned irq;
 
@@ -478,7 +479,7 @@  void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
      * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
     if (!cap_interrupt_level &&
         run->ready_for_interrupt_injection &&
-        (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+        (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
         (env->irq_input_state & (1<<PPC_INPUT_INT)))
     {
         /* For now KVM disregards the 'irq' argument. However, in the
@@ -508,13 +509,17 @@  void kvm_arch_post_run(CPUPPCState *env, struct kvm_run *run)
 
 int kvm_arch_process_async_events(CPUPPCState *env)
 {
-    return env->halted;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    return cpu->halted;
 }
 
 static int kvmppc_handle_halt(CPUPPCState *env)
 {
-    if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
-        env->halted = 1;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    if (!(cpu->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
+        cpu->halted = 1;
         env->exception_index = EXCP_HLT;
     }
 
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 4ef2332..0f8d3f0 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -1594,9 +1594,11 @@  void helper_fcmpo (uint64_t arg1, uint64_t arg2, uint32_t crfD)
 #if !defined (CONFIG_USER_ONLY)
 void helper_store_msr (target_ulong val)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     val = hreg_store_msr(env, val, 0);
     if (val != 0) {
-        env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+        cpu->interrupt_request |= CPU_INTERRUPT_EXITTB;
         helper_raise_exception(val);
     }
 }
@@ -1604,6 +1606,8 @@  void helper_store_msr (target_ulong val)
 static inline void do_rfi(target_ulong nip, target_ulong msr,
                           target_ulong msrm, int keep_msrh)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
 #if defined(TARGET_PPC64)
     if (msr & (1ULL << MSR_SF)) {
         nip = (uint64_t)nip;
@@ -1627,7 +1631,7 @@  static inline void do_rfi(target_ulong nip, target_ulong msr,
     /* No need to raise an exception here,
      * as rfi is always the last insn of a TB
      */
-    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+    cpu->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
 
 void helper_rfi (void)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index cf59765..57b63ac 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3213,7 +3213,8 @@  static void gen_sync(DisasContext *ctx)
 static void gen_wait(DisasContext *ctx)
 {
     TCGv_i32 t0 = tcg_temp_new_i32();
-    tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted));
+    tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted)
+                              - offsetof(PowerPCCPU, env));
     tcg_temp_free_i32(t0);
     /* Stop translation, as the CPU is supposed to sleep from now */
     gen_exception_err(ctx, EXCP_HLT, 1);
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index be13348..ecda9e6 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -989,7 +989,7 @@  static inline bool cpu_has_work(CPUState *cpu)
 {
     CPUS390XState *env = &S390_CPU(cpu)->env;
 
-    return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+    return (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
         (env->psw.mask & PSW_MASK_EXT);
 }
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index d0a1180..7bf9554 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -438,6 +438,8 @@  target_phys_addr_t cpu_get_phys_page_debug(CPUS390XState *env, target_ulong vadd
 
 void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     if (mask & PSW_MASK_WAIT) {
         if (!(mask & (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK))) {
             if (s390_del_running_cpu(env) == 0) {
@@ -446,7 +448,7 @@  void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
 #endif
             }
         }
-        env->halted = 1;
+        cpu->halted = 1;
         env->exception_index = EXCP_HLT;
     }
 
@@ -571,8 +573,10 @@  static void do_ext_interrupt(CPUS390XState *env)
     load_psw(env, mask, addr);
 }
 
-void do_interrupt (CPUS390XState *env)
+void do_interrupt(CPUS390XState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     qemu_log("%s: %d at pc=%" PRIx64 "\n", __FUNCTION__, env->exception_index,
              env->psw.addr);
 
@@ -610,7 +614,7 @@  void do_interrupt (CPUS390XState *env)
     env->exception_index = -1;
 
     if (!env->pending_int) {
-        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+        cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
     }
 }
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index e09709d..722511e 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -172,7 +172,9 @@  void kvm_arch_post_run(CPUS390XState *env, struct kvm_run *run)
 
 int kvm_arch_process_async_events(CPUS390XState *env)
 {
-    return env->halted;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    return cpu->halted;
 }
 
 void kvm_s390_interrupt_internal(CPUS390XState *env, int type, uint32_t parm,
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index fd6fb86..ba66479 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -373,9 +373,7 @@  static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUSH4State *env = &SUPERH_CPU(cpu)->env;
-
-    return env->interrupt_request & CPU_INTERRUPT_HARD;
+    return cpu->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
 #include "exec-all.h"
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 5c57380..fe3063d 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -78,9 +78,10 @@  int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
 #define MMU_DADDR_ERROR_READ     (-12)
 #define MMU_DADDR_ERROR_WRITE    (-13)
 
-void do_interrupt(CPUSH4State * env)
+void do_interrupt(CPUSH4State *env)
 {
-    int do_irq = env->interrupt_request & CPU_INTERRUPT_HARD;
+    CPUState *cpu = ENV_GET_CPU(env);
+    int do_irq = cpu->interrupt_request & CPU_INTERRUPT_HARD;
     int do_exp, irq_vector = env->exception_index;
 
     /* prioritize exceptions over interrupts */
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 4054791..4226671 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -117,7 +117,9 @@  void helper_debug(void)
 
 void helper_sleep(uint32_t next_pc)
 {
-    env->halted = 1;
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    cpu->halted = 1;
     env->in_sleep = 1;
     env->exception_index = EXCP_HLT;
     env->pc = next_pc;
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index e3b3b44..31cd9f6 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -767,7 +767,7 @@  static inline bool cpu_has_work(CPUState *cpu)
 {
     CPUSPARCState *env1 = &SPARC_CPU(cpu)->env;
 
-    return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
+    return (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
            cpu_interrupts_enabled(env1);
 }
 
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 2843a97..48431cd 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -185,9 +185,7 @@  void switch_mode(CPUUniCore32State *, int);
 
 static inline bool cpu_has_work(CPUState *cpu)
 {
-    CPUUniCore32State *env = &UNICORE32_CPU(cpu)->env;
-
-    return env->interrupt_request &
+    return cpu->interrupt_request &
         (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }
 
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 364dc19..8eb02a5 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -390,6 +390,8 @@  void HELPER(dump_state)(void)
 
 void HELPER(waiti)(uint32_t pc, uint32_t intlevel)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
+
     env->pc = pc;
     env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
         (intlevel << PS_INTLEVEL_SHIFT);
@@ -400,7 +402,7 @@  void HELPER(waiti)(uint32_t pc, uint32_t intlevel)
     }
 
     env->halt_clock = qemu_get_clock_ns(vm_clock);
-    env->halted = 1;
+    cpu->halted = 1;
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
         xtensa_rearm_ccompare_timer(env);
     }
diff --git a/xen-all.c b/xen-all.c
index bdf9c0f..33ebb72 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -590,9 +590,9 @@  static MemoryListener xen_memory_listener = {
 
 static void xen_reset_vcpu(void *opaque)
 {
-    CPUArchState *env = opaque;
+    CPUState *cpu = opaque;
 
-    env->halted = 1;
+    cpu->halted = 1;
 }
 
 void xen_vcpu_init(void)
@@ -600,8 +600,10 @@  void xen_vcpu_init(void)
     CPUArchState *first_cpu;
 
     if ((first_cpu = qemu_get_cpu(0))) {
-        qemu_register_reset(xen_reset_vcpu, first_cpu);
-        xen_reset_vcpu(first_cpu);
+        CPUState *cpu = ENV_GET_CPU(first_cpu);
+
+        qemu_register_reset(xen_reset_vcpu, cpu);
+        xen_reset_vcpu(cpu);
     }
 }