Patchwork [RFC,qom-cpu,11/41] cpu: Move exception_index field from CPU_COMMON to CPUState

login
register
mail settings
Submitter Andreas Färber
Date Sept. 4, 2013, 9:04 a.m.
Message ID <1378285521-3230-12-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/272534/
State New
Headers show

Comments

Andreas Färber - Sept. 4, 2013, 9:04 a.m.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c                    | 50 +++++++++++++++++++++---------------------
 exec.c                        |  2 +-
 hw/ppc/e500.c                 |  3 +--
 hw/ppc/ppce500_spin.c         |  2 +-
 hw/ppc/spapr_hcall.c          |  2 +-
 hw/s390x/s390-virtio.c        |  8 +++----
 include/exec/cpu-defs.h       |  3 ---
 include/qom/cpu.h             |  1 +
 linux-user/signal.c           |  7 +++---
 target-alpha/helper.c         | 18 ++++++++++-----
 target-alpha/mem_helper.c     |  4 +++-
 target-arm/helper.c           | 25 ++++++++++-----------
 target-arm/op_helper.c        | 16 +++++++++-----
 target-cris/helper.c          | 18 +++++++--------
 target-cris/op_helper.c       |  6 +++--
 target-i386/excp_helper.c     |  4 +++-
 target-i386/helper.c          |  6 ++---
 target-i386/mem_helper.c      |  5 +++--
 target-i386/misc_helper.c     |  6 +++--
 target-i386/seg_helper.c      |  8 ++++---
 target-i386/svm_helper.c      | 13 ++++++-----
 target-lm32/helper.c          | 12 +++++-----
 target-lm32/op_helper.c       |  6 +++--
 target-m68k/helper.c          |  2 +-
 target-m68k/op_helper.c       | 22 +++++++++----------
 target-m68k/qregs.def         |  1 -
 target-m68k/translate.c       |  5 +++++
 target-microblaze/helper.c    | 16 ++++++--------
 target-microblaze/op_helper.c |  4 +++-
 target-mips/helper.c          | 31 ++++++++++++++------------
 target-mips/op_helper.c       |  9 +++++---
 target-mips/translate.c       |  4 +---
 target-moxie/helper.c         | 21 ++++++++++--------
 target-openrisc/cpu.c         |  2 +-
 target-openrisc/exception.c   |  4 +++-
 target-openrisc/interrupt.c   | 27 ++++++++++++-----------
 target-openrisc/mmu.c         |  3 ++-
 target-ppc/excp_helper.c      | 19 +++++++++-------
 target-ppc/fpu_helper.c       | 26 +++++++++++++++-------
 target-ppc/mmu-hash32.c       | 24 ++++++++++----------
 target-ppc/mmu-hash64.c       | 15 +++++++------
 target-ppc/mmu_helper.c       | 43 ++++++++++++++++++------------------
 target-ppc/translate_init.c   |  2 +-
 target-ppc/user_only_helper.c |  2 +-
 target-s390x/helper.c         | 39 ++++++++++++++++-----------------
 target-s390x/mem_helper.c     |  9 ++++----
 target-s390x/misc_helper.c    | 15 +++++++++----
 target-sh4/helper.c           | 51 +++++++++++++++++++++----------------------
 target-sh4/op_helper.c        |  4 +++-
 target-sparc/helper.c         | 10 ++++++---
 target-sparc/int32_helper.c   |  8 +++----
 target-sparc/int64_helper.c   |  6 ++---
 target-sparc/ldst_helper.c    |  3 ++-
 target-sparc/mmu_helper.c     | 22 +++++++++----------
 target-unicore32/op_helper.c  |  4 +++-
 target-unicore32/softmmu.c    |  8 +++----
 target-xtensa/helper.c        | 20 +++++++++--------
 target-xtensa/op_helper.c     |  4 +++-
 user-exec.c                   |  6 +++--
 59 files changed, 393 insertions(+), 323 deletions(-)
Jia Liu - Sept. 4, 2013, 12:47 p.m.
On Wed, Sep 4, 2013 at 5:04 PM, Andreas Färber <afaerber@suse.de> wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpu-exec.c                    | 50 +++++++++++++++++++++---------------------
>  exec.c                        |  2 +-
>  hw/ppc/e500.c                 |  3 +--
>  hw/ppc/ppce500_spin.c         |  2 +-
>  hw/ppc/spapr_hcall.c          |  2 +-
>  hw/s390x/s390-virtio.c        |  8 +++----
>  include/exec/cpu-defs.h       |  3 ---
>  include/qom/cpu.h             |  1 +
>  linux-user/signal.c           |  7 +++---
>  target-alpha/helper.c         | 18 ++++++++++-----
>  target-alpha/mem_helper.c     |  4 +++-
>  target-arm/helper.c           | 25 ++++++++++-----------
>  target-arm/op_helper.c        | 16 +++++++++-----
>  target-cris/helper.c          | 18 +++++++--------
>  target-cris/op_helper.c       |  6 +++--
>  target-i386/excp_helper.c     |  4 +++-
>  target-i386/helper.c          |  6 ++---
>  target-i386/mem_helper.c      |  5 +++--
>  target-i386/misc_helper.c     |  6 +++--
>  target-i386/seg_helper.c      |  8 ++++---
>  target-i386/svm_helper.c      | 13 ++++++-----
>  target-lm32/helper.c          | 12 +++++-----
>  target-lm32/op_helper.c       |  6 +++--
>  target-m68k/helper.c          |  2 +-
>  target-m68k/op_helper.c       | 22 +++++++++----------
>  target-m68k/qregs.def         |  1 -
>  target-m68k/translate.c       |  5 +++++
>  target-microblaze/helper.c    | 16 ++++++--------
>  target-microblaze/op_helper.c |  4 +++-
>  target-mips/helper.c          | 31 ++++++++++++++------------
>  target-mips/op_helper.c       |  9 +++++---
>  target-mips/translate.c       |  4 +---
>  target-moxie/helper.c         | 21 ++++++++++--------
>  target-openrisc/cpu.c         |  2 +-
>  target-openrisc/exception.c   |  4 +++-
>  target-openrisc/interrupt.c   | 27 ++++++++++++-----------
>  target-openrisc/mmu.c         |  3 ++-
>  target-ppc/excp_helper.c      | 19 +++++++++-------
>  target-ppc/fpu_helper.c       | 26 +++++++++++++++-------
>  target-ppc/mmu-hash32.c       | 24 ++++++++++----------
>  target-ppc/mmu-hash64.c       | 15 +++++++------
>  target-ppc/mmu_helper.c       | 43 ++++++++++++++++++------------------
>  target-ppc/translate_init.c   |  2 +-
>  target-ppc/user_only_helper.c |  2 +-
>  target-s390x/helper.c         | 39 ++++++++++++++++-----------------
>  target-s390x/mem_helper.c     |  9 ++++----
>  target-s390x/misc_helper.c    | 15 +++++++++----
>  target-sh4/helper.c           | 51 +++++++++++++++++++++----------------------
>  target-sh4/op_helper.c        |  4 +++-
>  target-sparc/helper.c         | 10 ++++++---
>  target-sparc/int32_helper.c   |  8 +++----
>  target-sparc/int64_helper.c   |  6 ++---
>  target-sparc/ldst_helper.c    |  3 ++-
>  target-sparc/mmu_helper.c     | 22 +++++++++----------
>  target-unicore32/op_helper.c  |  4 +++-
>  target-unicore32/softmmu.c    |  8 +++----
>  target-xtensa/helper.c        | 20 +++++++++--------
>  target-xtensa/op_helper.c     |  4 +++-
>  user-exec.c                   |  6 +++--
>  59 files changed, 393 insertions(+), 323 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 39e4f8b..0081eaf 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -41,7 +41,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
>
>      /* XXX: restore cpu registers saved in host registers */
>
> -    env->exception_index = -1;
> +    cpu->exception_index = -1;
>      siglongjmp(cpu->jmp_env, 1);
>  }
>  #endif
> @@ -262,16 +262,16 @@ int cpu_exec(CPUArchState *env)
>  #else
>  #error unsupported target CPU
>  #endif
> -    env->exception_index = -1;
> +    cpu->exception_index = -1;
>
>      /* prepare setjmp context for exception handling */
>      for(;;) {
>          if (sigsetjmp(cpu->jmp_env, 0) == 0) {
>              /* if an exception is pending, we execute it here */
> -            if (env->exception_index >= 0) {
> -                if (env->exception_index >= EXCP_INTERRUPT) {
> +            if (cpu->exception_index >= 0) {
> +                if (cpu->exception_index >= EXCP_INTERRUPT) {
>                      /* exit request from the cpu execution loop */
> -                    ret = env->exception_index;
> +                    ret = cpu->exception_index;
>                      if (ret == EXCP_DEBUG) {
>                          cpu_handle_debug_exception(env);
>                      }
> @@ -284,11 +284,11 @@ int cpu_exec(CPUArchState *env)
>  #if defined(TARGET_I386)
>                      cc->do_interrupt(cpu);
>  #endif
> -                    ret = env->exception_index;
> +                    ret = cpu->exception_index;
>                      break;
>  #else
>                      cc->do_interrupt(cpu);
> -                    env->exception_index = -1;
> +                    cpu->exception_index = -1;
>  #endif
>                  }
>              }
> @@ -303,7 +303,7 @@ int cpu_exec(CPUArchState *env)
>                      }
>                      if (interrupt_request & CPU_INTERRUPT_DEBUG) {
>                          cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
> -                        env->exception_index = EXCP_DEBUG;
> +                        cpu->exception_index = EXCP_DEBUG;
>                          cpu_loop_exit(env);
>                      }
>  #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
> @@ -312,7 +312,7 @@ int cpu_exec(CPUArchState *env)
>                      if (interrupt_request & CPU_INTERRUPT_HALT) {
>                          cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
>                          cpu->halted = 1;
> -                        env->exception_index = EXCP_HLT;
> +                        cpu->exception_index = EXCP_HLT;
>                          cpu_loop_exit(env);
>                      }
>  #endif
> @@ -327,7 +327,7 @@ int cpu_exec(CPUArchState *env)
>                              cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
>                                                            0);
>                              do_cpu_init(x86_env_get_cpu(env));
> -                            env->exception_index = EXCP_HALTED;
> +                            cpu->exception_index = EXCP_HALTED;
>                              cpu_loop_exit(env);
>                      } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
>                              do_cpu_sipi(x86_env_get_cpu(env));
> @@ -396,7 +396,7 @@ int cpu_exec(CPUArchState *env)
>  #elif defined(TARGET_LM32)
>                      if ((interrupt_request & CPU_INTERRUPT_HARD)
>                          && (env->ie & IE_IE)) {
> -                        env->exception_index = EXCP_IRQ;
> +                        cpu->exception_index = EXCP_IRQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -405,7 +405,7 @@ int cpu_exec(CPUArchState *env)
>                          && (env->sregs[SR_MSR] & MSR_IE)
>                          && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
>                          && !(env->iflags & (D_FLAG | IMM_FLAG))) {
> -                        env->exception_index = EXCP_IRQ;
> +                        cpu->exception_index = EXCP_IRQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -413,7 +413,7 @@ int cpu_exec(CPUArchState *env)
>                      if ((interrupt_request & CPU_INTERRUPT_HARD) &&
>                          cpu_mips_hw_interrupts_pending(env)) {
>                          /* Raise it */
> -                        env->exception_index = EXCP_EXT_INTERRUPT;
> +                        cpu->exception_index = EXCP_EXT_INTERRUPT;
>                          env->error_code = 0;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
> @@ -430,7 +430,7 @@ int cpu_exec(CPUArchState *env)
>                              idx = EXCP_TICK;
>                          }
>                          if (idx >= 0) {
> -                            env->exception_index = idx;
> +                            cpu->exception_index = idx;
>                              cc->do_interrupt(cpu);
>                              next_tb = 0;
>                          }
> @@ -445,7 +445,7 @@ int cpu_exec(CPUArchState *env)
>                              if (((type == TT_EXTINT) &&
>                                    cpu_pil_allowed(env, pil)) ||
>                                    type != TT_EXTINT) {
> -                                env->exception_index = env->interrupt_index;
> +                                cpu->exception_index = env->interrupt_index;
>                                  cc->do_interrupt(cpu);
>                                  next_tb = 0;
>                              }
> @@ -454,7 +454,7 @@ int cpu_exec(CPUArchState *env)
>  #elif defined(TARGET_ARM)
>                      if (interrupt_request & CPU_INTERRUPT_FIQ
>                          && !(env->uncached_cpsr & CPSR_F)) {
> -                        env->exception_index = EXCP_FIQ;
> +                        cpu->exception_index = EXCP_FIQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -470,14 +470,14 @@ int cpu_exec(CPUArchState *env)
>                      if (interrupt_request & CPU_INTERRUPT_HARD
>                          && ((IS_M(env) && env->regs[15] < 0xfffffff0)
>                              || !(env->uncached_cpsr & CPSR_I))) {
> -                        env->exception_index = EXCP_IRQ;
> +                        cpu->exception_index = EXCP_IRQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
>  #elif defined(TARGET_UNICORE32)
>                      if (interrupt_request & CPU_INTERRUPT_HARD
>                          && !(env->uncached_asr & ASR_I)) {
> -                        env->exception_index = UC32_EXCP_INTR;
> +                        cpu->exception_index = UC32_EXCP_INTR;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -512,7 +512,7 @@ int cpu_exec(CPUArchState *env)
>                              }
>                          }
>                          if (idx >= 0) {
> -                            env->exception_index = idx;
> +                            cpu->exception_index = idx;
>                              env->error_code = 0;
>                              cc->do_interrupt(cpu);
>                              next_tb = 0;
> @@ -522,7 +522,7 @@ int cpu_exec(CPUArchState *env)
>                      if (interrupt_request & CPU_INTERRUPT_HARD
>                          && (env->pregs[PR_CCS] & I_FLAG)
>                          && !env->locked_irq) {
> -                        env->exception_index = EXCP_IRQ;
> +                        cpu->exception_index = EXCP_IRQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -534,7 +534,7 @@ int cpu_exec(CPUArchState *env)
>                              m_flag_archval = M_FLAG_V32;
>                          }
>                          if ((env->pregs[PR_CCS] & m_flag_archval)) {
> -                            env->exception_index = EXCP_NMI;
> +                            cpu->exception_index = EXCP_NMI;
>                              cc->do_interrupt(cpu);
>                              next_tb = 0;
>                          }
> @@ -548,7 +548,7 @@ int cpu_exec(CPUArchState *env)
>                             hardware doesn't rely on this, so we
>                             provide/save the vector when the interrupt is
>                             first signalled.  */
> -                        env->exception_index = env->pending_vector;
> +                        cpu->exception_index = env->pending_vector;
>                          do_interrupt_m68k_hardirq(env);
>                          next_tb = 0;
>                      }
> @@ -560,7 +560,7 @@ int cpu_exec(CPUArchState *env)
>                      }
>  #elif defined(TARGET_XTENSA)
>                      if (interrupt_request & CPU_INTERRUPT_HARD) {
> -                        env->exception_index = EXC_IRQ;
> +                        cpu->exception_index = EXC_IRQ;
>                          cc->do_interrupt(cpu);
>                          next_tb = 0;
>                      }
> @@ -576,7 +576,7 @@ int cpu_exec(CPUArchState *env)
>                  }
>                  if (unlikely(cpu->exit_request)) {
>                      cpu->exit_request = 0;
> -                    env->exception_index = EXCP_INTERRUPT;
> +                    cpu->exception_index = EXCP_INTERRUPT;
>                      cpu_loop_exit(env);
>                  }
>  #if defined(DEBUG_DISAS)
> @@ -662,7 +662,7 @@ int cpu_exec(CPUArchState *env)
>                                  /* Execute remaining instructions.  */
>                                  cpu_exec_nocache(env, insns_left, tb);
>                              }
> -                            env->exception_index = EXCP_INTERRUPT;
> +                            cpu->exception_index = EXCP_INTERRUPT;
>                              next_tb = 0;
>                              cpu_loop_exit(env);
>                          }
> diff --git a/exec.c b/exec.c
> index 00c44ea..508f1e2 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1502,7 +1502,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
>                  env->watchpoint_hit = wp;
>                  tb_check_watchpoint(env);
>                  if (wp->flags & BP_STOP_BEFORE_ACCESS) {
> -                    env->exception_index = EXCP_DEBUG;
> +                    cpu->exception_index = EXCP_DEBUG;
>                      cpu_loop_exit(env);
>                  } else {
>                      cc->get_tb_cpu_state(cpu, &pc, &cs_base, &cpu_flags);
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index cfdd84b..2d1d478 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -468,14 +468,13 @@ static void ppce500_cpu_reset_sec(void *opaque)
>  {
>      PowerPCCPU *cpu = opaque;
>      CPUState *cs = CPU(cpu);
> -    CPUPPCState *env = &cpu->env;
>
>      cpu_reset(cs);
>
>      /* Secondary CPU starts in halted state for now. Needs to change when
>         implementing non-kernel boot. */
>      cs->halted = 1;
> -    env->exception_index = EXCP_HLT;
> +    cs->exception_index = EXCP_HLT;
>  }
>
>  static void ppce500_cpu_reset(void *opaque)
> diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
> index 78b23fa..f9fdc8c 100644
> --- a/hw/ppc/ppce500_spin.c
> +++ b/hw/ppc/ppce500_spin.c
> @@ -117,7 +117,7 @@ static void spin_kick(void *data)
>      mmubooke_create_initial_mapping(env, 0, map_start, map_size);
>
>      cpu->halted = 0;
> -    env->exception_index = -1;
> +    cpu->exception_index = -1;
>      cpu->stopped = false;
>      qemu_cpu_kick(cpu);
>  }
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index f10ba8a..d4aa4ea 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -511,7 +511,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>      hreg_compute_hflags(env);
>      if (!cpu_has_work(cs)) {
>          cs->halted = 1;
> -        env->exception_index = EXCP_HLT;
> +        cs->exception_index = EXCP_HLT;
>          cs->exit_request = 1;
>      }
>      return H_SUCCESS;
> diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
> index 7adf92a..393f3c8 100644
> --- a/hw/s390x/s390-virtio.c
> +++ b/hw/s390x/s390-virtio.c
> @@ -134,25 +134,23 @@ static unsigned s390_running_cpus;
>  void s390_add_running_cpu(S390CPU *cpu)
>  {
>      CPUState *cs = CPU(cpu);
> -    CPUS390XState *env = &cpu->env;
>
>      if (cs->halted) {
>          s390_running_cpus++;
>          cs->halted = 0;
> -        env->exception_index = -1;
> +        cs->exception_index = -1;
>      }
>  }
>
>  unsigned s390_del_running_cpu(S390CPU *cpu)
>  {
>      CPUState *cs = CPU(cpu);
> -    CPUS390XState *env = &cpu->env;
>
>      if (cs->halted == 0) {
>          assert(s390_running_cpus >= 1);
>          s390_running_cpus--;
>          cs->halted = 1;
> -        env->exception_index = EXCP_HLT;
> +        cs->exception_index = EXCP_HLT;
>      }
>      return s390_running_cpus;
>  }
> @@ -195,7 +193,7 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
>
>          ipi_states[i] = cpu;
>          cs->halted = 1;
> -        cpu->env.exception_index = EXCP_HLT;
> +        cs->exception_index = EXCP_HLT;
>          cpu->env.storage_keys = storage_keys;
>      }
>  }
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index d000a5e..6801968 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -138,9 +138,6 @@ typedef struct CPUWatchpoint {
>      QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
>      CPUWatchpoint *watchpoint_hit;                                      \
>                                                                          \
> -    /* Core interrupt code */                                           \
> -    int exception_index;                                                \
> -                                                                        \
>      /* user data */                                                     \
>      void *opaque;                                                       \
>                                                                          \
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 288ffa9..8191a80 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -249,6 +249,7 @@ struct CPUState {
>          icount_decr_u16 u16;
>      } icount_decr;
>      uint32_t can_do_io;
> +    int32_t exception_index; /* used by m68k TCG */
>  };
>
>  QTAILQ_HEAD(CPUTailQ, CPUState);
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 23d65da..6e51519 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -773,8 +773,9 @@ static int
>  setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
>                  CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
>  {
> -       int err = 0;
> -        uint16_t magic;
> +    CPUState *cs = CPU(x86_env_get_cpu(env));
> +    int err = 0;
> +    uint16_t magic;
>
>         /* already locked in setup_frame() */
>         err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
> @@ -789,7 +790,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
>         err |= __put_user(env->regs[R_EDX], &sc->edx);
>         err |= __put_user(env->regs[R_ECX], &sc->ecx);
>         err |= __put_user(env->regs[R_EAX], &sc->eax);
> -       err |= __put_user(env->exception_index, &sc->trapno);
> +    err |= __put_user(cs->exception_index, &sc->trapno);
>         err |= __put_user(env->error_code, &sc->err);
>         err |= __put_user(env->eip, &sc->eip);
>         err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
> diff --git a/target-alpha/helper.c b/target-alpha/helper.c
> index ef2dc25..6f103ec 100644
> --- a/target-alpha/helper.c
> +++ b/target-alpha/helper.c
> @@ -173,7 +173,7 @@ int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);
>
> -    cpu->env.exception_index = EXCP_MMFAULT;
> +    cs->exception_index = EXCP_MMFAULT;
>      cpu->env.trap_arg0 = address;
>      return 1;
>  }
> @@ -337,7 +337,7 @@ int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw,
>
>      fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot);
>      if (unlikely(fail >= 0)) {
> -        env->exception_index = EXCP_MMFAULT;
> +        cs->exception_index = EXCP_MMFAULT;
>          env->trap_arg0 = addr;
>          env->trap_arg1 = fail;
>          env->trap_arg2 = (rw == 2 ? -1 : rw);
> @@ -354,7 +354,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);
>      CPUAlphaState *env = &cpu->env;
> -    int i = env->exception_index;
> +    int i = cs->exception_index;
>
>      if (qemu_loglevel_mask(CPU_LOG_INT)) {
>          static int count;
> @@ -405,7 +405,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
>                   ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
>      }
>
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>
>  #if !defined(CONFIG_USER_ONLY)
>      switch (i) {
> @@ -507,7 +507,10 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>     We expect that ENV->PC has already been updated.  */
>  void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
>  {
> -    env->exception_index = excp;
> +    AlphaCPU *cpu = alpha_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
> +
> +    cs->exception_index = excp;
>      env->error_code = error;
>      cpu_loop_exit(env);
>  }
> @@ -516,7 +519,10 @@ void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
>  void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, uintptr_t retaddr,
>                                  int excp, int error)
>  {
> -    env->exception_index = excp;
> +    AlphaCPU *cpu = alpha_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
> +
> +    cs->exception_index = excp;
>      env->error_code = error;
>      if (retaddr) {
>          cpu_restore_state(env, retaddr);
> diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
> index d140688..22fcbe1 100644
> --- a/target-alpha/mem_helper.c
> +++ b/target-alpha/mem_helper.c
> @@ -91,6 +91,8 @@ uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
>  static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
>                                  int is_write, int is_user, uintptr_t retaddr)
>  {
> +    AlphaCPU *cpu = alpha_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
>      uint64_t pc;
>      uint32_t insn;
>
> @@ -104,7 +106,7 @@ static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
>      env->trap_arg0 = addr;
>      env->trap_arg1 = insn >> 26;                /* opcode */
>      env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
> -    env->exception_index = EXCP_UNALIGN;
> +    cs->exception_index = EXCP_UNALIGN;
>      env->error_code = 0;
>      cpu_loop_exit(env);
>  }
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 9d0d8b4..508a7fc 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2072,10 +2072,7 @@ uint32_t HELPER(rbit)(uint32_t x)
>
>  void arm_cpu_do_interrupt(CPUState *cs)
>  {
> -    ARMCPU *cpu = ARM_CPU(cs);
> -    CPUARMState *env = &cpu->env;
> -
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
>
>  int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> @@ -2085,10 +2082,10 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>      CPUARMState *env = &cpu->env;
>
>      if (rw == 2) {
> -        env->exception_index = EXCP_PREFETCH_ABORT;
> +        cs->exception_index = EXCP_PREFETCH_ABORT;
>          env->cp15.c6_insn = address;
>      } else {
> -        env->exception_index = EXCP_DATA_ABORT;
> +        cs->exception_index = EXCP_DATA_ABORT;
>          env->cp15.c6_data = address;
>      }
>      return 1;
> @@ -2270,7 +2267,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
>      uint32_t lr;
>      uint32_t addr;
>
> -    arm_log_exception(env->exception_index);
> +    arm_log_exception(cs->exception_index);
>
>      lr = 0xfffffff1;
>      if (env->v7m.current_sp)
> @@ -2282,7 +2279,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
>         handle it.  */
>      /* TODO: Need to escalate if the current priority is higher than the
>         one we're raising.  */
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_UDEF:
>          armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
>          return;
> @@ -2314,7 +2311,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
>          do_v7m_exception_exit(env);
>          return;
>      default:
> -        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
> +        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
>          return; /* Never happens.  Keep compiler happy.  */
>      }
>
> @@ -2355,10 +2352,10 @@ void arm_cpu_do_interrupt(CPUState *cs)
>
>      assert(!IS_M(env));
>
> -    arm_log_exception(env->exception_index);
> +    arm_log_exception(cs->exception_index);
>
>      /* TODO: Vectored interrupt controller.  */
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_UDEF:
>          new_mode = ARM_CPU_MODE_UND;
>          addr = 0x04;
> @@ -2439,7 +2436,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
>          offset = 4;
>          break;
>      default:
> -        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
> +        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
>          return; /* Never happens.  Keep compiler happy.  */
>      }
>      /* High vectors.  */
> @@ -3053,13 +3050,13 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>      if (access_type == 2) {
>          env->cp15.c5_insn = ret;
>          env->cp15.c6_insn = address;
> -        env->exception_index = EXCP_PREFETCH_ABORT;
> +        cs->exception_index = EXCP_PREFETCH_ABORT;
>      } else {
>          env->cp15.c5_data = ret;
>          if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
>              env->cp15.c5_data |= (1 << 11);
>          env->cp15.c6_data = address;
> -        env->exception_index = EXCP_DATA_ABORT;
> +        cs->exception_index = EXCP_DATA_ABORT;
>      }
>      return 1;
>  }
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 13d34fb..2c2b3b7 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -24,7 +24,10 @@
>
>  static void raise_exception(CPUARMState *env, int tt)
>  {
> -    env->exception_index = tt;
> +    ARMCPU *cpu = arm_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
> +
> +    cs->exception_index = tt;
>      cpu_loop_exit(env);
>  }
>
> @@ -75,15 +78,16 @@ void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
>      ARMCPU *cpu = arm_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
>      int ret;
>
> -    ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
> +    ret = arm_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
>              cpu_restore_state(env, retaddr);
>          }
> -        raise_exception(env, env->exception_index);
> +        raise_exception(env, cs->exception_index);
>      }
>  }
>  #endif
> @@ -221,14 +225,16 @@ void HELPER(wfi)(CPUARMState *env)
>  {
>      CPUState *cs = CPU(arm_env_get_cpu(env));
>
> -    env->exception_index = EXCP_HLT;
> +    cs->exception_index = EXCP_HLT;
>      cs->halted = 1;
>      cpu_loop_exit(env);
>  }
>
>  void HELPER(exception)(CPUARMState *env, uint32_t excp)
>  {
> -    env->exception_index = excp;
> +    CPUState *cs = CPU(arm_env_get_cpu(env));
> +
> +    cs->exception_index = excp;
>      cpu_loop_exit(env);
>  }
>
> diff --git a/target-cris/helper.c b/target-cris/helper.c
> index 72dc839..3c4501c 100644
> --- a/target-cris/helper.c
> +++ b/target-cris/helper.c
> @@ -41,7 +41,7 @@ void cris_cpu_do_interrupt(CPUState *cs)
>      CRISCPU *cpu = CRIS_CPU(cs);
>      CPUCRISState *env = &cpu->env;
>
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>      env->pregs[PR_ERP] = env->pc;
>  }
>
> @@ -55,7 +55,7 @@ int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>  {
>      CRISCPU *cpu = CRIS_CPU(cs);
>
> -    cpu->env.exception_index = 0xaa;
> +    cs->exception_index = 0xaa;
>      cpu->env.pregs[PR_EDA] = address;
>      cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
> @@ -88,7 +88,7 @@ int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>      miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
>                                rw, mmu_idx, 0);
>      if (miss) {
> -        if (env->exception_index == EXCP_BUSFAULT) {
> +        if (cs->exception_index == EXCP_BUSFAULT) {
>              cpu_abort(env,
>                        "CRIS: Illegal recursive bus fault."
>                        "addr=%" VADDR_PRIx " rw=%d\n",
> @@ -96,7 +96,7 @@ int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>          }
>
>          env->pregs[PR_EDA] = address;
> -        env->exception_index = EXCP_BUSFAULT;
> +        cs->exception_index = EXCP_BUSFAULT;
>          env->fault_vector = res.bf_vec;
>          r = 1;
>      } else {
> @@ -125,11 +125,11 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
>      int ex_vec = -1;
>
>      D_LOG("exception index=%d interrupt_req=%d\n",
> -          env->exception_index,
> +          cs->exception_index,
>            cs->interrupt_request);
>
>      assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_BREAK:
>          /* These exceptions are genereated by the core itself.
>             ERP should point to the insn following the brk.  */
> @@ -182,10 +182,10 @@ void cris_cpu_do_interrupt(CPUState *cs)
>      int ex_vec = -1;
>
>      D_LOG("exception index=%d interrupt_req=%d\n",
> -          env->exception_index,
> +          cs->exception_index,
>            cs->interrupt_request);
>
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_BREAK:
>          /* These exceptions are genereated by the core itself.
>             ERP should point to the insn following the brk.  */
> @@ -248,7 +248,7 @@ void cris_cpu_do_interrupt(CPUState *cs)
>
>      /* Clear the excption_index to avoid spurios hw_aborts for recursive
>         bus faults.  */
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>
>      D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
>            __func__, env->pc, ex_vec,
> diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
> index 4a6215d..9b20b94 100644
> --- a/target-cris/op_helper.c
> +++ b/target-cris/op_helper.c
> @@ -79,8 +79,10 @@ void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
>
>  void helper_raise_exception(CPUCRISState *env, uint32_t index)
>  {
> -       env->exception_index = index;
> -        cpu_loop_exit(env);
> +    CPUState *cs = CPU(cris_env_get_cpu(env));
> +
> +    cs->exception_index = index;
> +    cpu_loop_exit(env);
>  }
>
>  void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
> diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c
> index 5319aef..ec76eba 100644
> --- a/target-i386/excp_helper.c
> +++ b/target-i386/excp_helper.c
> @@ -94,6 +94,8 @@ static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
>                                             int is_int, int error_code,
>                                             int next_eip_addend)
>  {
> +    CPUState *cs = CPU(x86_env_get_cpu(env));
> +
>      if (!is_int) {
>          cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
>                                        error_code);
> @@ -102,7 +104,7 @@ static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
>          cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0);
>      }
>
> -    env->exception_index = intno;
> +    cs->exception_index = intno;
>      env->error_code = error_code;
>      env->exception_is_int = is_int;
>      env->exception_next_eip = env->eip + next_eip_addend;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 8c2ad94..864d9f8 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -496,7 +496,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
>      env->cr[2] = addr;
>      env->error_code = (is_write << PG_ERROR_W_BIT);
>      env->error_code |= PG_ERROR_U_MASK;
> -    env->exception_index = EXCP0E_PAGE;
> +    cs->exception_index = EXCP0E_PAGE;
>      return 1;
>  }
>
> @@ -555,7 +555,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
>              sext = (int64_t)addr >> 47;
>              if (sext != 0 && sext != -1) {
>                  env->error_code = 0;
> -                env->exception_index = EXCP0D_GPF;
> +                cs->exception_index = EXCP0D_GPF;
>                  return 1;
>              }
>
> @@ -885,7 +885,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
>          env->cr[2] = addr;
>      }
>      env->error_code = error_code;
> -    env->exception_index = EXCP0E_PAGE;
> +    cs->exception_index = EXCP0E_PAGE;
>      return 1;
>  }
>
> diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
> index 5b25ccd..c0d3b45 100644
> --- a/target-i386/mem_helper.c
> +++ b/target-i386/mem_helper.c
> @@ -136,15 +136,16 @@ void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
>      X86CPU *cpu = x86_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
>      int ret;
>
> -    ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
> +    ret = x86_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
>      if (ret) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
>              cpu_restore_state(env, retaddr);
>          }
> -        raise_exception_err(env, env->exception_index, env->error_code);
> +        raise_exception_err(env, cs->exception_index, env->error_code);
>      }
>  }
>  #endif
> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
> index 93933fd..a058c43 100644
> --- a/target-i386/misc_helper.c
> +++ b/target-i386/misc_helper.c
> @@ -573,7 +573,7 @@ static void do_hlt(X86CPU *cpu)
>
>      env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
>      cs->halted = 1;
> -    env->exception_index = EXCP_HLT;
> +    cs->exception_index = EXCP_HLT;
>      cpu_loop_exit(env);
>  }
>
> @@ -620,6 +620,8 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
>
>  void helper_debug(CPUX86State *env)
>  {
> -    env->exception_index = EXCP_DEBUG;
> +    CPUState *cs = CPU(x86_env_get_cpu(env));
> +
> +    cs->exception_index = EXCP_DEBUG;
>      cpu_loop_exit(env);
>  }
> diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
> index e789102..b689e94 100644
> --- a/target-i386/seg_helper.c
> +++ b/target-i386/seg_helper.c
> @@ -935,7 +935,9 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
>  #if defined(CONFIG_USER_ONLY)
>  void helper_syscall(CPUX86State *env, int next_eip_addend)
>  {
> -    env->exception_index = EXCP_SYSCALL;
> +    CPUState *cs = CPU(x86_env_get_cpu(env));
> +
> +    cs->exception_index = EXCP_SYSCALL;
>      env->exception_next_eip = env->eip + next_eip_addend;
>      cpu_loop_exit(env);
>  }
> @@ -1244,7 +1246,7 @@ void x86_cpu_do_interrupt(CPUState *cs)
>      /* if user mode only, we simulate a fake exception
>         which will be handled outside the cpu execution
>         loop */
> -    do_interrupt_user(env, env->exception_index,
> +    do_interrupt_user(env, cs->exception_index,
>                        env->exception_is_int,
>                        env->error_code,
>                        env->exception_next_eip);
> @@ -1254,7 +1256,7 @@ void x86_cpu_do_interrupt(CPUState *cs)
>      /* simulate a real cpu exception. On i386, it can
>         trigger new exceptions, but we do not handle
>         double or triple faults yet. */
> -    do_interrupt_all(cpu, env->exception_index,
> +    do_interrupt_all(cpu, cs->exception_index,
>                       env->exception_is_int,
>                       env->error_code,
>                       env->exception_next_eip, 0);
> diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
> index 4a7de42..3c12cb8 100644
> --- a/target-i386/svm_helper.c
> +++ b/target-i386/svm_helper.c
> @@ -122,6 +122,7 @@ static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
>
>  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>  {
> +    CPUState *cs = CPU(x86_env_get_cpu(env));
>      target_ulong addr;
>      uint32_t event_inj;
>      uint32_t int_ctl;
> @@ -290,7 +291,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>          /* FIXME: need to implement valid_err */
>          switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
>          case SVM_EVTINJ_TYPE_INTR:
> -            env->exception_index = vector;
> +            cs->exception_index = vector;
>              env->error_code = event_inj_err;
>              env->exception_is_int = 0;
>              env->exception_next_eip = -1;
> @@ -299,7 +300,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>              do_interrupt_x86_hardirq(env, vector, 1);
>              break;
>          case SVM_EVTINJ_TYPE_NMI:
> -            env->exception_index = EXCP02_NMI;
> +            cs->exception_index = EXCP02_NMI;
>              env->error_code = event_inj_err;
>              env->exception_is_int = 0;
>              env->exception_next_eip = env->eip;
> @@ -307,7 +308,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>              cpu_loop_exit(env);
>              break;
>          case SVM_EVTINJ_TYPE_EXEPT:
> -            env->exception_index = vector;
> +            cs->exception_index = vector;
>              env->error_code = event_inj_err;
>              env->exception_is_int = 0;
>              env->exception_next_eip = -1;
> @@ -315,7 +316,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>              cpu_loop_exit(env);
>              break;
>          case SVM_EVTINJ_TYPE_SOFT:
> -            env->exception_index = vector;
> +            cs->exception_index = vector;
>              env->error_code = event_inj_err;
>              env->exception_is_int = 1;
>              env->exception_next_eip = env->eip;
> @@ -323,7 +324,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>              cpu_loop_exit(env);
>              break;
>          }
> -        qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index,
> +        qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", cs->exception_index,
>                        env->error_code);
>      }
>  }
> @@ -705,7 +706,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
>         #GP fault is delivered inside the host. */
>
>      /* remove any pending exception */
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>      env->error_code = 0;
>      env->old_exception = -1;
>
> diff --git a/target-lm32/helper.c b/target-lm32/helper.c
> index 55a3de6..b2093a8 100644
> --- a/target-lm32/helper.c
> +++ b/target-lm32/helper.c
> @@ -57,9 +57,9 @@ void lm32_cpu_do_interrupt(CPUState *cs)
>      CPULM32State *env = &cpu->env;
>
>      qemu_log_mask(CPU_LOG_INT,
> -            "exception at pc=%x type=%x\n", env->pc, env->exception_index);
> +            "exception at pc=%x type=%x\n", env->pc, cs->exception_index);
>
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_INSN_BUS_ERROR:
>      case EXCP_DATA_BUS_ERROR:
>      case EXCP_DIVIDE_BY_ZERO:
> @@ -70,9 +70,9 @@ void lm32_cpu_do_interrupt(CPUState *cs)
>          env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
>          env->ie &= ~IE_IE;
>          if (env->dc & DC_RE) {
> -            env->pc = env->deba + (env->exception_index * 32);
> +            env->pc = env->deba + (cs->exception_index * 32);
>          } else {
> -            env->pc = env->eba + (env->exception_index * 32);
> +            env->pc = env->eba + (cs->exception_index * 32);
>          }
>          log_cpu_state_mask(CPU_LOG_INT, cs, 0);
>          break;
> @@ -82,12 +82,12 @@ void lm32_cpu_do_interrupt(CPUState *cs)
>          env->regs[R_BA] = env->pc;
>          env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
>          env->ie &= ~IE_IE;
> -        env->pc = env->deba + (env->exception_index * 32);
> +        env->pc = env->deba + (cs->exception_index * 32);
>          log_cpu_state_mask(CPU_LOG_INT, cs, 0);
>          break;
>      default:
>          cpu_abort(env, "unhandled exception type=%d\n",
> -                  env->exception_index);
> +                  cs->exception_index);
>          break;
>      }
>  }
> diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
> index 215215e..c7ad910 100644
> --- a/target-lm32/op_helper.c
> +++ b/target-lm32/op_helper.c
> @@ -21,7 +21,9 @@
>
>  void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
>  {
> -    env->exception_index = index;
> +    CPUState *cs = CPU(lm32_env_get_cpu(env));
> +
> +    cs->exception_index = index;
>      cpu_loop_exit(env);
>  }
>
> @@ -30,7 +32,7 @@ void HELPER(hlt)(CPULM32State *env)
>      CPUState *cs = CPU(lm32_env_get_cpu(env));
>
>      cs->halted = 1;
> -    env->exception_index = EXCP_HLT;
> +    cs->exception_index = EXCP_HLT;
>      cpu_loop_exit(env);
>  }
>
> diff --git a/target-m68k/helper.c b/target-m68k/helper.c
> index 25a0570..003a298 100644
> --- a/target-m68k/helper.c
> +++ b/target-m68k/helper.c
> @@ -283,7 +283,7 @@ int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>  {
>      M68kCPU *cpu = M68K_CPU(cs);
>
> -    cpu->env.exception_index = EXCP_ACCESS;
> +    cs->exception_index = EXCP_ACCESS;
>      cpu->env.mmu.ar = address;
>      return 1;
>  }
> diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
> index bc10f38..466ad0c 100644
> --- a/target-m68k/op_helper.c
> +++ b/target-m68k/op_helper.c
> @@ -23,10 +23,7 @@
>
>  void m68k_cpu_do_interrupt(CPUState *cs)
>  {
> -    M68kCPU *cpu = M68K_CPU(cs);
> -    CPUM68KState *env = &cpu->env;
> -
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
>
>  void do_interrupt_m68k_hardirq(CPUM68KState *env)
> @@ -88,7 +85,7 @@ static void do_rte(CPUM68KState *env)
>
>  static void do_interrupt_all(CPUM68KState *env, int is_hw)
>  {
> -    CPUState *cs;
> +    CPUState *cs = CPU(m68k_env_get_cpu(env));
>      uint32_t sp;
>      uint32_t fmt;
>      uint32_t retaddr;
> @@ -98,7 +95,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
>      retaddr = env->pc;
>
>      if (!is_hw) {
> -        switch (env->exception_index) {
> +        switch (cs->exception_index) {
>          case EXCP_RTE:
>              /* Return from an exception.  */
>              do_rte(env);
> @@ -113,20 +110,19 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
>                  do_m68k_semihosting(env, env->dregs[0]);
>                  return;
>              }
> -            cs = CPU(m68k_env_get_cpu(env));
>              cs->halted = 1;
> -            env->exception_index = EXCP_HLT;
> +            cs->exception_index = EXCP_HLT;
>              cpu_loop_exit(env);
>              return;
>          }
> -        if (env->exception_index >= EXCP_TRAP0
> -            && env->exception_index <= EXCP_TRAP15) {
> +        if (cs->exception_index >= EXCP_TRAP0
> +            && cs->exception_index <= EXCP_TRAP15) {
>              /* Move the PC after the trap instruction.  */
>              retaddr += 2;
>          }
>      }
>
> -    vector = env->exception_index << 2;
> +    vector = cs->exception_index << 2;
>
>      sp = env->aregs[7];
>
> @@ -169,7 +165,9 @@ void do_interrupt_m68k_hardirq(CPUM68KState *env)
>
>  static void raise_exception(CPUM68KState *env, int tt)
>  {
> -    env->exception_index = tt;
> +    CPUState *cs = CPU(m68k_env_get_cpu(env));
> +
> +    cs->exception_index = tt;
>      cpu_loop_exit(env);
>  }
>
> diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def
> index 4235b02..204663e 100644
> --- a/target-m68k/qregs.def
> +++ b/target-m68k/qregs.def
> @@ -7,6 +7,5 @@ DEFO32(CC_SRC, cc_src)
>  DEFO32(CC_X, cc_x)
>  DEFO32(DIV1, div1)
>  DEFO32(DIV2, div2)
> -DEFO32(EXCEPTION, exception_index)
>  DEFO32(MACSR, macsr)
>  DEFO32(MAC_MASK, mac_mask)
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index 0be0a96..f3cdee0 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -43,6 +43,7 @@
>  #undef DEFF64
>
>  static TCGv_i32 cpu_halted;
> +static TCGv_i32 cpu_exception_index;
>
>  static TCGv_ptr cpu_env;
>
> @@ -81,6 +82,10 @@ void m68k_tcg_init(void)
>      cpu_halted = tcg_global_mem_new_i32(TCG_AREG0,
>                                          -offsetof(M68kCPU, env) +
>                                          offsetof(CPUState, halted), "HALTED");
> +    cpu_exception_index = tcg_global_mem_new_i32(TCG_AREG0,
> +                                                 -offsetof(M68kCPU, env) +
> +                                                 offsetof(CPUState, exception_index),
> +                                                 "EXCEPTION");
>
>      cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
>
> diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
> index d03f369..4825415 100644
> --- a/target-microblaze/helper.c
> +++ b/target-microblaze/helper.c
> @@ -31,7 +31,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>      MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
>      CPUMBState *env = &cpu->env;
>
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>      env->res_addr = RES_ADDR_NONE;
>      env->regs[14] = env->sregs[SR_PC];
>  }
> @@ -39,9 +39,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>  int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                              int mmu_idx)
>  {
> -    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
> -
> -    cpu->env.exception_index = 0xaa;
> +    cs->exception_index = 0xaa;
>      cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
>  }
> @@ -99,12 +97,12 @@ int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                      break;
>              }
>
> -            if (env->exception_index == EXCP_MMU) {
> +            if (cs->exception_index == EXCP_MMU) {
>                  cpu_abort(env, "recursive faults\n");
>              }
>
>              /* TLB miss.  */
> -            env->exception_index = EXCP_MMU;
> +            cs->exception_index = EXCP_MMU;
>          }
>      } else {
>          /* MMU disabled or not available.  */
> @@ -127,7 +125,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>      assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
>  /*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
>      env->res_addr = RES_ADDR_NONE;
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>          case EXCP_HW_EXCP:
>              if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
>                  qemu_log("Exception raised on system without exceptions!\n");
> @@ -253,7 +251,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
>              env->sregs[SR_MSR] |= t;
>              env->sregs[SR_MSR] |= MSR_BIP;
> -            if (env->exception_index == EXCP_HW_BREAK) {
> +            if (cs->exception_index == EXCP_HW_BREAK) {
>                  env->regs[16] = env->sregs[SR_PC];
>                  env->sregs[SR_MSR] |= MSR_BIP;
>                  env->sregs[SR_PC] = cpu->base_vectors + 0x18;
> @@ -262,7 +260,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              break;
>          default:
>              cpu_abort(env, "unhandled exception type=%d\n",
> -                      env->exception_index);
> +                      cs->exception_index);
>              break;
>      }
>  }
> diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
> index b70b2ea..318185a 100644
> --- a/target-microblaze/op_helper.c
> +++ b/target-microblaze/op_helper.c
> @@ -95,7 +95,9 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
>
>  void helper_raise_exception(CPUMBState *env, uint32_t index)
>  {
> -    env->exception_index = index;
> +    CPUState *cs = CPU(mb_env_get_cpu(env));
> +
> +    cs->exception_index = index;
>      cpu_loop_exit(env);
>  }
>
> diff --git a/target-mips/helper.c b/target-mips/helper.c
> index d8e9166..698c3d1 100644
> --- a/target-mips/helper.c
> +++ b/target-mips/helper.c
> @@ -204,6 +204,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
>  static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
>                                  int rw, int tlb_error)
>  {
> +    CPUState *cs = CPU(mips_env_get_cpu(env));
>      int exception = 0, error_code = 0;
>
>      switch (tlb_error) {
> @@ -249,7 +250,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
>                          ((address & 0xC00000000000ULL) >> (55 - env->SEGBITS)) |
>                          ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
>  #endif
> -    env->exception_index = exception;
> +    cs->exception_index = exception;
>      env->error_code = error_code;
>  }
>
> @@ -404,27 +405,29 @@ static void set_hflags_for_handler (CPUMIPSState *env)
>
>  void mips_cpu_do_interrupt(CPUState *cs)
>  {
> +#if !defined(CONFIG_USER_ONLY)
>      MIPSCPU *cpu = MIPS_CPU(cs);
>      CPUMIPSState *env = &cpu->env;
> -#if !defined(CONFIG_USER_ONLY)
>      target_ulong offset;
>      int cause = -1;
>      const char *name;
>
> -    if (qemu_log_enabled() && env->exception_index != EXCP_EXT_INTERRUPT) {
> -        if (env->exception_index < 0 || env->exception_index > EXCP_LAST)
> +    if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) {
> +        if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) {
>              name = "unknown";
> -        else
> -            name = excp_names[env->exception_index];
> +        } else {
> +            name = excp_names[cs->exception_index];
> +        }
>
>          qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n",
>                   __func__, env->active_tc.PC, env->CP0_EPC, name);
>      }
> -    if (env->exception_index == EXCP_EXT_INTERRUPT &&
> -        (env->hflags & MIPS_HFLAG_DM))
> -        env->exception_index = EXCP_DINT;
> +    if (cs->exception_index == EXCP_EXT_INTERRUPT &&
> +        (env->hflags & MIPS_HFLAG_DM)) {
> +        cs->exception_index = EXCP_DINT;
> +    }
>      offset = 0x180;
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_DSS:
>          env->CP0_Debug |= 1 << CP0DB_DSS;
>          /* Debug single step cannot be raised inside a delay slot and
> @@ -632,11 +635,11 @@ void mips_cpu_do_interrupt(CPUState *cs)
>          env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
>          break;
>      default:
> -        qemu_log("Invalid MIPS exception %d. Exiting\n", env->exception_index);
> -        printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
> +        qemu_log("Invalid MIPS exception %d. Exiting\n", cs->exception_index);
> +        printf("Invalid MIPS exception %d. Exiting\n", cs->exception_index);
>          exit(1);
>      }
> -    if (qemu_log_enabled() && env->exception_index != EXCP_EXT_INTERRUPT) {
> +    if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) {
>          qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n"
>                  "    S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
>                  __func__, env->active_tc.PC, env->CP0_EPC, cause,
> @@ -644,7 +647,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
>                  env->CP0_DEPC);
>      }
>  #endif
> -    env->exception_index = EXCP_NONE;
> +    cs->exception_index = EXCP_NONE;
>  }
>
>  #if !defined(CONFIG_USER_ONLY)
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 34ac4c6..eeb98a6 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -38,10 +38,12 @@ static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
>                                                          int error_code,
>                                                          uintptr_t pc)
>  {
> +    CPUState *cs = CPU(mips_env_get_cpu(env));
> +
>      if (exception < EXCP_SC) {
>          qemu_log("%s: %d %d\n", __func__, exception, error_code);
>      }
> -    env->exception_index = exception;
> +    cs->exception_index = exception;
>      env->error_code = error_code;
>
>      if (pc) {
> @@ -2135,11 +2137,12 @@ void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
>      MIPSCPU *cpu = mips_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
>      int ret;
>
> -    ret = mips_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
> +    ret = mips_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
>      if (ret) {
> -        do_raise_exception_err(env, env->exception_index,
> +        do_raise_exception_err(env, cs->exception_index,
>                                 env->error_code, retaddr);
>      }
>  }
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index ad43d59..716d50c 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -15922,10 +15922,8 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
>
>  void cpu_state_reset(CPUMIPSState *env)
>  {
> -#ifndef CONFIG_USER_ONLY
>      MIPSCPU *cpu = mips_env_get_cpu(env);
>      CPUState *cs = CPU(cpu);
> -#endif
>
>      /* Reset registers to their default values */
>      env->CP0_PRid = env->cpu_model->CP0_PRid;
> @@ -16049,7 +16047,7 @@ void cpu_state_reset(CPUMIPSState *env)
>      }
>  #endif
>      compute_hflags(env);
> -    env->exception_index = EXCP_NONE;
> +    cs->exception_index = EXCP_NONE;
>  }
>
>  void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
> diff --git a/target-moxie/helper.c b/target-moxie/helper.c
> index 8160475..3b14f37 100644
> --- a/target-moxie/helper.c
> +++ b/target-moxie/helper.c
> @@ -63,7 +63,9 @@ void tlb_fill(CPUMoxieState *env, target_ulong addr, int is_write, int mmu_idx,
>
>  void helper_raise_exception(CPUMoxieState *env, int ex)
>  {
> -    env->exception_index = ex;
> +    CPUState *cs = CPU(moxie_env_get_cpu(env));
> +
> +    cs->exception_index = ex;
>      /* Stash the exception type.  */
>      env->sregs[2] = ex;
>      /* Stash the address where the exception occurred.  */
> @@ -98,7 +100,9 @@ uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
>
>  void helper_debug(CPUMoxieState *env)
>  {
> -    env->exception_index = EXCP_DEBUG;
> +    CPUState *cs = CPU(moxie_env_get_cpu(env));
> +
> +    cs->exception_index = EXCP_DEBUG;
>      cpu_loop_exit(env);
>  }
>
> @@ -106,7 +110,9 @@ void helper_debug(CPUMoxieState *env)
>
>  void moxie_cpu_do_interrupt(CPUState *cs)
>  {
> -    env->exception_index = -1;
> +    CPUState *cs = CPU(moxie_env_get_cpu(env));
> +
> +    cs->exception_index = -1;
>  }
>
>  int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
> @@ -114,7 +120,7 @@ int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>  {
>      MoxieCPU *cpu = MOXIE_CPU(cs);
>
> -    cpu->env.exception_index = 0xaa;
> +    cs->exception_index = 0xaa;
>      cpu->env.debug1 = address;
>      cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
> @@ -138,7 +144,7 @@ int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>      if (miss) {
>          /* handle the miss.  */
>          phy = 0;
> -        env->exception_index = MOXIE_EX_MMU_MISS;
> +        cs->exception_index = MOXIE_EX_MMU_MISS;
>      } else {
>          phy = res.phy;
>          r = 0;
> @@ -150,10 +156,7 @@ int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>
>  void moxie_cpu_do_interrupt(CPUState *cs)
>  {
> -    MoxieCPU *cpu = MOXIE_CPU(cs);
> -    CPUMoxieState *env = &cpu->env;
> -
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case MOXIE_EX_BREAK:
>          break;
>      default:
> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
> index ee1591d..b233969 100644
> --- a/target-openrisc/cpu.c
> +++ b/target-openrisc/cpu.c
> @@ -69,7 +69,7 @@ static void openrisc_cpu_reset(CPUState *s)
>
>      cpu->env.pc = 0x100;
>      cpu->env.sr = SR_FO | SR_SM;
> -    cpu->env.exception_index = -1;
> +    s->exception_index = -1;
>
>      cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
>      cpu->env.cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S;
> diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
> index 58e53c6..b96f3f8 100644
> --- a/target-openrisc/exception.c
> +++ b/target-openrisc/exception.c
> @@ -22,6 +22,8 @@
>
>  void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
>  {
> -    cpu->env.exception_index = excp;
> +    CPUState *cs = CPU(cpu);
> +
> +    cs->exception_index = excp;
>      cpu_loop_exit(&cpu->env);
>  }
> diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
> index 16ef4b3..64f2ca6 100644
> --- a/target-openrisc/interrupt.c
> +++ b/target-openrisc/interrupt.c
> @@ -27,25 +27,26 @@
>
>  void openrisc_cpu_do_interrupt(CPUState *cs)
>  {
> +#ifndef CONFIG_USER_ONLY
>      OpenRISCCPU *cpu = OPENRISC_CPU(cs);
>      CPUOpenRISCState *env = &cpu->env;
> -#ifndef CONFIG_USER_ONLY
> +
>      if (env->flags & D_FLAG) { /* Delay Slot insn */
>          env->flags &= ~D_FLAG;
>          env->sr |= SR_DSX;
> -        if (env->exception_index == EXCP_TICK    ||
> -            env->exception_index == EXCP_INT     ||
> -            env->exception_index == EXCP_SYSCALL ||
> -            env->exception_index == EXCP_FPE) {
> +        if (cs->exception_index == EXCP_TICK    ||
> +            cs->exception_index == EXCP_INT     ||
> +            cs->exception_index == EXCP_SYSCALL ||
> +            cs->exception_index == EXCP_FPE) {
>              env->epcr = env->jmp_pc;
>          } else {
>              env->epcr = env->pc - 4;
>          }
>      } else {
> -        if (env->exception_index == EXCP_TICK    ||
> -            env->exception_index == EXCP_INT     ||
> -            env->exception_index == EXCP_SYSCALL ||
> -            env->exception_index == EXCP_FPE) {
> +        if (cs->exception_index == EXCP_TICK    ||
> +            cs->exception_index == EXCP_INT     ||
> +            cs->exception_index == EXCP_SYSCALL ||
> +            cs->exception_index == EXCP_FPE) {
>              env->epcr = env->npc;
>          } else {
>              env->epcr = env->pc;
> @@ -65,12 +66,12 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
>      env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
>      env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
>
> -    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
> -        env->pc = (env->exception_index << 8);
> +    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
> +        env->pc = (cs->exception_index << 8);
>      } else {
> -        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
> +        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
>      }
>  #endif
>
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
> diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
> index 0f13c5d..b1830da 100644
> --- a/target-openrisc/mmu.c
> +++ b/target-openrisc/mmu.c
> @@ -146,6 +146,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
>                                               target_ulong address,
>                                               int rw, int tlb_error)
>  {
> +    CPUState *cs = CPU(cpu);
>      int exception = 0;
>
>      switch (tlb_error) {
> @@ -176,7 +177,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
>  #endif
>      }
>
> -    cpu->env.exception_index = exception;
> +    cs->exception_index = exception;
>      cpu->env.eear = address;
>  }
>
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index c959460..0ec2615 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -43,13 +43,15 @@ void ppc_cpu_do_interrupt(CPUState *cs)
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
>      CPUPPCState *env = &cpu->env;
>
> -    env->exception_index = POWERPC_EXCP_NONE;
> +    cs->exception_index = POWERPC_EXCP_NONE;
>      env->error_code = 0;
>  }
>
>  void ppc_hw_interrupt(CPUPPCState *env)
>  {
> -    env->exception_index = POWERPC_EXCP_NONE;
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
> +
> +    cs->exception_index = POWERPC_EXCP_NONE;
>      env->error_code = 0;
>  }
>  #else /* defined(CONFIG_USER_ONLY) */
> @@ -68,8 +70,8 @@ static inline void dump_syscall(CPUPPCState *env)
>   */
>  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUPPCState *env = &cpu->env;
> -    CPUState *cs;
>      target_ulong msr, new_msr, vector;
>      int srr0, srr1, asrr0, asrr1;
>      int lpes0, lpes1, lev;
> @@ -135,7 +137,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                  fprintf(stderr, "Machine check while not allowed. "
>                          "Entering checkstop state\n");
>              }
> -            cs = CPU(cpu);
>              cs->halted = 1;
>              cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
>          }
> @@ -202,7 +203,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          case POWERPC_EXCP_FP:
>              if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
>                  LOG_EXCP("Ignore floating point exception\n");
> -                env->exception_index = POWERPC_EXCP_NONE;
> +                cs->exception_index = POWERPC_EXCP_NONE;
>                  env->error_code = 0;
>                  return;
>              }
> @@ -655,7 +656,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      hreg_compute_hflags(env);
>      env->nip = vector;
>      /* Reset exception state */
> -    env->exception_index = POWERPC_EXCP_NONE;
> +    cs->exception_index = POWERPC_EXCP_NONE;
>      env->error_code = 0;
>
>      if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> @@ -672,7 +673,7 @@ void ppc_cpu_do_interrupt(CPUState *cs)
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
>      CPUPPCState *env = &cpu->env;
>
> -    powerpc_excp(cpu, env->excp_model, env->exception_index);
> +    powerpc_excp(cpu, env->excp_model, cs->exception_index);
>  }
>
>  void ppc_hw_interrupt(CPUPPCState *env)
> @@ -808,10 +809,12 @@ static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
>  void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
>                                  uint32_t error_code)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
> +
>  #if 0
>      printf("Raise exception %3x code : %d\n", exception, error_code);
>  #endif
> -    env->exception_index = exception;
> +    cs->exception_index = exception;
>      env->error_code = error_code;
>      cpu_loop_exit(env);
>  }
> diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
> index 4f60218..314e66f 100644
> --- a/target-ppc/fpu_helper.c
> +++ b/target-ppc/fpu_helper.c
> @@ -108,6 +108,7 @@ uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf)
>  /* Floating-point invalid operations exception */
>  static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      uint64_t ret = 0;
>      int ve;
>
> @@ -142,7 +143,7 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
>          env->fpscr |= 0x11 << FPSCR_FPCC;
>          /* We must update the target FPR before raising the exception */
>          if (ve != 0) {
> -            env->exception_index = POWERPC_EXCP_PROGRAM;
> +            cs->exception_index = POWERPC_EXCP_PROGRAM;
>              env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
>              /* Update the floating-point enabled exception summary */
>              env->fpscr |= 1 << FPSCR_FEX;
> @@ -207,6 +208,8 @@ static inline void float_zero_divide_excp(CPUPPCState *env)
>
>  static inline void float_overflow_excp(CPUPPCState *env)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
> +
>      env->fpscr |= 1 << FPSCR_OX;
>      /* Update the floating-point exception summary */
>      env->fpscr |= 1 << FPSCR_FX;
> @@ -215,7 +218,7 @@ static inline void float_overflow_excp(CPUPPCState *env)
>          /* Update the floating-point enabled exception summary */
>          env->fpscr |= 1 << FPSCR_FEX;
>          /* We must update the target FPR before raising the exception */
> -        env->exception_index = POWERPC_EXCP_PROGRAM;
> +        cs->exception_index = POWERPC_EXCP_PROGRAM;
>          env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
>      } else {
>          env->fpscr |= 1 << FPSCR_XX;
> @@ -225,6 +228,8 @@ static inline void float_overflow_excp(CPUPPCState *env)
>
>  static inline void float_underflow_excp(CPUPPCState *env)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
> +
>      env->fpscr |= 1 << FPSCR_UX;
>      /* Update the floating-point exception summary */
>      env->fpscr |= 1 << FPSCR_FX;
> @@ -233,13 +238,15 @@ static inline void float_underflow_excp(CPUPPCState *env)
>          /* Update the floating-point enabled exception summary */
>          env->fpscr |= 1 << FPSCR_FEX;
>          /* We must update the target FPR before raising the exception */
> -        env->exception_index = POWERPC_EXCP_PROGRAM;
> +        cs->exception_index = POWERPC_EXCP_PROGRAM;
>          env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
>      }
>  }
>
>  static inline void float_inexact_excp(CPUPPCState *env)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
> +
>      env->fpscr |= 1 << FPSCR_XX;
>      /* Update the floating-point exception summary */
>      env->fpscr |= 1 << FPSCR_FX;
> @@ -247,7 +254,7 @@ static inline void float_inexact_excp(CPUPPCState *env)
>          /* Update the floating-point enabled exception summary */
>          env->fpscr |= 1 << FPSCR_FEX;
>          /* We must update the target FPR before raising the exception */
> -        env->exception_index = POWERPC_EXCP_PROGRAM;
> +        cs->exception_index = POWERPC_EXCP_PROGRAM;
>          env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
>      }
>  }
> @@ -299,6 +306,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
>
>  void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      int prev;
>
>      prev = (env->fpscr >> bit) & 1;
> @@ -422,7 +430,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
>              /* Update the floating-point enabled exception summary */
>              env->fpscr |= 1 << FPSCR_FEX;
>              /* We have to update Rc1 before raising the exception */
> -            env->exception_index = POWERPC_EXCP_PROGRAM;
> +            cs->exception_index = POWERPC_EXCP_PROGRAM;
>              break;
>          }
>      }
> @@ -430,6 +438,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
>
>  void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      target_ulong prev, new;
>      int i;
>
> @@ -451,7 +460,7 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
>      }
>      if ((fpscr_ex & fpscr_eex) != 0) {
>          env->fpscr |= 1 << FPSCR_FEX;
> -        env->exception_index = POWERPC_EXCP_PROGRAM;
> +        cs->exception_index = POWERPC_EXCP_PROGRAM;
>          /* XXX: we should compute it properly */
>          env->error_code = POWERPC_EXCP_FP;
>      } else {
> @@ -467,6 +476,7 @@ void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
>
>  void helper_float_check_status(CPUPPCState *env)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      int status = get_float_exception_flags(&env->fp_status);
>
>      if (status & float_flag_divbyzero) {
> @@ -479,11 +489,11 @@ void helper_float_check_status(CPUPPCState *env)
>          float_inexact_excp(env);
>      }
>
> -    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
> +    if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
>          (env->error_code & POWERPC_EXCP_FP)) {
>          /* Differred floating-point exception after target FPR update */
>          if (msr_fe0 != 0 || msr_fe1 != 0) {
> -            helper_raise_exception_err(env, env->exception_index,
> +            helper_raise_exception_err(env, cs->exception_index,
>                                         env->error_code);
>          }
>      }
> diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
> index 6a77dc4..aa87084 100644
> --- a/target-ppc/mmu-hash32.c
> +++ b/target-ppc/mmu-hash32.c
> @@ -222,6 +222,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
>                                     target_ulong eaddr, int rwx,
>                                     hwaddr *raddr, int *prot)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
>
>      LOG_MMU("direct store...\n");
> @@ -238,7 +239,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
>
>      if (rwx == 2) {
>          /* No code fetch is allowed in direct-store areas */
> -        env->exception_index = POWERPC_EXCP_ISI;
> +        cs->exception_index = POWERPC_EXCP_ISI;
>          env->error_code = 0x10000000;
>          return 1;
>      }
> @@ -249,7 +250,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
>          break;
>      case ACCESS_FLOAT:
>          /* Floating point load/store */
> -        env->exception_index = POWERPC_EXCP_ALIGN;
> +        cs->exception_index = POWERPC_EXCP_ALIGN;
>          env->error_code = POWERPC_EXCP_ALIGN_FP;
>          env->spr[SPR_DAR] = eaddr;
>          return 1;
> @@ -272,7 +273,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
>          return 0;
>      case ACCESS_EXT:
>          /* eciwx or ecowx */
> -        env->exception_index = POWERPC_EXCP_DSI;
> +        cs->exception_index = POWERPC_EXCP_DSI;
>          env->error_code = 0;
>          env->spr[SPR_DAR] = eaddr;
>          if (rwx == 1) {
> @@ -290,7 +291,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
>          *raddr = eaddr;
>          return 0;
>      } else {
> -        env->exception_index = POWERPC_EXCP_DSI;
> +        cs->exception_index = POWERPC_EXCP_DSI;
>          env->error_code = 0;
>          env->spr[SPR_DAR] = eaddr;
>          if (rwx == 1) {
> @@ -383,6 +384,7 @@ static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
>  int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
>                                  int mmu_idx)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      target_ulong sr;
>      hwaddr pte_offset;
>      ppc_hash_pte32_t pte;
> @@ -409,10 +411,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
>          if (raddr != -1) {
>              if (need_prot[rwx] & ~prot) {
>                  if (rwx == 2) {
> -                    env->exception_index = POWERPC_EXCP_ISI;
> +                    cs->exception_index = POWERPC_EXCP_ISI;
>                      env->error_code = 0x08000000;
>                  } else {
> -                    env->exception_index = POWERPC_EXCP_DSI;
> +                    cs->exception_index = POWERPC_EXCP_DSI;
>                      env->error_code = 0;
>                      env->spr[SPR_DAR] = eaddr;
>                      if (rwx == 1) {
> @@ -449,7 +451,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
>
>      /* 5. Check for segment level no-execute violation */
>      if ((rwx == 2) && (sr & SR32_NX)) {
> -        env->exception_index = POWERPC_EXCP_ISI;
> +        cs->exception_index = POWERPC_EXCP_ISI;
>          env->error_code = 0x10000000;
>          return 1;
>      }
> @@ -458,10 +460,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
>      pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte);
>      if (pte_offset == -1) {
>          if (rwx == 2) {
> -            env->exception_index = POWERPC_EXCP_ISI;
> +            cs->exception_index = POWERPC_EXCP_ISI;
>              env->error_code = 0x40000000;
>          } else {
> -            env->exception_index = POWERPC_EXCP_DSI;
> +            cs->exception_index = POWERPC_EXCP_DSI;
>              env->error_code = 0;
>              env->spr[SPR_DAR] = eaddr;
>              if (rwx == 1) {
> @@ -483,10 +485,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
>          /* Access right violation */
>          LOG_MMU("PTE access rejected\n");
>          if (rwx == 2) {
> -            env->exception_index = POWERPC_EXCP_ISI;
> +            cs->exception_index = POWERPC_EXCP_ISI;
>              env->error_code = 0x08000000;
>          } else {
> -            env->exception_index = POWERPC_EXCP_DSI;
> +            cs->exception_index = POWERPC_EXCP_DSI;
>              env->error_code = 0;
>              env->spr[SPR_DAR] = eaddr;
>              if (rwx == 1) {
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 67fc1b5..04dcfb3 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -399,6 +399,7 @@ static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
>  int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
>                                  int rwx, int mmu_idx)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      ppc_slb_t *slb;
>      hwaddr pte_offset;
>      ppc_hash_pte64_t pte;
> @@ -425,10 +426,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
>
>      if (!slb) {
>          if (rwx == 2) {
> -            env->exception_index = POWERPC_EXCP_ISEG;
> +            cs->exception_index = POWERPC_EXCP_ISEG;
>              env->error_code = 0;
>          } else {
> -            env->exception_index = POWERPC_EXCP_DSEG;
> +            cs->exception_index = POWERPC_EXCP_DSEG;
>              env->error_code = 0;
>              env->spr[SPR_DAR] = eaddr;
>          }
> @@ -437,7 +438,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
>
>      /* 3. Check for segment level no-execute violation */
>      if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
> -        env->exception_index = POWERPC_EXCP_ISI;
> +        cs->exception_index = POWERPC_EXCP_ISI;
>          env->error_code = 0x10000000;
>          return 1;
>      }
> @@ -446,10 +447,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
>      pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte);
>      if (pte_offset == -1) {
>          if (rwx == 2) {
> -            env->exception_index = POWERPC_EXCP_ISI;
> +            cs->exception_index = POWERPC_EXCP_ISI;
>              env->error_code = 0x40000000;
>          } else {
> -            env->exception_index = POWERPC_EXCP_DSI;
> +            cs->exception_index = POWERPC_EXCP_DSI;
>              env->error_code = 0;
>              env->spr[SPR_DAR] = eaddr;
>              if (rwx == 1) {
> @@ -472,12 +473,12 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
>          /* Access right violation */
>          LOG_MMU("PTE access rejected\n");
>          if (rwx == 2) {
> -            env->exception_index = POWERPC_EXCP_ISI;
> +            cs->exception_index = POWERPC_EXCP_ISI;
>              env->error_code = 0x08000000;
>          } else {
>              target_ulong dsisr = 0;
>
> -            env->exception_index = POWERPC_EXCP_DSI;
> +            cs->exception_index = POWERPC_EXCP_DSI;
>              env->error_code = 0;
>              env->spr[SPR_DAR] = eaddr;
>              if (need_prot[rwx] & ~pp_prot) {
> diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
> index 04a840b..79a9134 100644
> --- a/target-ppc/mmu_helper.c
> +++ b/target-ppc/mmu_helper.c
> @@ -1491,6 +1491,7 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
>  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                                      int rw, int mmu_idx)
>  {
> +    CPUState *cs = CPU(ppc_env_get_cpu(env));
>      mmu_ctx_t ctx;
>      int access_type;
>      int ret = 0;
> @@ -1510,24 +1511,24 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                       mmu_idx, TARGET_PAGE_SIZE);
>          ret = 0;
>      } else if (ret < 0) {
> -        LOG_MMU_STATE(CPU(ppc_env_get_cpu(env)));
> +        LOG_MMU_STATE(cs);
>          if (access_type == ACCESS_CODE) {
>              switch (ret) {
>              case -1:
>                  /* No matches in page tables or TLB */
>                  switch (env->mmu_model) {
>                  case POWERPC_MMU_SOFT_6xx:
> -                    env->exception_index = POWERPC_EXCP_IFTLB;
> +                    cs->exception_index = POWERPC_EXCP_IFTLB;
>                      env->error_code = 1 << 18;
>                      env->spr[SPR_IMISS] = address;
>                      env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
>                      goto tlb_miss;
>                  case POWERPC_MMU_SOFT_74xx:
> -                    env->exception_index = POWERPC_EXCP_IFTLB;
> +                    cs->exception_index = POWERPC_EXCP_IFTLB;
>                      goto tlb_miss_74xx;
>                  case POWERPC_MMU_SOFT_4xx:
>                  case POWERPC_MMU_SOFT_4xx_Z:
> -                    env->exception_index = POWERPC_EXCP_ITLB;
> +                    cs->exception_index = POWERPC_EXCP_ITLB;
>                      env->error_code = 0;
>                      env->spr[SPR_40x_DEAR] = address;
>                      env->spr[SPR_40x_ESR] = 0x00000000;
> @@ -1536,7 +1537,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      booke206_update_mas_tlb_miss(env, address, rw);
>                      /* fall through */
>                  case POWERPC_MMU_BOOKE:
> -                    env->exception_index = POWERPC_EXCP_ITLB;
> +                    cs->exception_index = POWERPC_EXCP_ITLB;
>                      env->error_code = 0;
>                      env->spr[SPR_BOOKE_DEAR] = address;
>                      return -1;
> @@ -1555,7 +1556,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                  break;
>              case -2:
>                  /* Access rights violation */
> -                env->exception_index = POWERPC_EXCP_ISI;
> +                cs->exception_index = POWERPC_EXCP_ISI;
>                  env->error_code = 0x08000000;
>                  break;
>              case -3:
> @@ -1564,13 +1565,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      (env->mmu_model == POWERPC_MMU_BOOKE206)) {
>                      env->spr[SPR_BOOKE_ESR] = 0x00000000;
>                  }
> -                env->exception_index = POWERPC_EXCP_ISI;
> +                cs->exception_index = POWERPC_EXCP_ISI;
>                  env->error_code = 0x10000000;
>                  break;
>              case -4:
>                  /* Direct store exception */
>                  /* No code fetch is allowed in direct-store areas */
> -                env->exception_index = POWERPC_EXCP_ISI;
> +                cs->exception_index = POWERPC_EXCP_ISI;
>                  env->error_code = 0x10000000;
>                  break;
>              }
> @@ -1581,10 +1582,10 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                  switch (env->mmu_model) {
>                  case POWERPC_MMU_SOFT_6xx:
>                      if (rw == 1) {
> -                        env->exception_index = POWERPC_EXCP_DSTLB;
> +                        cs->exception_index = POWERPC_EXCP_DSTLB;
>                          env->error_code = 1 << 16;
>                      } else {
> -                        env->exception_index = POWERPC_EXCP_DLTLB;
> +                        cs->exception_index = POWERPC_EXCP_DLTLB;
>                          env->error_code = 0;
>                      }
>                      env->spr[SPR_DMISS] = address;
> @@ -1598,9 +1599,9 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      break;
>                  case POWERPC_MMU_SOFT_74xx:
>                      if (rw == 1) {
> -                        env->exception_index = POWERPC_EXCP_DSTLB;
> +                        cs->exception_index = POWERPC_EXCP_DSTLB;
>                      } else {
> -                        env->exception_index = POWERPC_EXCP_DLTLB;
> +                        cs->exception_index = POWERPC_EXCP_DLTLB;
>                      }
>                  tlb_miss_74xx:
>                      /* Implement LRU algorithm */
> @@ -1611,7 +1612,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      break;
>                  case POWERPC_MMU_SOFT_4xx:
>                  case POWERPC_MMU_SOFT_4xx_Z:
> -                    env->exception_index = POWERPC_EXCP_DTLB;
> +                    cs->exception_index = POWERPC_EXCP_DTLB;
>                      env->error_code = 0;
>                      env->spr[SPR_40x_DEAR] = address;
>                      if (rw) {
> @@ -1628,7 +1629,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      booke206_update_mas_tlb_miss(env, address, rw);
>                      /* fall through */
>                  case POWERPC_MMU_BOOKE:
> -                    env->exception_index = POWERPC_EXCP_DTLB;
> +                    cs->exception_index = POWERPC_EXCP_DTLB;
>                      env->error_code = 0;
>                      env->spr[SPR_BOOKE_DEAR] = address;
>                      env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
> @@ -1644,7 +1645,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                  break;
>              case -2:
>                  /* Access rights violation */
> -                env->exception_index = POWERPC_EXCP_DSI;
> +                cs->exception_index = POWERPC_EXCP_DSI;
>                  env->error_code = 0;
>                  if (env->mmu_model == POWERPC_MMU_SOFT_4xx
>                      || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
> @@ -1670,13 +1671,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                  switch (access_type) {
>                  case ACCESS_FLOAT:
>                      /* Floating point load/store */
> -                    env->exception_index = POWERPC_EXCP_ALIGN;
> +                    cs->exception_index = POWERPC_EXCP_ALIGN;
>                      env->error_code = POWERPC_EXCP_ALIGN_FP;
>                      env->spr[SPR_DAR] = address;
>                      break;
>                  case ACCESS_RES:
>                      /* lwarx, ldarx or stwcx. */
> -                    env->exception_index = POWERPC_EXCP_DSI;
> +                    cs->exception_index = POWERPC_EXCP_DSI;
>                      env->error_code = 0;
>                      env->spr[SPR_DAR] = address;
>                      if (rw == 1) {
> @@ -1687,7 +1688,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      break;
>                  case ACCESS_EXT:
>                      /* eciwx or ecowx */
> -                    env->exception_index = POWERPC_EXCP_DSI;
> +                    cs->exception_index = POWERPC_EXCP_DSI;
>                      env->error_code = 0;
>                      env->spr[SPR_DAR] = address;
>                      if (rw == 1) {
> @@ -1698,7 +1699,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>                      break;
>                  default:
>                      printf("DSI: invalid exception (%d)\n", ret);
> -                    env->exception_index = POWERPC_EXCP_PROGRAM;
> +                    cs->exception_index = POWERPC_EXCP_PROGRAM;
>                      env->error_code =
>                          POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
>                      env->spr[SPR_DAR] = address;
> @@ -1709,7 +1710,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
>          }
>  #if 0
>          printf("%s: set exception to %d %02x\n", __func__,
> -               env->exception, env->error_code);
> +               cs->exception, env->error_code);
>  #endif
>          ret = 1;
>      }
> @@ -2908,6 +2909,6 @@ void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
>              /* now we have a real cpu fault */
>              cpu_restore_state(env, retaddr);
>          }
> -        helper_raise_exception_err(env, env->exception_index, env->error_code);
> +        helper_raise_exception_err(env, cpu->exception_index, env->error_code);
>      }
>  }
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 8b6fbb5..0934a45 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8511,7 +8511,7 @@ static void ppc_cpu_reset(CPUState *s)
>      env->reserve_addr = (target_ulong)-1ULL;
>      /* Be sure no exception or interrupt is pending */
>      env->pending_interrupts = 0;
> -    env->exception_index = POWERPC_EXCP_NONE;
> +    s->exception_index = POWERPC_EXCP_NONE;
>      env->error_code = 0;
>
>  #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
> diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
> index a7c99e0..829f66f 100644
> --- a/target-ppc/user_only_helper.c
> +++ b/target-ppc/user_only_helper.c
> @@ -39,7 +39,7 @@ int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>          env->spr[SPR_DAR] = address;
>          env->spr[SPR_DSISR] = error_code;
>      }
> -    env->exception_index = exception;
> +    cs->exception_index = exception;
>      env->error_code = error_code;
>
>      return 1;
> diff --git a/target-s390x/helper.c b/target-s390x/helper.c
> index 361d713..c9d3d55 100644
> --- a/target-s390x/helper.c
> +++ b/target-s390x/helper.c
> @@ -88,10 +88,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
>
>  void s390_cpu_do_interrupt(CPUState *cs)
>  {
> -    S390CPU *cpu = S390_CPU(cs);
> -    CPUS390XState *env = &cpu->env;
> -
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
>
>  int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
> @@ -99,7 +96,7 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>  {
>      S390CPU *cpu = S390_CPU(cs);
>
> -    cpu->env.exception_index = EXCP_PGM;
> +    cs->exception_index = EXCP_PGM;
>      cpu->env.int_pgm_code = PGM_ADDRESSING;
>      /* On real machines this value is dropped into LowMem.  Since this
>         is userland, simply put this someplace that cpu_loop can find it.  */
> @@ -113,7 +110,9 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>  static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
>                                    uint32_t ilen)
>  {
> -    env->exception_index = EXCP_PGM;
> +    CPUState *cs = CPU(s390_env_get_cpu(env));
> +
> +    cs->exception_index = EXCP_PGM;
>      env->int_pgm_code = code;
>      env->int_pgm_ilen = ilen;
>  }
> @@ -427,7 +426,7 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
>      CPUS390XState *env = &cpu->env;
>      target_ulong raddr;
>      int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> -    int old_exc = env->exception_index;
> +    int old_exc = cs->exception_index;
>      uint64_t asc = env->psw.mask & PSW_MASK_ASC;
>
>      /* 31-Bit mode */
> @@ -436,7 +435,7 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
>      }
>
>      mmu_translate(env, vaddr, 2, asc, &raddr, &prot);
> -    env->exception_index = old_exc;
> +    cs->exception_index = old_exc;
>
>      return raddr;
>  }
> @@ -454,7 +453,7 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
>              }
>          }
>          cs->halted = 1;
> -        env->exception_index = EXCP_HLT;
> +        cs->exception_index = EXCP_HLT;
>      }
>
>      env->psw.addr = addr;
> @@ -751,43 +750,43 @@ void s390_cpu_do_interrupt(CPUState *cs)
>      CPUS390XState *env = &cpu->env;
>
>      qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
> -                  __func__, env->exception_index, env->psw.addr);
> +                  __func__, cs->exception_index, env->psw.addr);
>
>      s390_add_running_cpu(cpu);
>      /* handle machine checks */
>      if ((env->psw.mask & PSW_MASK_MCHECK) &&
> -        (env->exception_index == -1)) {
> +        (cs->exception_index == -1)) {
>          if (env->pending_int & INTERRUPT_MCHK) {
> -            env->exception_index = EXCP_MCHK;
> +            cs->exception_index = EXCP_MCHK;
>          }
>      }
>      /* handle external interrupts */
>      if ((env->psw.mask & PSW_MASK_EXT) &&
> -        env->exception_index == -1) {
> +        cs->exception_index == -1) {
>          if (env->pending_int & INTERRUPT_EXT) {
>              /* code is already in env */
> -            env->exception_index = EXCP_EXT;
> +            cs->exception_index = EXCP_EXT;
>          } else if (env->pending_int & INTERRUPT_TOD) {
>              cpu_inject_ext(cpu, 0x1004, 0, 0);
> -            env->exception_index = EXCP_EXT;
> +            cs->exception_index = EXCP_EXT;
>              env->pending_int &= ~INTERRUPT_EXT;
>              env->pending_int &= ~INTERRUPT_TOD;
>          } else if (env->pending_int & INTERRUPT_CPUTIMER) {
>              cpu_inject_ext(cpu, 0x1005, 0, 0);
> -            env->exception_index = EXCP_EXT;
> +            cs->exception_index = EXCP_EXT;
>              env->pending_int &= ~INTERRUPT_EXT;
>              env->pending_int &= ~INTERRUPT_TOD;
>          }
>      }
>      /* handle I/O interrupts */
>      if ((env->psw.mask & PSW_MASK_IO) &&
> -        (env->exception_index == -1)) {
> +        (cs->exception_index == -1)) {
>          if (env->pending_int & INTERRUPT_IO) {
> -            env->exception_index = EXCP_IO;
> +            cs->exception_index = EXCP_IO;
>          }
>      }
>
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXCP_PGM:
>          do_program_interrupt(env);
>          break;
> @@ -804,7 +803,7 @@ void s390_cpu_do_interrupt(CPUState *cs)
>          do_mchk_interrupt(env);
>          break;
>      }
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>
>      if (!env->pending_int) {
>          cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
> diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
> index 747ba46..e2748a7 100644
> --- a/target-s390x/mem_helper.c
> +++ b/target-s390x/mem_helper.c
> @@ -1048,8 +1048,9 @@ void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint64_t v1)
>  /* load real address */
>  uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>  {
> +    CPUState *cs = CPU(s390_env_get_cpu(env));
>      uint32_t cc = 0;
> -    int old_exc = env->exception_index;
> +    int old_exc = cs->exception_index;
>      uint64_t asc = env->psw.mask & PSW_MASK_ASC;
>      uint64_t ret;
>      int flags;
> @@ -1059,16 +1060,16 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>          program_interrupt(env, PGM_SPECIAL_OP, 2);
>      }
>
> -    env->exception_index = old_exc;
> +    cs->exception_index = old_exc;
>      if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
>          cc = 3;
>      }
> -    if (env->exception_index == EXCP_PGM) {
> +    if (cs->exception_index == EXCP_PGM) {
>          ret = env->int_pgm_code | 0x80000000;
>      } else {
>          ret |= addr & ~TARGET_PAGE_MASK;
>      }
> -    env->exception_index = old_exc;
> +    cs->exception_index = old_exc;
>
>      env->cc_op = cc;
>      return ret;
> diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
> index 1690907..b6bd16f 100644
> --- a/target-s390x/misc_helper.c
> +++ b/target-s390x/misc_helper.c
> @@ -46,9 +46,10 @@
>  void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
>                                       uintptr_t retaddr)
>  {
> +    CPUState *cs = CPU(s390_env_get_cpu(env));
>      int t;
>
> -    env->exception_index = EXCP_PGM;
> +    cs->exception_index = EXCP_PGM;
>      env->int_pgm_code = excp;
>
>      /* Use the (ultimate) callers address to find the insn that trapped.  */
> @@ -65,8 +66,10 @@ void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
>  /* Raise an exception statically from a TB.  */
>  void HELPER(exception)(CPUS390XState *env, uint32_t excp)
>  {
> +    CPUState *cs = CPU(s390_env_get_cpu(env));
> +
>      HELPER_LOG("%s: exception %d\n", __func__, excp);
> -    env->exception_index = excp;
> +    cs->exception_index = excp;
>      cpu_loop_exit(env);
>  }
>
> @@ -154,17 +157,21 @@ static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
>
>  void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
>  {
> +    S390CPU *cpu = s390_env_get_cpu(env);
> +
>      qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
>                    env->psw.addr);
>
>      if (kvm_enabled()) {
>  #ifdef CONFIG_KVM
> -        kvm_s390_interrupt(s390_env_get_cpu(env), KVM_S390_PROGRAM_INT, code);
> +        kvm_s390_interrupt(cpu, KVM_S390_PROGRAM_INT, code);
>  #endif
>      } else {
> +        CPUState *cs = CPU(cpu);
> +
>          env->int_pgm_code = code;
>          env->int_pgm_ilen = ilen;
> -        env->exception_index = EXCP_PGM;
> +        cs->exception_index = EXCP_PGM;
>          cpu_loop_exit(env);
>      }
>  }
> diff --git a/target-sh4/helper.c b/target-sh4/helper.c
> index 3f8f1fa..0357ceb 100644
> --- a/target-sh4/helper.c
> +++ b/target-sh4/helper.c
> @@ -33,10 +33,7 @@
>
>  void superh_cpu_do_interrupt(CPUState *cs)
>  {
> -    SuperHCPU *cpu = SUPERH_CPU(cs);
> -    CPUSH4State *env = &cpu->env;
> -
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
>
>  int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> @@ -46,16 +43,16 @@ int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>      CPUSH4State *env = &cpu->env;
>
>      env->tea = address;
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>      switch (rw) {
>      case 0:
> -        env->exception_index = 0x0a0;
> +        cs->exception_index = 0x0a0;
>          break;
>      case 1:
> -        env->exception_index = 0x0c0;
> +        cs->exception_index = 0x0c0;
>          break;
>      case 2:
> -        env->exception_index = 0x0a0;
> +        cs->exception_index = 0x0a0;
>          break;
>      }
>      return 1;
> @@ -89,16 +86,16 @@ void superh_cpu_do_interrupt(CPUState *cs)
>      SuperHCPU *cpu = SUPERH_CPU(cs);
>      CPUSH4State *env = &cpu->env;
>      int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD;
> -    int do_exp, irq_vector = env->exception_index;
> +    int do_exp, irq_vector = cs->exception_index;
>
>      /* prioritize exceptions over interrupts */
>
> -    do_exp = env->exception_index != -1;
> -    do_irq = do_irq && (env->exception_index == -1);
> +    do_exp = cs->exception_index != -1;
> +    do_irq = do_irq && (cs->exception_index == -1);
>
>      if (env->sr & SR_BL) {
> -        if (do_exp && env->exception_index != 0x1e0) {
> -            env->exception_index = 0x000; /* masked exception -> reset */
> +        if (do_exp && cs->exception_index != 0x1e0) {
> +            cs->exception_index = 0x000; /* masked exception -> reset */
>          }
>          if (do_irq && !env->in_sleep) {
>              return; /* masked */
> @@ -116,7 +113,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
>
>      if (qemu_loglevel_mask(CPU_LOG_INT)) {
>         const char *expname;
> -       switch (env->exception_index) {
> +        switch (cs->exception_index) {
>         case 0x0e0:
>             expname = "addr_error";
>             break;
> @@ -180,8 +177,8 @@ void superh_cpu_do_interrupt(CPUState *cs)
>          env->flags = 0;
>
>      if (do_exp) {
> -        env->expevt = env->exception_index;
> -        switch (env->exception_index) {
> +        env->expevt = cs->exception_index;
> +        switch (cs->exception_index) {
>          case 0x000:
>          case 0x020:
>          case 0x140:
> @@ -472,33 +469,33 @@ int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>         switch (ret) {
>         case MMU_ITLB_MISS:
>         case MMU_DTLB_MISS_READ:
> -           env->exception_index = 0x040;
> +            cs->exception_index = 0x040;
>             break;
>         case MMU_DTLB_MULTIPLE:
>         case MMU_ITLB_MULTIPLE:
> -           env->exception_index = 0x140;
> +            cs->exception_index = 0x140;
>             break;
>         case MMU_ITLB_VIOLATION:
> -           env->exception_index = 0x0a0;
> +            cs->exception_index = 0x0a0;
>             break;
>         case MMU_DTLB_MISS_WRITE:
> -           env->exception_index = 0x060;
> +            cs->exception_index = 0x060;
>             break;
>         case MMU_DTLB_INITIAL_WRITE:
> -           env->exception_index = 0x080;
> +            cs->exception_index = 0x080;
>             break;
>         case MMU_DTLB_VIOLATION_READ:
> -           env->exception_index = 0x0a0;
> +            cs->exception_index = 0x0a0;
>             break;
>         case MMU_DTLB_VIOLATION_WRITE:
> -           env->exception_index = 0x0c0;
> +            cs->exception_index = 0x0c0;
>             break;
>         case MMU_IADDR_ERROR:
>         case MMU_DADDR_ERROR_READ:
> -           env->exception_index = 0x0e0;
> +            cs->exception_index = 0x0e0;
>             break;
>         case MMU_DADDR_ERROR_WRITE:
> -           env->exception_index = 0x100;
> +            cs->exception_index = 0x100;
>             break;
>         default:
>              cpu_abort(env, "Unhandled MMU fault");
> @@ -702,8 +699,10 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, hwaddr addr,
>              if (entry->vpn == vpn
>                  && (!use_asid || entry->asid == asid || entry->sh)) {
>                 if (utlb_match_entry) {
> +                    CPUState *cs = CPU(sh_env_get_cpu(s));
> +
>                     /* Multiple TLB Exception */
> -                   s->exception_index = 0x140;
> +                    cs->exception_index = 0x140;
>                     s->tea = addr;
>                     break;
>                 }
> diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
> index 35f9067..03633f0 100644
> --- a/target-sh4/op_helper.c
> +++ b/target-sh4/op_helper.c
> @@ -69,7 +69,9 @@ void helper_ldtlb(CPUSH4State *env)
>  static inline void QEMU_NORETURN raise_exception(CPUSH4State *env, int index,
>                                                   uintptr_t retaddr)
>  {
> -    env->exception_index = index;
> +    CPUState *cs = CPU(sh_env_get_cpu(env));
> +
> +    cs->exception_index = index;
>      if (retaddr) {
>          cpu_restore_state(env, retaddr);
>      }
> diff --git a/target-sparc/helper.c b/target-sparc/helper.c
> index 57c20af..a393ef0 100644
> --- a/target-sparc/helper.c
> +++ b/target-sparc/helper.c
> @@ -24,13 +24,17 @@
>
>  void helper_raise_exception(CPUSPARCState *env, int tt)
>  {
> -    env->exception_index = tt;
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
> +
> +    cs->exception_index = tt;
>      cpu_loop_exit(env);
>  }
>
>  void helper_debug(CPUSPARCState *env)
>  {
> -    env->exception_index = EXCP_DEBUG;
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
> +
> +    cs->exception_index = EXCP_DEBUG;
>      cpu_loop_exit(env);
>  }
>
> @@ -232,7 +236,7 @@ void helper_power_down(CPUSPARCState *env)
>      CPUState *cs = CPU(sparc_env_get_cpu(env));
>
>      cs->halted = 1;
> -    env->exception_index = EXCP_HLT;
> +    cs->exception_index = EXCP_HLT;
>      env->pc = env->npc;
>      env->npc = env->pc + 4;
>      cpu_loop_exit(env);
> diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
> index d532238..f350a90 100644
> --- a/target-sparc/int32_helper.c
> +++ b/target-sparc/int32_helper.c
> @@ -62,7 +62,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>  {
>      SPARCCPU *cpu = SPARC_CPU(cs);
>      CPUSPARCState *env = &cpu->env;
> -    int cwp, intno = env->exception_index;
> +    int cwp, intno = cs->exception_index;
>
>      /* Compute PSR before exposing state.  */
>      if (env->cc_op != CC_OP_FLAGS) {
> @@ -105,12 +105,12 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>  #endif
>  #if !defined(CONFIG_USER_ONLY)
>      if (env->psret == 0) {
> -        if (env->exception_index == 0x80 &&
> +        if (cs->exception_index == 0x80 &&
>              env->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
>              qemu_system_shutdown_request();
>          } else {
>              cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
> -                      env->exception_index);
> +                      cs->exception_index);
>          }
>          return;
>      }
> @@ -125,7 +125,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>      env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
>      env->pc = env->tbr;
>      env->npc = env->pc + 4;
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>
>  #if !defined(CONFIG_USER_ONLY)
>      /* IRQ acknowledgment */
> diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
> index bf7dd86..1744245 100644
> --- a/target-sparc/int64_helper.c
> +++ b/target-sparc/int64_helper.c
> @@ -63,7 +63,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>  {
>      SPARCCPU *cpu = SPARC_CPU(cs);
>      CPUSPARCState *env = &cpu->env;
> -    int intno = env->exception_index;
> +    int intno = cs->exception_index;
>      trap_state *tsptr;
>
>      /* Compute PSR before exposing state.  */
> @@ -112,7 +112,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>  #if !defined(CONFIG_USER_ONLY)
>      if (env->tl >= env->maxtl) {
>          cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
> -                  " Error state", env->exception_index, env->tl, env->maxtl);
> +                  " Error state", cs->exception_index, env->tl, env->maxtl);
>          return;
>      }
>  #endif
> @@ -160,7 +160,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>      env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
>      env->pc = env->tbr;
>      env->npc = env->pc + 4;
> -    env->exception_index = -1;
> +    cs->exception_index = -1;
>  }
>
>  trap_state *cpu_tsptr(CPUSPARCState* env)
> diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
> index 2f55af9..af7c289 100644
> --- a/target-sparc/ldst_helper.c
> +++ b/target-sparc/ldst_helper.c
> @@ -1284,6 +1284,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
>  uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
>                         int sign)
>  {
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
>      uint64_t ret = 0;
>  #if defined(DEBUG_ASI)
>      target_ulong last_addr = addr;
> @@ -1317,7 +1318,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
>              dump_asi("read ", last_addr, asi, size, ret);
>  #endif
>              /* env->exception_index is set in get_physical_address_data(). */
> -            helper_raise_exception(env, env->exception_index);
> +            helper_raise_exception(env, cs->exception_index);
>          }
>
>          /* convert nonfaulting load ASIs to normal load ASIs */
> diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
> index 0d88326..ea72657 100644
> --- a/target-sparc/mmu_helper.c
> +++ b/target-sparc/mmu_helper.c
> @@ -28,12 +28,10 @@
>  int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                 int mmu_idx)
>  {
> -    SPARCCPU *cpu = SPARC_CPU(cs);
> -
>      if (rw & 2) {
> -        cpu->env.exception_index = TT_TFAULT;
> +        cs->exception_index = TT_TFAULT;
>      } else {
> -        cpu->env.exception_index = TT_DFAULT;
> +        cs->exception_index = TT_DFAULT;
>      }
>      return 1;
>  }
> @@ -238,9 +236,9 @@ int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>          return 0;
>      } else {
>          if (rw & 2) {
> -            env->exception_index = TT_TFAULT;
> +            cs->exception_index = TT_TFAULT;
>          } else {
> -            env->exception_index = TT_DFAULT;
> +            cs->exception_index = TT_DFAULT;
>          }
>          return 1;
>      }
> @@ -489,6 +487,7 @@ static int get_physical_address_data(CPUSPARCState *env,
>                                       hwaddr *physical, int *prot,
>                                       target_ulong address, int rw, int mmu_idx)
>  {
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
>      unsigned int i;
>      uint64_t context;
>      uint64_t sfsr = 0;
> @@ -553,10 +552,10 @@ static int get_physical_address_data(CPUSPARCState *env,
>
>              if (do_fault) {
>                  /* faults above are reported with TT_DFAULT. */
> -                env->exception_index = TT_DFAULT;
> +                cs->exception_index = TT_DFAULT;
>              } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
>                  do_fault = 1;
> -                env->exception_index = TT_DPROT;
> +                cs->exception_index = TT_DPROT;
>
>                  trace_mmu_helper_dprot(address, context, mmu_idx, env->tl);
>              }
> @@ -600,7 +599,7 @@ static int get_physical_address_data(CPUSPARCState *env,
>       * - JPS1: SFAR updated and some fields of SFSR updated
>       */
>      env->dmmu.tag_access = (address & ~0x1fffULL) | context;
> -    env->exception_index = TT_DMISS;
> +    cs->exception_index = TT_DMISS;
>      return 1;
>  }
>
> @@ -608,6 +607,7 @@ static int get_physical_address_code(CPUSPARCState *env,
>                                       hwaddr *physical, int *prot,
>                                       target_ulong address, int mmu_idx)
>  {
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
>      unsigned int i;
>      uint64_t context;
>
> @@ -651,7 +651,7 @@ static int get_physical_address_code(CPUSPARCState *env,
>
>                  /* FIXME: ASI field in SFSR must be set */
>                  env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
> -                env->exception_index = TT_TFAULT;
> +                cs->exception_index = TT_TFAULT;
>
>                  env->immu.tag_access = (address & ~0x1fffULL) | context;
>
> @@ -669,7 +669,7 @@ static int get_physical_address_code(CPUSPARCState *env,
>
>      /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
>      env->immu.tag_access = (address & ~0x1fffULL) | context;
> -    env->exception_index = TT_TMISS;
> +    cs->exception_index = TT_TMISS;
>      return 1;
>  }
>
> diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
> index 5cd2378..cd2cbef 100644
> --- a/target-unicore32/op_helper.c
> +++ b/target-unicore32/op_helper.c
> @@ -16,7 +16,9 @@
>
>  void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
>  {
> -    env->exception_index = excp;
> +    CPUState *cs = CPU(uc32_env_get_cpu(env));
> +
> +    cs->exception_index = excp;
>      cpu_loop_exit(env);
>  }
>
> diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
> index 408f1b0..2e26fd1 100644
> --- a/target-unicore32/softmmu.c
> +++ b/target-unicore32/softmmu.c
> @@ -79,7 +79,7 @@ void uc32_cpu_do_interrupt(CPUState *cs)
>      uint32_t addr;
>      int new_mode;
>
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case UC32_EXCP_PRIV:
>          new_mode = ASR_MODE_PRIV;
>          addr = 0x08;
> @@ -99,7 +99,7 @@ void uc32_cpu_do_interrupt(CPUState *cs)
>          addr = 0x18;
>          break;
>      default:
> -        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
> +        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
>          return;
>      }
>      /* High vectors.  */
> @@ -256,9 +256,9 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>      env->cp0.c3_faultstatus = ret;
>      env->cp0.c4_faultaddr = address;
>      if (access_type == 2) {
> -        env->exception_index = UC32_EXCP_ITRAP;
> +        cs->exception_index = UC32_EXCP_ITRAP;
>      } else {
> -        env->exception_index = UC32_EXCP_DTRAP;
> +        cs->exception_index = UC32_EXCP_DTRAP;
>      }
>      return ret;
>  }
> diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
> index a0f9993..f55095e 100644
> --- a/target-xtensa/helper.c
> +++ b/target-xtensa/helper.c
> @@ -169,6 +169,8 @@ static void handle_interrupt(CPUXtensaState *env)
>              (env->config->level_mask[level] &
>               env->sregs[INTSET] &
>               env->sregs[INTENABLE])) {
> +        CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +
>          if (level > 1) {
>              env->sregs[EPC1 + level - 1] = env->pc;
>              env->sregs[EPS2 + level - 2] = env->sregs[PS];
> @@ -185,10 +187,10 @@ static void handle_interrupt(CPUXtensaState *env)
>                  } else {
>                      env->sregs[EPC1] = env->pc;
>                  }
> -                env->exception_index = EXC_DOUBLE;
> +                cs->exception_index = EXC_DOUBLE;
>              } else {
>                  env->sregs[EPC1] = env->pc;
> -                env->exception_index =
> +                cs->exception_index =
>                      (env->sregs[PS] & PS_UM) ? EXC_USER : EXC_KERNEL;
>              }
>              env->sregs[PS] |= PS_EXCM;
> @@ -202,7 +204,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>      XtensaCPU *cpu = XTENSA_CPU(cs);
>      CPUXtensaState *env = &cpu->env;
>
> -    if (env->exception_index == EXC_IRQ) {
> +    if (cs->exception_index == EXC_IRQ) {
>          qemu_log_mask(CPU_LOG_INT,
>                  "%s(EXC_IRQ) level = %d, cintlevel = %d, "
>                  "pc = %08x, a0 = %08x, ps = %08x, "
> @@ -215,7 +217,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>          handle_interrupt(env);
>      }
>
> -    switch (env->exception_index) {
> +    switch (cs->exception_index) {
>      case EXC_WINDOW_OVERFLOW4:
>      case EXC_WINDOW_UNDERFLOW4:
>      case EXC_WINDOW_OVERFLOW8:
> @@ -228,15 +230,15 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>      case EXC_DEBUG:
>          qemu_log_mask(CPU_LOG_INT, "%s(%d) "
>                  "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
> -                __func__, env->exception_index,
> +                __func__, cs->exception_index,
>                  env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
> -        if (env->config->exception_vector[env->exception_index]) {
> +        if (env->config->exception_vector[cs->exception_index]) {
>              env->pc = relocated_vector(env,
> -                    env->config->exception_vector[env->exception_index]);
> +                    env->config->exception_vector[cs->exception_index]);
>              env->exception_taken = 1;
>          } else {
>              qemu_log("%s(pc = %08x) bad exception_index: %d\n",
> -                    __func__, env->pc, env->exception_index);
> +                    __func__, env->pc, cs->exception_index);
>          }
>          break;
>
> @@ -245,7 +247,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>
>      default:
>          qemu_log("%s(pc = %08x) unknown exception_index: %d\n",
> -                __func__, env->pc, env->exception_index);
> +                __func__, env->pc, cs->exception_index);
>          break;
>      }
>      check_interrupts(env);
> diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
> index cf97025..2e006e4 100644
> --- a/target-xtensa/op_helper.c
> +++ b/target-xtensa/op_helper.c
> @@ -96,7 +96,9 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
>
>  void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
>  {
> -    env->exception_index = excp;
> +    CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +
> +    cs->exception_index = excp;
>      if (excp == EXCP_DEBUG) {
>          env->exception_taken = 0;
>      }
> diff --git a/user-exec.c b/user-exec.c
> index dec636e..dbb9c8d 100644
> --- a/user-exec.c
> +++ b/user-exec.c
> @@ -41,7 +41,9 @@
>  static void exception_action(CPUArchState *env1)
>  {
>  #if defined(TARGET_I386)
> -    raise_exception_err(env1, env1->exception_index, env1->error_code);
> +    CPUState *cpu = ENV_GET_CPU(env1);
> +
> +    raise_exception_err(env1, cpu->exception_index, env1->error_code);
>  #else
>      cpu_loop_exit(env1);
>  #endif
> @@ -71,7 +73,7 @@ void cpu_resume_from_signal(CPUArchState *env1, void *puc)
>          sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
>  #endif
>      }
> -    env1->exception_index = -1;
> +    cpu->exception_index = -1;
>      siglongjmp(cpu->jmp_env, 1);
>  }

target-openrisc: Tested-by: Jia Liu <proljc@gmail.com>

>
> --
> 1.8.1.4
>

Patch

diff --git a/cpu-exec.c b/cpu-exec.c
index 39e4f8b..0081eaf 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -41,7 +41,7 @@  void cpu_resume_from_signal(CPUArchState *env, void *puc)
 
     /* XXX: restore cpu registers saved in host registers */
 
-    env->exception_index = -1;
+    cpu->exception_index = -1;
     siglongjmp(cpu->jmp_env, 1);
 }
 #endif
@@ -262,16 +262,16 @@  int cpu_exec(CPUArchState *env)
 #else
 #error unsupported target CPU
 #endif
-    env->exception_index = -1;
+    cpu->exception_index = -1;
 
     /* prepare setjmp context for exception handling */
     for(;;) {
         if (sigsetjmp(cpu->jmp_env, 0) == 0) {
             /* if an exception is pending, we execute it here */
-            if (env->exception_index >= 0) {
-                if (env->exception_index >= EXCP_INTERRUPT) {
+            if (cpu->exception_index >= 0) {
+                if (cpu->exception_index >= EXCP_INTERRUPT) {
                     /* exit request from the cpu execution loop */
-                    ret = env->exception_index;
+                    ret = cpu->exception_index;
                     if (ret == EXCP_DEBUG) {
                         cpu_handle_debug_exception(env);
                     }
@@ -284,11 +284,11 @@  int cpu_exec(CPUArchState *env)
 #if defined(TARGET_I386)
                     cc->do_interrupt(cpu);
 #endif
-                    ret = env->exception_index;
+                    ret = cpu->exception_index;
                     break;
 #else
                     cc->do_interrupt(cpu);
-                    env->exception_index = -1;
+                    cpu->exception_index = -1;
 #endif
                 }
             }
@@ -303,7 +303,7 @@  int cpu_exec(CPUArchState *env)
                     }
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                         cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
-                        env->exception_index = EXCP_DEBUG;
+                        cpu->exception_index = EXCP_DEBUG;
                         cpu_loop_exit(env);
                     }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
@@ -312,7 +312,7 @@  int cpu_exec(CPUArchState *env)
                     if (interrupt_request & CPU_INTERRUPT_HALT) {
                         cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         cpu->halted = 1;
-                        env->exception_index = EXCP_HLT;
+                        cpu->exception_index = EXCP_HLT;
                         cpu_loop_exit(env);
                     }
 #endif
@@ -327,7 +327,7 @@  int cpu_exec(CPUArchState *env)
                             cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
                                                           0);
                             do_cpu_init(x86_env_get_cpu(env));
-                            env->exception_index = EXCP_HALTED;
+                            cpu->exception_index = EXCP_HALTED;
                             cpu_loop_exit(env);
                     } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
                             do_cpu_sipi(x86_env_get_cpu(env));
@@ -396,7 +396,7 @@  int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_LM32)
                     if ((interrupt_request & CPU_INTERRUPT_HARD)
                         && (env->ie & IE_IE)) {
-                        env->exception_index = EXCP_IRQ;
+                        cpu->exception_index = EXCP_IRQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -405,7 +405,7 @@  int cpu_exec(CPUArchState *env)
                         && (env->sregs[SR_MSR] & MSR_IE)
                         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
                         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
-                        env->exception_index = EXCP_IRQ;
+                        cpu->exception_index = EXCP_IRQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -413,7 +413,7 @@  int cpu_exec(CPUArchState *env)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         cpu_mips_hw_interrupts_pending(env)) {
                         /* Raise it */
-                        env->exception_index = EXCP_EXT_INTERRUPT;
+                        cpu->exception_index = EXCP_EXT_INTERRUPT;
                         env->error_code = 0;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
@@ -430,7 +430,7 @@  int cpu_exec(CPUArchState *env)
                             idx = EXCP_TICK;
                         }
                         if (idx >= 0) {
-                            env->exception_index = idx;
+                            cpu->exception_index = idx;
                             cc->do_interrupt(cpu);
                             next_tb = 0;
                         }
@@ -445,7 +445,7 @@  int cpu_exec(CPUArchState *env)
                             if (((type == TT_EXTINT) &&
                                   cpu_pil_allowed(env, pil)) ||
                                   type != TT_EXTINT) {
-                                env->exception_index = env->interrupt_index;
+                                cpu->exception_index = env->interrupt_index;
                                 cc->do_interrupt(cpu);
                                 next_tb = 0;
                             }
@@ -454,7 +454,7 @@  int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_ARM)
                     if (interrupt_request & CPU_INTERRUPT_FIQ
                         && !(env->uncached_cpsr & CPSR_F)) {
-                        env->exception_index = EXCP_FIQ;
+                        cpu->exception_index = EXCP_FIQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -470,14 +470,14 @@  int cpu_exec(CPUArchState *env)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && ((IS_M(env) && env->regs[15] < 0xfffffff0)
                             || !(env->uncached_cpsr & CPSR_I))) {
-                        env->exception_index = EXCP_IRQ;
+                        cpu->exception_index = EXCP_IRQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #elif defined(TARGET_UNICORE32)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && !(env->uncached_asr & ASR_I)) {
-                        env->exception_index = UC32_EXCP_INTR;
+                        cpu->exception_index = UC32_EXCP_INTR;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -512,7 +512,7 @@  int cpu_exec(CPUArchState *env)
                             }
                         }
                         if (idx >= 0) {
-                            env->exception_index = idx;
+                            cpu->exception_index = idx;
                             env->error_code = 0;
                             cc->do_interrupt(cpu);
                             next_tb = 0;
@@ -522,7 +522,7 @@  int cpu_exec(CPUArchState *env)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && (env->pregs[PR_CCS] & I_FLAG)
                         && !env->locked_irq) {
-                        env->exception_index = EXCP_IRQ;
+                        cpu->exception_index = EXCP_IRQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -534,7 +534,7 @@  int cpu_exec(CPUArchState *env)
                             m_flag_archval = M_FLAG_V32;
                         }
                         if ((env->pregs[PR_CCS] & m_flag_archval)) {
-                            env->exception_index = EXCP_NMI;
+                            cpu->exception_index = EXCP_NMI;
                             cc->do_interrupt(cpu);
                             next_tb = 0;
                         }
@@ -548,7 +548,7 @@  int cpu_exec(CPUArchState *env)
                            hardware doesn't rely on this, so we
                            provide/save the vector when the interrupt is
                            first signalled.  */
-                        env->exception_index = env->pending_vector;
+                        cpu->exception_index = env->pending_vector;
                         do_interrupt_m68k_hardirq(env);
                         next_tb = 0;
                     }
@@ -560,7 +560,7 @@  int cpu_exec(CPUArchState *env)
                     }
 #elif defined(TARGET_XTENSA)
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
-                        env->exception_index = EXC_IRQ;
+                        cpu->exception_index = EXC_IRQ;
                         cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
@@ -576,7 +576,7 @@  int cpu_exec(CPUArchState *env)
                 }
                 if (unlikely(cpu->exit_request)) {
                     cpu->exit_request = 0;
-                    env->exception_index = EXCP_INTERRUPT;
+                    cpu->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit(env);
                 }
 #if defined(DEBUG_DISAS)
@@ -662,7 +662,7 @@  int cpu_exec(CPUArchState *env)
                                 /* Execute remaining instructions.  */
                                 cpu_exec_nocache(env, insns_left, tb);
                             }
-                            env->exception_index = EXCP_INTERRUPT;
+                            cpu->exception_index = EXCP_INTERRUPT;
                             next_tb = 0;
                             cpu_loop_exit(env);
                         }
diff --git a/exec.c b/exec.c
index 00c44ea..508f1e2 100644
--- a/exec.c
+++ b/exec.c
@@ -1502,7 +1502,7 @@  static void check_watchpoint(int offset, int len_mask, int flags)
                 env->watchpoint_hit = wp;
                 tb_check_watchpoint(env);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
-                    env->exception_index = EXCP_DEBUG;
+                    cpu->exception_index = EXCP_DEBUG;
                     cpu_loop_exit(env);
                 } else {
                     cc->get_tb_cpu_state(cpu, &pc, &cs_base, &cpu_flags);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index cfdd84b..2d1d478 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -468,14 +468,13 @@  static void ppce500_cpu_reset_sec(void *opaque)
 {
     PowerPCCPU *cpu = opaque;
     CPUState *cs = CPU(cpu);
-    CPUPPCState *env = &cpu->env;
 
     cpu_reset(cs);
 
     /* Secondary CPU starts in halted state for now. Needs to change when
        implementing non-kernel boot. */
     cs->halted = 1;
-    env->exception_index = EXCP_HLT;
+    cs->exception_index = EXCP_HLT;
 }
 
 static void ppce500_cpu_reset(void *opaque)
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index 78b23fa..f9fdc8c 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -117,7 +117,7 @@  static void spin_kick(void *data)
     mmubooke_create_initial_mapping(env, 0, map_start, map_size);
 
     cpu->halted = 0;
-    env->exception_index = -1;
+    cpu->exception_index = -1;
     cpu->stopped = false;
     qemu_cpu_kick(cpu);
 }
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f10ba8a..d4aa4ea 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -511,7 +511,7 @@  static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     hreg_compute_hflags(env);
     if (!cpu_has_work(cs)) {
         cs->halted = 1;
-        env->exception_index = EXCP_HLT;
+        cs->exception_index = EXCP_HLT;
         cs->exit_request = 1;
     }
     return H_SUCCESS;
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 7adf92a..393f3c8 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -134,25 +134,23 @@  static unsigned s390_running_cpus;
 void s390_add_running_cpu(S390CPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    CPUS390XState *env = &cpu->env;
 
     if (cs->halted) {
         s390_running_cpus++;
         cs->halted = 0;
-        env->exception_index = -1;
+        cs->exception_index = -1;
     }
 }
 
 unsigned s390_del_running_cpu(S390CPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    CPUS390XState *env = &cpu->env;
 
     if (cs->halted == 0) {
         assert(s390_running_cpus >= 1);
         s390_running_cpus--;
         cs->halted = 1;
-        env->exception_index = EXCP_HLT;
+        cs->exception_index = EXCP_HLT;
     }
     return s390_running_cpus;
 }
@@ -195,7 +193,7 @@  void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
 
         ipi_states[i] = cpu;
         cs->halted = 1;
-        cpu->env.exception_index = EXCP_HLT;
+        cs->exception_index = EXCP_HLT;
         cpu->env.storage_keys = storage_keys;
     }
 }
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index d000a5e..6801968 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -138,9 +138,6 @@  typedef struct CPUWatchpoint {
     QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
     CPUWatchpoint *watchpoint_hit;                                      \
                                                                         \
-    /* Core interrupt code */                                           \
-    int exception_index;                                                \
-                                                                        \
     /* user data */                                                     \
     void *opaque;                                                       \
                                                                         \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 288ffa9..8191a80 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -249,6 +249,7 @@  struct CPUState {
         icount_decr_u16 u16;
     } icount_decr;
     uint32_t can_do_io;
+    int32_t exception_index; /* used by m68k TCG */
 };
 
 QTAILQ_HEAD(CPUTailQ, CPUState);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 23d65da..6e51519 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -773,8 +773,9 @@  static int
 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
 		 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
 {
-	int err = 0;
-        uint16_t magic;
+    CPUState *cs = CPU(x86_env_get_cpu(env));
+    int err = 0;
+    uint16_t magic;
 
 	/* already locked in setup_frame() */
 	err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
@@ -789,7 +790,7 @@  setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
 	err |= __put_user(env->regs[R_EDX], &sc->edx);
 	err |= __put_user(env->regs[R_ECX], &sc->ecx);
 	err |= __put_user(env->regs[R_EAX], &sc->eax);
-	err |= __put_user(env->exception_index, &sc->trapno);
+    err |= __put_user(cs->exception_index, &sc->trapno);
 	err |= __put_user(env->error_code, &sc->err);
 	err |= __put_user(env->eip, &sc->eip);
 	err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index ef2dc25..6f103ec 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -173,7 +173,7 @@  int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
 
-    cpu->env.exception_index = EXCP_MMFAULT;
+    cs->exception_index = EXCP_MMFAULT;
     cpu->env.trap_arg0 = address;
     return 1;
 }
@@ -337,7 +337,7 @@  int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw,
 
     fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot);
     if (unlikely(fail >= 0)) {
-        env->exception_index = EXCP_MMFAULT;
+        cs->exception_index = EXCP_MMFAULT;
         env->trap_arg0 = addr;
         env->trap_arg1 = fail;
         env->trap_arg2 = (rw == 2 ? -1 : rw);
@@ -354,7 +354,7 @@  void alpha_cpu_do_interrupt(CPUState *cs)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
-    int i = env->exception_index;
+    int i = cs->exception_index;
 
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         static int count;
@@ -405,7 +405,7 @@  void alpha_cpu_do_interrupt(CPUState *cs)
                  ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
     }
 
-    env->exception_index = -1;
+    cs->exception_index = -1;
 
 #if !defined(CONFIG_USER_ONLY)
     switch (i) {
@@ -507,7 +507,10 @@  void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
    We expect that ENV->PC has already been updated.  */
 void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
 {
-    env->exception_index = excp;
+    AlphaCPU *cpu = alpha_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = excp;
     env->error_code = error;
     cpu_loop_exit(env);
 }
@@ -516,7 +519,10 @@  void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, uintptr_t retaddr,
                                 int excp, int error)
 {
-    env->exception_index = excp;
+    AlphaCPU *cpu = alpha_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = excp;
     env->error_code = error;
     if (retaddr) {
         cpu_restore_state(env, retaddr);
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index d140688..22fcbe1 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -91,6 +91,8 @@  uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
 static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
                                 int is_write, int is_user, uintptr_t retaddr)
 {
+    AlphaCPU *cpu = alpha_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     uint64_t pc;
     uint32_t insn;
 
@@ -104,7 +106,7 @@  static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
     env->trap_arg0 = addr;
     env->trap_arg1 = insn >> 26;                /* opcode */
     env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
-    env->exception_index = EXCP_UNALIGN;
+    cs->exception_index = EXCP_UNALIGN;
     env->error_code = 0;
     cpu_loop_exit(env);
 }
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 9d0d8b4..508a7fc 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2072,10 +2072,7 @@  uint32_t HELPER(rbit)(uint32_t x)
 
 void arm_cpu_do_interrupt(CPUState *cs)
 {
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
 
 int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
@@ -2085,10 +2082,10 @@  int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
     CPUARMState *env = &cpu->env;
 
     if (rw == 2) {
-        env->exception_index = EXCP_PREFETCH_ABORT;
+        cs->exception_index = EXCP_PREFETCH_ABORT;
         env->cp15.c6_insn = address;
     } else {
-        env->exception_index = EXCP_DATA_ABORT;
+        cs->exception_index = EXCP_DATA_ABORT;
         env->cp15.c6_data = address;
     }
     return 1;
@@ -2270,7 +2267,7 @@  void arm_v7m_cpu_do_interrupt(CPUState *cs)
     uint32_t lr;
     uint32_t addr;
 
-    arm_log_exception(env->exception_index);
+    arm_log_exception(cs->exception_index);
 
     lr = 0xfffffff1;
     if (env->v7m.current_sp)
@@ -2282,7 +2279,7 @@  void arm_v7m_cpu_do_interrupt(CPUState *cs)
        handle it.  */
     /* TODO: Need to escalate if the current priority is higher than the
        one we're raising.  */
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_UDEF:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
         return;
@@ -2314,7 +2311,7 @@  void arm_v7m_cpu_do_interrupt(CPUState *cs)
         do_v7m_exception_exit(env);
         return;
     default:
-        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
         return; /* Never happens.  Keep compiler happy.  */
     }
 
@@ -2355,10 +2352,10 @@  void arm_cpu_do_interrupt(CPUState *cs)
 
     assert(!IS_M(env));
 
-    arm_log_exception(env->exception_index);
+    arm_log_exception(cs->exception_index);
 
     /* TODO: Vectored interrupt controller.  */
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_UDEF:
         new_mode = ARM_CPU_MODE_UND;
         addr = 0x04;
@@ -2439,7 +2436,7 @@  void arm_cpu_do_interrupt(CPUState *cs)
         offset = 4;
         break;
     default:
-        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
         return; /* Never happens.  Keep compiler happy.  */
     }
     /* High vectors.  */
@@ -3053,13 +3050,13 @@  int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
     if (access_type == 2) {
         env->cp15.c5_insn = ret;
         env->cp15.c6_insn = address;
-        env->exception_index = EXCP_PREFETCH_ABORT;
+        cs->exception_index = EXCP_PREFETCH_ABORT;
     } else {
         env->cp15.c5_data = ret;
         if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
             env->cp15.c5_data |= (1 << 11);
         env->cp15.c6_data = address;
-        env->exception_index = EXCP_DATA_ABORT;
+        cs->exception_index = EXCP_DATA_ABORT;
     }
     return 1;
 }
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 13d34fb..2c2b3b7 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -24,7 +24,10 @@ 
 
 static void raise_exception(CPUARMState *env, int tt)
 {
-    env->exception_index = tt;
+    ARMCPU *cpu = arm_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = tt;
     cpu_loop_exit(env);
 }
 
@@ -75,15 +78,16 @@  void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     int ret;
 
-    ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
+    ret = arm_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
             cpu_restore_state(env, retaddr);
         }
-        raise_exception(env, env->exception_index);
+        raise_exception(env, cs->exception_index);
     }
 }
 #endif
@@ -221,14 +225,16 @@  void HELPER(wfi)(CPUARMState *env)
 {
     CPUState *cs = CPU(arm_env_get_cpu(env));
 
-    env->exception_index = EXCP_HLT;
+    cs->exception_index = EXCP_HLT;
     cs->halted = 1;
     cpu_loop_exit(env);
 }
 
 void HELPER(exception)(CPUARMState *env, uint32_t excp)
 {
-    env->exception_index = excp;
+    CPUState *cs = CPU(arm_env_get_cpu(env));
+
+    cs->exception_index = excp;
     cpu_loop_exit(env);
 }
 
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 72dc839..3c4501c 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -41,7 +41,7 @@  void cris_cpu_do_interrupt(CPUState *cs)
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
 
-    env->exception_index = -1;
+    cs->exception_index = -1;
     env->pregs[PR_ERP] = env->pc;
 }
 
@@ -55,7 +55,7 @@  int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 {
     CRISCPU *cpu = CRIS_CPU(cs);
 
-    cpu->env.exception_index = 0xaa;
+    cs->exception_index = 0xaa;
     cpu->env.pregs[PR_EDA] = address;
     cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
@@ -88,7 +88,7 @@  int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
     miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
                               rw, mmu_idx, 0);
     if (miss) {
-        if (env->exception_index == EXCP_BUSFAULT) {
+        if (cs->exception_index == EXCP_BUSFAULT) {
             cpu_abort(env,
                       "CRIS: Illegal recursive bus fault."
                       "addr=%" VADDR_PRIx " rw=%d\n",
@@ -96,7 +96,7 @@  int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
         }
 
         env->pregs[PR_EDA] = address;
-        env->exception_index = EXCP_BUSFAULT;
+        cs->exception_index = EXCP_BUSFAULT;
         env->fault_vector = res.bf_vec;
         r = 1;
     } else {
@@ -125,11 +125,11 @@  void crisv10_cpu_do_interrupt(CPUState *cs)
     int ex_vec = -1;
 
     D_LOG("exception index=%d interrupt_req=%d\n",
-          env->exception_index,
+          cs->exception_index,
           cs->interrupt_request);
 
     assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_BREAK:
         /* These exceptions are genereated by the core itself.
            ERP should point to the insn following the brk.  */
@@ -182,10 +182,10 @@  void cris_cpu_do_interrupt(CPUState *cs)
     int ex_vec = -1;
 
     D_LOG("exception index=%d interrupt_req=%d\n",
-          env->exception_index,
+          cs->exception_index,
           cs->interrupt_request);
 
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_BREAK:
         /* These exceptions are genereated by the core itself.
            ERP should point to the insn following the brk.  */
@@ -248,7 +248,7 @@  void cris_cpu_do_interrupt(CPUState *cs)
 
     /* Clear the excption_index to avoid spurios hw_aborts for recursive
        bus faults.  */
-    env->exception_index = -1;
+    cs->exception_index = -1;
 
     D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
           __func__, env->pc, ex_vec,
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 4a6215d..9b20b94 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -79,8 +79,10 @@  void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
 
 void helper_raise_exception(CPUCRISState *env, uint32_t index)
 {
-	env->exception_index = index;
-        cpu_loop_exit(env);
+    CPUState *cs = CPU(cris_env_get_cpu(env));
+
+    cs->exception_index = index;
+    cpu_loop_exit(env);
 }
 
 void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c
index 5319aef..ec76eba 100644
--- a/target-i386/excp_helper.c
+++ b/target-i386/excp_helper.c
@@ -94,6 +94,8 @@  static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
                                            int is_int, int error_code,
                                            int next_eip_addend)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
+
     if (!is_int) {
         cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
                                       error_code);
@@ -102,7 +104,7 @@  static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
         cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0);
     }
 
-    env->exception_index = intno;
+    cs->exception_index = intno;
     env->error_code = error_code;
     env->exception_is_int = is_int;
     env->exception_next_eip = env->eip + next_eip_addend;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 8c2ad94..864d9f8 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -496,7 +496,7 @@  int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
     env->cr[2] = addr;
     env->error_code = (is_write << PG_ERROR_W_BIT);
     env->error_code |= PG_ERROR_U_MASK;
-    env->exception_index = EXCP0E_PAGE;
+    cs->exception_index = EXCP0E_PAGE;
     return 1;
 }
 
@@ -555,7 +555,7 @@  int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
             sext = (int64_t)addr >> 47;
             if (sext != 0 && sext != -1) {
                 env->error_code = 0;
-                env->exception_index = EXCP0D_GPF;
+                cs->exception_index = EXCP0D_GPF;
                 return 1;
             }
 
@@ -885,7 +885,7 @@  int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
         env->cr[2] = addr;
     }
     env->error_code = error_code;
-    env->exception_index = EXCP0E_PAGE;
+    cs->exception_index = EXCP0E_PAGE;
     return 1;
 }
 
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 5b25ccd..c0d3b45 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -136,15 +136,16 @@  void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
     X86CPU *cpu = x86_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     int ret;
 
-    ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
+    ret = x86_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
             cpu_restore_state(env, retaddr);
         }
-        raise_exception_err(env, env->exception_index, env->error_code);
+        raise_exception_err(env, cs->exception_index, env->error_code);
     }
 }
 #endif
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 93933fd..a058c43 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -573,7 +573,7 @@  static void do_hlt(X86CPU *cpu)
 
     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
     cs->halted = 1;
-    env->exception_index = EXCP_HLT;
+    cs->exception_index = EXCP_HLT;
     cpu_loop_exit(env);
 }
 
@@ -620,6 +620,8 @@  void helper_mwait(CPUX86State *env, int next_eip_addend)
 
 void helper_debug(CPUX86State *env)
 {
-    env->exception_index = EXCP_DEBUG;
+    CPUState *cs = CPU(x86_env_get_cpu(env));
+
+    cs->exception_index = EXCP_DEBUG;
     cpu_loop_exit(env);
 }
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index e789102..b689e94 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -935,7 +935,9 @@  static void do_interrupt64(CPUX86State *env, int intno, int is_int,
 #if defined(CONFIG_USER_ONLY)
 void helper_syscall(CPUX86State *env, int next_eip_addend)
 {
-    env->exception_index = EXCP_SYSCALL;
+    CPUState *cs = CPU(x86_env_get_cpu(env));
+
+    cs->exception_index = EXCP_SYSCALL;
     env->exception_next_eip = env->eip + next_eip_addend;
     cpu_loop_exit(env);
 }
@@ -1244,7 +1246,7 @@  void x86_cpu_do_interrupt(CPUState *cs)
     /* if user mode only, we simulate a fake exception
        which will be handled outside the cpu execution
        loop */
-    do_interrupt_user(env, env->exception_index,
+    do_interrupt_user(env, cs->exception_index,
                       env->exception_is_int,
                       env->error_code,
                       env->exception_next_eip);
@@ -1254,7 +1256,7 @@  void x86_cpu_do_interrupt(CPUState *cs)
     /* simulate a real cpu exception. On i386, it can
        trigger new exceptions, but we do not handle
        double or triple faults yet. */
-    do_interrupt_all(cpu, env->exception_index,
+    do_interrupt_all(cpu, cs->exception_index,
                      env->exception_is_int,
                      env->error_code,
                      env->exception_next_eip, 0);
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 4a7de42..3c12cb8 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -122,6 +122,7 @@  static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
 
 void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     target_ulong addr;
     uint32_t event_inj;
     uint32_t int_ctl;
@@ -290,7 +291,7 @@  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
         /* FIXME: need to implement valid_err */
         switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
         case SVM_EVTINJ_TYPE_INTR:
-            env->exception_index = vector;
+            cs->exception_index = vector;
             env->error_code = event_inj_err;
             env->exception_is_int = 0;
             env->exception_next_eip = -1;
@@ -299,7 +300,7 @@  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             do_interrupt_x86_hardirq(env, vector, 1);
             break;
         case SVM_EVTINJ_TYPE_NMI:
-            env->exception_index = EXCP02_NMI;
+            cs->exception_index = EXCP02_NMI;
             env->error_code = event_inj_err;
             env->exception_is_int = 0;
             env->exception_next_eip = env->eip;
@@ -307,7 +308,7 @@  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             cpu_loop_exit(env);
             break;
         case SVM_EVTINJ_TYPE_EXEPT:
-            env->exception_index = vector;
+            cs->exception_index = vector;
             env->error_code = event_inj_err;
             env->exception_is_int = 0;
             env->exception_next_eip = -1;
@@ -315,7 +316,7 @@  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             cpu_loop_exit(env);
             break;
         case SVM_EVTINJ_TYPE_SOFT:
-            env->exception_index = vector;
+            cs->exception_index = vector;
             env->error_code = event_inj_err;
             env->exception_is_int = 1;
             env->exception_next_eip = env->eip;
@@ -323,7 +324,7 @@  void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             cpu_loop_exit(env);
             break;
         }
-        qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index,
+        qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", cs->exception_index,
                       env->error_code);
     }
 }
@@ -705,7 +706,7 @@  void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
        #GP fault is delivered inside the host. */
 
     /* remove any pending exception */
-    env->exception_index = -1;
+    cs->exception_index = -1;
     env->error_code = 0;
     env->old_exception = -1;
 
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 55a3de6..b2093a8 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -57,9 +57,9 @@  void lm32_cpu_do_interrupt(CPUState *cs)
     CPULM32State *env = &cpu->env;
 
     qemu_log_mask(CPU_LOG_INT,
-            "exception at pc=%x type=%x\n", env->pc, env->exception_index);
+            "exception at pc=%x type=%x\n", env->pc, cs->exception_index);
 
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_INSN_BUS_ERROR:
     case EXCP_DATA_BUS_ERROR:
     case EXCP_DIVIDE_BY_ZERO:
@@ -70,9 +70,9 @@  void lm32_cpu_do_interrupt(CPUState *cs)
         env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
         env->ie &= ~IE_IE;
         if (env->dc & DC_RE) {
-            env->pc = env->deba + (env->exception_index * 32);
+            env->pc = env->deba + (cs->exception_index * 32);
         } else {
-            env->pc = env->eba + (env->exception_index * 32);
+            env->pc = env->eba + (cs->exception_index * 32);
         }
         log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
@@ -82,12 +82,12 @@  void lm32_cpu_do_interrupt(CPUState *cs)
         env->regs[R_BA] = env->pc;
         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
         env->ie &= ~IE_IE;
-        env->pc = env->deba + (env->exception_index * 32);
+        env->pc = env->deba + (cs->exception_index * 32);
         log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
     default:
         cpu_abort(env, "unhandled exception type=%d\n",
-                  env->exception_index);
+                  cs->exception_index);
         break;
     }
 }
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 215215e..c7ad910 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -21,7 +21,9 @@ 
 
 void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
 {
-    env->exception_index = index;
+    CPUState *cs = CPU(lm32_env_get_cpu(env));
+
+    cs->exception_index = index;
     cpu_loop_exit(env);
 }
 
@@ -30,7 +32,7 @@  void HELPER(hlt)(CPULM32State *env)
     CPUState *cs = CPU(lm32_env_get_cpu(env));
 
     cs->halted = 1;
-    env->exception_index = EXCP_HLT;
+    cs->exception_index = EXCP_HLT;
     cpu_loop_exit(env);
 }
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 25a0570..003a298 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -283,7 +283,7 @@  int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 {
     M68kCPU *cpu = M68K_CPU(cs);
 
-    cpu->env.exception_index = EXCP_ACCESS;
+    cs->exception_index = EXCP_ACCESS;
     cpu->env.mmu.ar = address;
     return 1;
 }
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index bc10f38..466ad0c 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -23,10 +23,7 @@ 
 
 void m68k_cpu_do_interrupt(CPUState *cs)
 {
-    M68kCPU *cpu = M68K_CPU(cs);
-    CPUM68KState *env = &cpu->env;
-
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
 
 void do_interrupt_m68k_hardirq(CPUM68KState *env)
@@ -88,7 +85,7 @@  static void do_rte(CPUM68KState *env)
 
 static void do_interrupt_all(CPUM68KState *env, int is_hw)
 {
-    CPUState *cs;
+    CPUState *cs = CPU(m68k_env_get_cpu(env));
     uint32_t sp;
     uint32_t fmt;
     uint32_t retaddr;
@@ -98,7 +95,7 @@  static void do_interrupt_all(CPUM68KState *env, int is_hw)
     retaddr = env->pc;
 
     if (!is_hw) {
-        switch (env->exception_index) {
+        switch (cs->exception_index) {
         case EXCP_RTE:
             /* Return from an exception.  */
             do_rte(env);
@@ -113,20 +110,19 @@  static void do_interrupt_all(CPUM68KState *env, int is_hw)
                 do_m68k_semihosting(env, env->dregs[0]);
                 return;
             }
-            cs = CPU(m68k_env_get_cpu(env));
             cs->halted = 1;
-            env->exception_index = EXCP_HLT;
+            cs->exception_index = EXCP_HLT;
             cpu_loop_exit(env);
             return;
         }
-        if (env->exception_index >= EXCP_TRAP0
-            && env->exception_index <= EXCP_TRAP15) {
+        if (cs->exception_index >= EXCP_TRAP0
+            && cs->exception_index <= EXCP_TRAP15) {
             /* Move the PC after the trap instruction.  */
             retaddr += 2;
         }
     }
 
-    vector = env->exception_index << 2;
+    vector = cs->exception_index << 2;
 
     sp = env->aregs[7];
 
@@ -169,7 +165,9 @@  void do_interrupt_m68k_hardirq(CPUM68KState *env)
 
 static void raise_exception(CPUM68KState *env, int tt)
 {
-    env->exception_index = tt;
+    CPUState *cs = CPU(m68k_env_get_cpu(env));
+
+    cs->exception_index = tt;
     cpu_loop_exit(env);
 }
 
diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def
index 4235b02..204663e 100644
--- a/target-m68k/qregs.def
+++ b/target-m68k/qregs.def
@@ -7,6 +7,5 @@  DEFO32(CC_SRC, cc_src)
 DEFO32(CC_X, cc_x)
 DEFO32(DIV1, div1)
 DEFO32(DIV2, div2)
-DEFO32(EXCEPTION, exception_index)
 DEFO32(MACSR, macsr)
 DEFO32(MAC_MASK, mac_mask)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0be0a96..f3cdee0 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -43,6 +43,7 @@ 
 #undef DEFF64
 
 static TCGv_i32 cpu_halted;
+static TCGv_i32 cpu_exception_index;
 
 static TCGv_ptr cpu_env;
 
@@ -81,6 +82,10 @@  void m68k_tcg_init(void)
     cpu_halted = tcg_global_mem_new_i32(TCG_AREG0,
                                         -offsetof(M68kCPU, env) +
                                         offsetof(CPUState, halted), "HALTED");
+    cpu_exception_index = tcg_global_mem_new_i32(TCG_AREG0,
+                                                 -offsetof(M68kCPU, env) +
+                                                 offsetof(CPUState, exception_index),
+                                                 "EXCEPTION");
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index d03f369..4825415 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -31,7 +31,7 @@  void mb_cpu_do_interrupt(CPUState *cs)
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
 
-    env->exception_index = -1;
+    cs->exception_index = -1;
     env->res_addr = RES_ADDR_NONE;
     env->regs[14] = env->sregs[SR_PC];
 }
@@ -39,9 +39,7 @@  void mb_cpu_do_interrupt(CPUState *cs)
 int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                             int mmu_idx)
 {
-    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
-
-    cpu->env.exception_index = 0xaa;
+    cs->exception_index = 0xaa;
     cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
 }
@@ -99,12 +97,12 @@  int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                     break;
             }
 
-            if (env->exception_index == EXCP_MMU) {
+            if (cs->exception_index == EXCP_MMU) {
                 cpu_abort(env, "recursive faults\n");
             }
 
             /* TLB miss.  */
-            env->exception_index = EXCP_MMU;
+            cs->exception_index = EXCP_MMU;
         }
     } else {
         /* MMU disabled or not available.  */
@@ -127,7 +125,7 @@  void mb_cpu_do_interrupt(CPUState *cs)
     assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
 /*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
     env->res_addr = RES_ADDR_NONE;
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
         case EXCP_HW_EXCP:
             if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
                 qemu_log("Exception raised on system without exceptions!\n");
@@ -253,7 +251,7 @@  void mb_cpu_do_interrupt(CPUState *cs)
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->sregs[SR_MSR] |= t;
             env->sregs[SR_MSR] |= MSR_BIP;
-            if (env->exception_index == EXCP_HW_BREAK) {
+            if (cs->exception_index == EXCP_HW_BREAK) {
                 env->regs[16] = env->sregs[SR_PC];
                 env->sregs[SR_MSR] |= MSR_BIP;
                 env->sregs[SR_PC] = cpu->base_vectors + 0x18;
@@ -262,7 +260,7 @@  void mb_cpu_do_interrupt(CPUState *cs)
             break;
         default:
             cpu_abort(env, "unhandled exception type=%d\n",
-                      env->exception_index);
+                      cs->exception_index);
             break;
     }
 }
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index b70b2ea..318185a 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -95,7 +95,9 @@  uint32_t helper_get(uint32_t id, uint32_t ctrl)
 
 void helper_raise_exception(CPUMBState *env, uint32_t index)
 {
-    env->exception_index = index;
+    CPUState *cs = CPU(mb_env_get_cpu(env));
+
+    cs->exception_index = index;
     cpu_loop_exit(env);
 }
 
diff --git a/target-mips/helper.c b/target-mips/helper.c
index d8e9166..698c3d1 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -204,6 +204,7 @@  static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
 static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
                                 int rw, int tlb_error)
 {
+    CPUState *cs = CPU(mips_env_get_cpu(env));
     int exception = 0, error_code = 0;
 
     switch (tlb_error) {
@@ -249,7 +250,7 @@  static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
                         ((address & 0xC00000000000ULL) >> (55 - env->SEGBITS)) |
                         ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
 #endif
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
 }
 
@@ -404,27 +405,29 @@  static void set_hflags_for_handler (CPUMIPSState *env)
 
 void mips_cpu_do_interrupt(CPUState *cs)
 {
+#if !defined(CONFIG_USER_ONLY)
     MIPSCPU *cpu = MIPS_CPU(cs);
     CPUMIPSState *env = &cpu->env;
-#if !defined(CONFIG_USER_ONLY)
     target_ulong offset;
     int cause = -1;
     const char *name;
 
-    if (qemu_log_enabled() && env->exception_index != EXCP_EXT_INTERRUPT) {
-        if (env->exception_index < 0 || env->exception_index > EXCP_LAST)
+    if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) {
+        if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) {
             name = "unknown";
-        else
-            name = excp_names[env->exception_index];
+        } else {
+            name = excp_names[cs->exception_index];
+        }
 
         qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n",
                  __func__, env->active_tc.PC, env->CP0_EPC, name);
     }
-    if (env->exception_index == EXCP_EXT_INTERRUPT &&
-        (env->hflags & MIPS_HFLAG_DM))
-        env->exception_index = EXCP_DINT;
+    if (cs->exception_index == EXCP_EXT_INTERRUPT &&
+        (env->hflags & MIPS_HFLAG_DM)) {
+        cs->exception_index = EXCP_DINT;
+    }
     offset = 0x180;
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_DSS:
         env->CP0_Debug |= 1 << CP0DB_DSS;
         /* Debug single step cannot be raised inside a delay slot and
@@ -632,11 +635,11 @@  void mips_cpu_do_interrupt(CPUState *cs)
         env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
         break;
     default:
-        qemu_log("Invalid MIPS exception %d. Exiting\n", env->exception_index);
-        printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
+        qemu_log("Invalid MIPS exception %d. Exiting\n", cs->exception_index);
+        printf("Invalid MIPS exception %d. Exiting\n", cs->exception_index);
         exit(1);
     }
-    if (qemu_log_enabled() && env->exception_index != EXCP_EXT_INTERRUPT) {
+    if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) {
         qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n"
                 "    S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
                 __func__, env->active_tc.PC, env->CP0_EPC, cause,
@@ -644,7 +647,7 @@  void mips_cpu_do_interrupt(CPUState *cs)
                 env->CP0_DEPC);
     }
 #endif
-    env->exception_index = EXCP_NONE;
+    cs->exception_index = EXCP_NONE;
 }
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 34ac4c6..eeb98a6 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -38,10 +38,12 @@  static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
                                                         int error_code,
                                                         uintptr_t pc)
 {
+    CPUState *cs = CPU(mips_env_get_cpu(env));
+
     if (exception < EXCP_SC) {
         qemu_log("%s: %d %d\n", __func__, exception, error_code);
     }
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
 
     if (pc) {
@@ -2135,11 +2137,12 @@  void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
     MIPSCPU *cpu = mips_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     int ret;
 
-    ret = mips_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
+    ret = mips_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
-        do_raise_exception_err(env, env->exception_index,
+        do_raise_exception_err(env, cs->exception_index,
                                env->error_code, retaddr);
     }
 }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index ad43d59..716d50c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15922,10 +15922,8 @@  MIPSCPU *cpu_mips_init(const char *cpu_model)
 
 void cpu_state_reset(CPUMIPSState *env)
 {
-#ifndef CONFIG_USER_ONLY
     MIPSCPU *cpu = mips_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
-#endif
 
     /* Reset registers to their default values */
     env->CP0_PRid = env->cpu_model->CP0_PRid;
@@ -16049,7 +16047,7 @@  void cpu_state_reset(CPUMIPSState *env)
     }
 #endif
     compute_hflags(env);
-    env->exception_index = EXCP_NONE;
+    cs->exception_index = EXCP_NONE;
 }
 
 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 8160475..3b14f37 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -63,7 +63,9 @@  void tlb_fill(CPUMoxieState *env, target_ulong addr, int is_write, int mmu_idx,
 
 void helper_raise_exception(CPUMoxieState *env, int ex)
 {
-    env->exception_index = ex;
+    CPUState *cs = CPU(moxie_env_get_cpu(env));
+
+    cs->exception_index = ex;
     /* Stash the exception type.  */
     env->sregs[2] = ex;
     /* Stash the address where the exception occurred.  */
@@ -98,7 +100,9 @@  uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
 
 void helper_debug(CPUMoxieState *env)
 {
-    env->exception_index = EXCP_DEBUG;
+    CPUState *cs = CPU(moxie_env_get_cpu(env));
+
+    cs->exception_index = EXCP_DEBUG;
     cpu_loop_exit(env);
 }
 
@@ -106,7 +110,9 @@  void helper_debug(CPUMoxieState *env)
 
 void moxie_cpu_do_interrupt(CPUState *cs)
 {
-    env->exception_index = -1;
+    CPUState *cs = CPU(moxie_env_get_cpu(env));
+
+    cs->exception_index = -1;
 }
 
 int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
@@ -114,7 +120,7 @@  int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 {
     MoxieCPU *cpu = MOXIE_CPU(cs);
 
-    cpu->env.exception_index = 0xaa;
+    cs->exception_index = 0xaa;
     cpu->env.debug1 = address;
     cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
@@ -138,7 +144,7 @@  int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
     if (miss) {
         /* handle the miss.  */
         phy = 0;
-        env->exception_index = MOXIE_EX_MMU_MISS;
+        cs->exception_index = MOXIE_EX_MMU_MISS;
     } else {
         phy = res.phy;
         r = 0;
@@ -150,10 +156,7 @@  int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 
 void moxie_cpu_do_interrupt(CPUState *cs)
 {
-    MoxieCPU *cpu = MOXIE_CPU(cs);
-    CPUMoxieState *env = &cpu->env;
-
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case MOXIE_EX_BREAK:
         break;
     default:
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index ee1591d..b233969 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -69,7 +69,7 @@  static void openrisc_cpu_reset(CPUState *s)
 
     cpu->env.pc = 0x100;
     cpu->env.sr = SR_FO | SR_SM;
-    cpu->env.exception_index = -1;
+    s->exception_index = -1;
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
     cpu->env.cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S;
diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 58e53c6..b96f3f8 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -22,6 +22,8 @@ 
 
 void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
 {
-    cpu->env.exception_index = excp;
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = excp;
     cpu_loop_exit(&cpu->env);
 }
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 16ef4b3..64f2ca6 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -27,25 +27,26 @@ 
 
 void openrisc_cpu_do_interrupt(CPUState *cs)
 {
+#ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
-#ifndef CONFIG_USER_ONLY
+
     if (env->flags & D_FLAG) { /* Delay Slot insn */
         env->flags &= ~D_FLAG;
         env->sr |= SR_DSX;
-        if (env->exception_index == EXCP_TICK    ||
-            env->exception_index == EXCP_INT     ||
-            env->exception_index == EXCP_SYSCALL ||
-            env->exception_index == EXCP_FPE) {
+        if (cs->exception_index == EXCP_TICK    ||
+            cs->exception_index == EXCP_INT     ||
+            cs->exception_index == EXCP_SYSCALL ||
+            cs->exception_index == EXCP_FPE) {
             env->epcr = env->jmp_pc;
         } else {
             env->epcr = env->pc - 4;
         }
     } else {
-        if (env->exception_index == EXCP_TICK    ||
-            env->exception_index == EXCP_INT     ||
-            env->exception_index == EXCP_SYSCALL ||
-            env->exception_index == EXCP_FPE) {
+        if (cs->exception_index == EXCP_TICK    ||
+            cs->exception_index == EXCP_INT     ||
+            cs->exception_index == EXCP_SYSCALL ||
+            cs->exception_index == EXCP_FPE) {
             env->epcr = env->npc;
         } else {
             env->epcr = env->pc;
@@ -65,12 +66,12 @@  void openrisc_cpu_do_interrupt(CPUState *cs)
     env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
     env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
 
-    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
-        env->pc = (env->exception_index << 8);
+    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
+        env->pc = (cs->exception_index << 8);
     } else {
-        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
     }
 #endif
 
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index 0f13c5d..b1830da 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -146,6 +146,7 @@  static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
                                              target_ulong address,
                                              int rw, int tlb_error)
 {
+    CPUState *cs = CPU(cpu);
     int exception = 0;
 
     switch (tlb_error) {
@@ -176,7 +177,7 @@  static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
 #endif
     }
 
-    cpu->env.exception_index = exception;
+    cs->exception_index = exception;
     cpu->env.eear = address;
 }
 
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index c959460..0ec2615 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -43,13 +43,15 @@  void ppc_cpu_do_interrupt(CPUState *cs)
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
 
-    env->exception_index = POWERPC_EXCP_NONE;
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 
 void ppc_hw_interrupt(CPUPPCState *env)
 {
-    env->exception_index = POWERPC_EXCP_NONE;
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 #else /* defined(CONFIG_USER_ONLY) */
@@ -68,8 +70,8 @@  static inline void dump_syscall(CPUPPCState *env)
  */
 static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
 {
+    CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    CPUState *cs;
     target_ulong msr, new_msr, vector;
     int srr0, srr1, asrr0, asrr1;
     int lpes0, lpes1, lev;
@@ -135,7 +137,6 @@  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 fprintf(stderr, "Machine check while not allowed. "
                         "Entering checkstop state\n");
             }
-            cs = CPU(cpu);
             cs->halted = 1;
             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
@@ -202,7 +203,7 @@  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         case POWERPC_EXCP_FP:
             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
                 LOG_EXCP("Ignore floating point exception\n");
-                env->exception_index = POWERPC_EXCP_NONE;
+                cs->exception_index = POWERPC_EXCP_NONE;
                 env->error_code = 0;
                 return;
             }
@@ -655,7 +656,7 @@  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     hreg_compute_hflags(env);
     env->nip = vector;
     /* Reset exception state */
-    env->exception_index = POWERPC_EXCP_NONE;
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 
     if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
@@ -672,7 +673,7 @@  void ppc_cpu_do_interrupt(CPUState *cs)
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
 
-    powerpc_excp(cpu, env->excp_model, env->exception_index);
+    powerpc_excp(cpu, env->excp_model, cs->exception_index);
 }
 
 void ppc_hw_interrupt(CPUPPCState *env)
@@ -808,10 +809,12 @@  static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
                                 uint32_t error_code)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
 #if 0
     printf("Raise exception %3x code : %d\n", exception, error_code);
 #endif
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
     cpu_loop_exit(env);
 }
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 4f60218..314e66f 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -108,6 +108,7 @@  uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf)
 /* Floating-point invalid operations exception */
 static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     uint64_t ret = 0;
     int ve;
 
@@ -142,7 +143,7 @@  static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
         env->fpscr |= 0x11 << FPSCR_FPCC;
         /* We must update the target FPR before raising the exception */
         if (ve != 0) {
-            env->exception_index = POWERPC_EXCP_PROGRAM;
+            cs->exception_index = POWERPC_EXCP_PROGRAM;
             env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
             /* Update the floating-point enabled exception summary */
             env->fpscr |= 1 << FPSCR_FEX;
@@ -207,6 +208,8 @@  static inline void float_zero_divide_excp(CPUPPCState *env)
 
 static inline void float_overflow_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_OX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -215,7 +218,7 @@  static inline void float_overflow_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
     } else {
         env->fpscr |= 1 << FPSCR_XX;
@@ -225,6 +228,8 @@  static inline void float_overflow_excp(CPUPPCState *env)
 
 static inline void float_underflow_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_UX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -233,13 +238,15 @@  static inline void float_underflow_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
     }
 }
 
 static inline void float_inexact_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_XX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -247,7 +254,7 @@  static inline void float_inexact_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
     }
 }
@@ -299,6 +306,7 @@  void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
 
 void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int prev;
 
     prev = (env->fpscr >> bit) & 1;
@@ -422,7 +430,7 @@  void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
             /* Update the floating-point enabled exception summary */
             env->fpscr |= 1 << FPSCR_FEX;
             /* We have to update Rc1 before raising the exception */
-            env->exception_index = POWERPC_EXCP_PROGRAM;
+            cs->exception_index = POWERPC_EXCP_PROGRAM;
             break;
         }
     }
@@ -430,6 +438,7 @@  void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
 
 void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     target_ulong prev, new;
     int i;
 
@@ -451,7 +460,7 @@  void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
     }
     if ((fpscr_ex & fpscr_eex) != 0) {
         env->fpscr |= 1 << FPSCR_FEX;
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         /* XXX: we should compute it properly */
         env->error_code = POWERPC_EXCP_FP;
     } else {
@@ -467,6 +476,7 @@  void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
 
 void helper_float_check_status(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int status = get_float_exception_flags(&env->fp_status);
 
     if (status & float_flag_divbyzero) {
@@ -479,11 +489,11 @@  void helper_float_check_status(CPUPPCState *env)
         float_inexact_excp(env);
     }
 
-    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
+    if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
         (env->error_code & POWERPC_EXCP_FP)) {
         /* Differred floating-point exception after target FPR update */
         if (msr_fe0 != 0 || msr_fe1 != 0) {
-            helper_raise_exception_err(env, env->exception_index,
+            helper_raise_exception_err(env, cs->exception_index,
                                        env->error_code);
         }
     }
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 6a77dc4..aa87084 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -222,6 +222,7 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
                                    target_ulong eaddr, int rwx,
                                    hwaddr *raddr, int *prot)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
 
     LOG_MMU("direct store...\n");
@@ -238,7 +239,7 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
 
     if (rwx == 2) {
         /* No code fetch is allowed in direct-store areas */
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -249,7 +250,7 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         break;
     case ACCESS_FLOAT:
         /* Floating point load/store */
-        env->exception_index = POWERPC_EXCP_ALIGN;
+        cs->exception_index = POWERPC_EXCP_ALIGN;
         env->error_code = POWERPC_EXCP_ALIGN_FP;
         env->spr[SPR_DAR] = eaddr;
         return 1;
@@ -272,7 +273,7 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         return 0;
     case ACCESS_EXT:
         /* eciwx or ecowx */
-        env->exception_index = POWERPC_EXCP_DSI;
+        cs->exception_index = POWERPC_EXCP_DSI;
         env->error_code = 0;
         env->spr[SPR_DAR] = eaddr;
         if (rwx == 1) {
@@ -290,7 +291,7 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         *raddr = eaddr;
         return 0;
     } else {
-        env->exception_index = POWERPC_EXCP_DSI;
+        cs->exception_index = POWERPC_EXCP_DSI;
         env->error_code = 0;
         env->spr[SPR_DAR] = eaddr;
         if (rwx == 1) {
@@ -383,6 +384,7 @@  static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
 int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
                                 int mmu_idx)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     target_ulong sr;
     hwaddr pte_offset;
     ppc_hash_pte32_t pte;
@@ -409,10 +411,10 @@  int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
         if (raddr != -1) {
             if (need_prot[rwx] & ~prot) {
                 if (rwx == 2) {
-                    env->exception_index = POWERPC_EXCP_ISI;
+                    cs->exception_index = POWERPC_EXCP_ISI;
                     env->error_code = 0x08000000;
                 } else {
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = eaddr;
                     if (rwx == 1) {
@@ -449,7 +451,7 @@  int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
 
     /* 5. Check for segment level no-execute violation */
     if ((rwx == 2) && (sr & SR32_NX)) {
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -458,10 +460,10 @@  int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
     pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte);
     if (pte_offset == -1) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x40000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
@@ -483,10 +485,10 @@  int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
         /* Access right violation */
         LOG_MMU("PTE access rejected\n");
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x08000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 67fc1b5..04dcfb3 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -399,6 +399,7 @@  static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
 int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
                                 int rwx, int mmu_idx)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     ppc_slb_t *slb;
     hwaddr pte_offset;
     ppc_hash_pte64_t pte;
@@ -425,10 +426,10 @@  int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
 
     if (!slb) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISEG;
+            cs->exception_index = POWERPC_EXCP_ISEG;
             env->error_code = 0;
         } else {
-            env->exception_index = POWERPC_EXCP_DSEG;
+            cs->exception_index = POWERPC_EXCP_DSEG;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
         }
@@ -437,7 +438,7 @@  int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
 
     /* 3. Check for segment level no-execute violation */
     if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -446,10 +447,10 @@  int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
     pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte);
     if (pte_offset == -1) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x40000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
@@ -472,12 +473,12 @@  int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
         /* Access right violation */
         LOG_MMU("PTE access rejected\n");
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x08000000;
         } else {
             target_ulong dsisr = 0;
 
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (need_prot[rwx] & ~pp_prot) {
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 04a840b..79a9134 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1491,6 +1491,7 @@  static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
 static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                                     int rw, int mmu_idx)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     mmu_ctx_t ctx;
     int access_type;
     int ret = 0;
@@ -1510,24 +1511,24 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                      mmu_idx, TARGET_PAGE_SIZE);
         ret = 0;
     } else if (ret < 0) {
-        LOG_MMU_STATE(CPU(ppc_env_get_cpu(env)));
+        LOG_MMU_STATE(cs);
         if (access_type == ACCESS_CODE) {
             switch (ret) {
             case -1:
                 /* No matches in page tables or TLB */
                 switch (env->mmu_model) {
                 case POWERPC_MMU_SOFT_6xx:
-                    env->exception_index = POWERPC_EXCP_IFTLB;
+                    cs->exception_index = POWERPC_EXCP_IFTLB;
                     env->error_code = 1 << 18;
                     env->spr[SPR_IMISS] = address;
                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
                     goto tlb_miss;
                 case POWERPC_MMU_SOFT_74xx:
-                    env->exception_index = POWERPC_EXCP_IFTLB;
+                    cs->exception_index = POWERPC_EXCP_IFTLB;
                     goto tlb_miss_74xx;
                 case POWERPC_MMU_SOFT_4xx:
                 case POWERPC_MMU_SOFT_4xx_Z:
-                    env->exception_index = POWERPC_EXCP_ITLB;
+                    cs->exception_index = POWERPC_EXCP_ITLB;
                     env->error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
                     env->spr[SPR_40x_ESR] = 0x00000000;
@@ -1536,7 +1537,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     booke206_update_mas_tlb_miss(env, address, rw);
                     /* fall through */
                 case POWERPC_MMU_BOOKE:
-                    env->exception_index = POWERPC_EXCP_ITLB;
+                    cs->exception_index = POWERPC_EXCP_ITLB;
                     env->error_code = 0;
                     env->spr[SPR_BOOKE_DEAR] = address;
                     return -1;
@@ -1555,7 +1556,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 break;
             case -2:
                 /* Access rights violation */
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x08000000;
                 break;
             case -3:
@@ -1564,13 +1565,13 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     (env->mmu_model == POWERPC_MMU_BOOKE206)) {
                     env->spr[SPR_BOOKE_ESR] = 0x00000000;
                 }
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x10000000;
                 break;
             case -4:
                 /* Direct store exception */
                 /* No code fetch is allowed in direct-store areas */
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x10000000;
                 break;
             }
@@ -1581,10 +1582,10 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 switch (env->mmu_model) {
                 case POWERPC_MMU_SOFT_6xx:
                     if (rw == 1) {
-                        env->exception_index = POWERPC_EXCP_DSTLB;
+                        cs->exception_index = POWERPC_EXCP_DSTLB;
                         env->error_code = 1 << 16;
                     } else {
-                        env->exception_index = POWERPC_EXCP_DLTLB;
+                        cs->exception_index = POWERPC_EXCP_DLTLB;
                         env->error_code = 0;
                     }
                     env->spr[SPR_DMISS] = address;
@@ -1598,9 +1599,9 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case POWERPC_MMU_SOFT_74xx:
                     if (rw == 1) {
-                        env->exception_index = POWERPC_EXCP_DSTLB;
+                        cs->exception_index = POWERPC_EXCP_DSTLB;
                     } else {
-                        env->exception_index = POWERPC_EXCP_DLTLB;
+                        cs->exception_index = POWERPC_EXCP_DLTLB;
                     }
                 tlb_miss_74xx:
                     /* Implement LRU algorithm */
@@ -1611,7 +1612,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case POWERPC_MMU_SOFT_4xx:
                 case POWERPC_MMU_SOFT_4xx_Z:
-                    env->exception_index = POWERPC_EXCP_DTLB;
+                    cs->exception_index = POWERPC_EXCP_DTLB;
                     env->error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
                     if (rw) {
@@ -1628,7 +1629,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     booke206_update_mas_tlb_miss(env, address, rw);
                     /* fall through */
                 case POWERPC_MMU_BOOKE:
-                    env->exception_index = POWERPC_EXCP_DTLB;
+                    cs->exception_index = POWERPC_EXCP_DTLB;
                     env->error_code = 0;
                     env->spr[SPR_BOOKE_DEAR] = address;
                     env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
@@ -1644,7 +1645,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 break;
             case -2:
                 /* Access rights violation */
-                env->exception_index = POWERPC_EXCP_DSI;
+                cs->exception_index = POWERPC_EXCP_DSI;
                 env->error_code = 0;
                 if (env->mmu_model == POWERPC_MMU_SOFT_4xx
                     || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
@@ -1670,13 +1671,13 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 switch (access_type) {
                 case ACCESS_FLOAT:
                     /* Floating point load/store */
-                    env->exception_index = POWERPC_EXCP_ALIGN;
+                    cs->exception_index = POWERPC_EXCP_ALIGN;
                     env->error_code = POWERPC_EXCP_ALIGN_FP;
                     env->spr[SPR_DAR] = address;
                     break;
                 case ACCESS_RES:
                     /* lwarx, ldarx or stwcx. */
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = address;
                     if (rw == 1) {
@@ -1687,7 +1688,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case ACCESS_EXT:
                     /* eciwx or ecowx */
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = address;
                     if (rw == 1) {
@@ -1698,7 +1699,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 default:
                     printf("DSI: invalid exception (%d)\n", ret);
-                    env->exception_index = POWERPC_EXCP_PROGRAM;
+                    cs->exception_index = POWERPC_EXCP_PROGRAM;
                     env->error_code =
                         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
                     env->spr[SPR_DAR] = address;
@@ -1709,7 +1710,7 @@  static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
         }
 #if 0
         printf("%s: set exception to %d %02x\n", __func__,
-               env->exception, env->error_code);
+               cs->exception, env->error_code);
 #endif
         ret = 1;
     }
@@ -2908,6 +2909,6 @@  void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
             /* now we have a real cpu fault */
             cpu_restore_state(env, retaddr);
         }
-        helper_raise_exception_err(env, env->exception_index, env->error_code);
+        helper_raise_exception_err(env, cpu->exception_index, env->error_code);
     }
 }
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 8b6fbb5..0934a45 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8511,7 +8511,7 @@  static void ppc_cpu_reset(CPUState *s)
     env->reserve_addr = (target_ulong)-1ULL;
     /* Be sure no exception or interrupt is pending */
     env->pending_interrupts = 0;
-    env->exception_index = POWERPC_EXCP_NONE;
+    s->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
index a7c99e0..829f66f 100644
--- a/target-ppc/user_only_helper.c
+++ b/target-ppc/user_only_helper.c
@@ -39,7 +39,7 @@  int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
         env->spr[SPR_DAR] = address;
         env->spr[SPR_DSISR] = error_code;
     }
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
 
     return 1;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 361d713..c9d3d55 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -88,10 +88,7 @@  S390CPU *cpu_s390x_init(const char *cpu_model)
 
 void s390_cpu_do_interrupt(CPUState *cs)
 {
-    S390CPU *cpu = S390_CPU(cs);
-    CPUS390XState *env = &cpu->env;
-
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
 
 int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
@@ -99,7 +96,7 @@  int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 {
     S390CPU *cpu = S390_CPU(cs);
 
-    cpu->env.exception_index = EXCP_PGM;
+    cs->exception_index = EXCP_PGM;
     cpu->env.int_pgm_code = PGM_ADDRESSING;
     /* On real machines this value is dropped into LowMem.  Since this
        is userland, simply put this someplace that cpu_loop can find it.  */
@@ -113,7 +110,9 @@  int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
                                   uint32_t ilen)
 {
-    env->exception_index = EXCP_PGM;
+    CPUState *cs = CPU(s390_env_get_cpu(env));
+
+    cs->exception_index = EXCP_PGM;
     env->int_pgm_code = code;
     env->int_pgm_ilen = ilen;
 }
@@ -427,7 +426,7 @@  hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
     CPUS390XState *env = &cpu->env;
     target_ulong raddr;
     int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-    int old_exc = env->exception_index;
+    int old_exc = cs->exception_index;
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
 
     /* 31-Bit mode */
@@ -436,7 +435,7 @@  hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
     }
 
     mmu_translate(env, vaddr, 2, asc, &raddr, &prot);
-    env->exception_index = old_exc;
+    cs->exception_index = old_exc;
 
     return raddr;
 }
@@ -454,7 +453,7 @@  void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
             }
         }
         cs->halted = 1;
-        env->exception_index = EXCP_HLT;
+        cs->exception_index = EXCP_HLT;
     }
 
     env->psw.addr = addr;
@@ -751,43 +750,43 @@  void s390_cpu_do_interrupt(CPUState *cs)
     CPUS390XState *env = &cpu->env;
 
     qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
-                  __func__, env->exception_index, env->psw.addr);
+                  __func__, cs->exception_index, env->psw.addr);
 
     s390_add_running_cpu(cpu);
     /* handle machine checks */
     if ((env->psw.mask & PSW_MASK_MCHECK) &&
-        (env->exception_index == -1)) {
+        (cs->exception_index == -1)) {
         if (env->pending_int & INTERRUPT_MCHK) {
-            env->exception_index = EXCP_MCHK;
+            cs->exception_index = EXCP_MCHK;
         }
     }
     /* handle external interrupts */
     if ((env->psw.mask & PSW_MASK_EXT) &&
-        env->exception_index == -1) {
+        cs->exception_index == -1) {
         if (env->pending_int & INTERRUPT_EXT) {
             /* code is already in env */
-            env->exception_index = EXCP_EXT;
+            cs->exception_index = EXCP_EXT;
         } else if (env->pending_int & INTERRUPT_TOD) {
             cpu_inject_ext(cpu, 0x1004, 0, 0);
-            env->exception_index = EXCP_EXT;
+            cs->exception_index = EXCP_EXT;
             env->pending_int &= ~INTERRUPT_EXT;
             env->pending_int &= ~INTERRUPT_TOD;
         } else if (env->pending_int & INTERRUPT_CPUTIMER) {
             cpu_inject_ext(cpu, 0x1005, 0, 0);
-            env->exception_index = EXCP_EXT;
+            cs->exception_index = EXCP_EXT;
             env->pending_int &= ~INTERRUPT_EXT;
             env->pending_int &= ~INTERRUPT_TOD;
         }
     }
     /* handle I/O interrupts */
     if ((env->psw.mask & PSW_MASK_IO) &&
-        (env->exception_index == -1)) {
+        (cs->exception_index == -1)) {
         if (env->pending_int & INTERRUPT_IO) {
-            env->exception_index = EXCP_IO;
+            cs->exception_index = EXCP_IO;
         }
     }
 
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXCP_PGM:
         do_program_interrupt(env);
         break;
@@ -804,7 +803,7 @@  void s390_cpu_do_interrupt(CPUState *cs)
         do_mchk_interrupt(env);
         break;
     }
-    env->exception_index = -1;
+    cs->exception_index = -1;
 
     if (!env->pending_int) {
         cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 747ba46..e2748a7 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -1048,8 +1048,9 @@  void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint64_t v1)
 /* load real address */
 uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
 {
+    CPUState *cs = CPU(s390_env_get_cpu(env));
     uint32_t cc = 0;
-    int old_exc = env->exception_index;
+    int old_exc = cs->exception_index;
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
     uint64_t ret;
     int flags;
@@ -1059,16 +1060,16 @@  uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
         program_interrupt(env, PGM_SPECIAL_OP, 2);
     }
 
-    env->exception_index = old_exc;
+    cs->exception_index = old_exc;
     if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
         cc = 3;
     }
-    if (env->exception_index == EXCP_PGM) {
+    if (cs->exception_index == EXCP_PGM) {
         ret = env->int_pgm_code | 0x80000000;
     } else {
         ret |= addr & ~TARGET_PAGE_MASK;
     }
-    env->exception_index = old_exc;
+    cs->exception_index = old_exc;
 
     env->cc_op = cc;
     return ret;
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 1690907..b6bd16f 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -46,9 +46,10 @@ 
 void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
                                      uintptr_t retaddr)
 {
+    CPUState *cs = CPU(s390_env_get_cpu(env));
     int t;
 
-    env->exception_index = EXCP_PGM;
+    cs->exception_index = EXCP_PGM;
     env->int_pgm_code = excp;
 
     /* Use the (ultimate) callers address to find the insn that trapped.  */
@@ -65,8 +66,10 @@  void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
 /* Raise an exception statically from a TB.  */
 void HELPER(exception)(CPUS390XState *env, uint32_t excp)
 {
+    CPUState *cs = CPU(s390_env_get_cpu(env));
+
     HELPER_LOG("%s: exception %d\n", __func__, excp);
-    env->exception_index = excp;
+    cs->exception_index = excp;
     cpu_loop_exit(env);
 }
 
@@ -154,17 +157,21 @@  static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
 
 void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
 {
+    S390CPU *cpu = s390_env_get_cpu(env);
+
     qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
                   env->psw.addr);
 
     if (kvm_enabled()) {
 #ifdef CONFIG_KVM
-        kvm_s390_interrupt(s390_env_get_cpu(env), KVM_S390_PROGRAM_INT, code);
+        kvm_s390_interrupt(cpu, KVM_S390_PROGRAM_INT, code);
 #endif
     } else {
+        CPUState *cs = CPU(cpu);
+
         env->int_pgm_code = code;
         env->int_pgm_ilen = ilen;
-        env->exception_index = EXCP_PGM;
+        cs->exception_index = EXCP_PGM;
         cpu_loop_exit(env);
     }
 }
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 3f8f1fa..0357ceb 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -33,10 +33,7 @@ 
 
 void superh_cpu_do_interrupt(CPUState *cs)
 {
-    SuperHCPU *cpu = SUPERH_CPU(cs);
-    CPUSH4State *env = &cpu->env;
-
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
 
 int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
@@ -46,16 +43,16 @@  int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
     CPUSH4State *env = &cpu->env;
 
     env->tea = address;
-    env->exception_index = -1;
+    cs->exception_index = -1;
     switch (rw) {
     case 0:
-        env->exception_index = 0x0a0;
+        cs->exception_index = 0x0a0;
         break;
     case 1:
-        env->exception_index = 0x0c0;
+        cs->exception_index = 0x0c0;
         break;
     case 2:
-        env->exception_index = 0x0a0;
+        cs->exception_index = 0x0a0;
         break;
     }
     return 1;
@@ -89,16 +86,16 @@  void superh_cpu_do_interrupt(CPUState *cs)
     SuperHCPU *cpu = SUPERH_CPU(cs);
     CPUSH4State *env = &cpu->env;
     int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD;
-    int do_exp, irq_vector = env->exception_index;
+    int do_exp, irq_vector = cs->exception_index;
 
     /* prioritize exceptions over interrupts */
 
-    do_exp = env->exception_index != -1;
-    do_irq = do_irq && (env->exception_index == -1);
+    do_exp = cs->exception_index != -1;
+    do_irq = do_irq && (cs->exception_index == -1);
 
     if (env->sr & SR_BL) {
-        if (do_exp && env->exception_index != 0x1e0) {
-            env->exception_index = 0x000; /* masked exception -> reset */
+        if (do_exp && cs->exception_index != 0x1e0) {
+            cs->exception_index = 0x000; /* masked exception -> reset */
         }
         if (do_irq && !env->in_sleep) {
             return; /* masked */
@@ -116,7 +113,7 @@  void superh_cpu_do_interrupt(CPUState *cs)
 
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
 	const char *expname;
-	switch (env->exception_index) {
+        switch (cs->exception_index) {
 	case 0x0e0:
 	    expname = "addr_error";
 	    break;
@@ -180,8 +177,8 @@  void superh_cpu_do_interrupt(CPUState *cs)
         env->flags = 0;
 
     if (do_exp) {
-        env->expevt = env->exception_index;
-        switch (env->exception_index) {
+        env->expevt = cs->exception_index;
+        switch (cs->exception_index) {
         case 0x000:
         case 0x020:
         case 0x140:
@@ -472,33 +469,33 @@  int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 	switch (ret) {
 	case MMU_ITLB_MISS:
 	case MMU_DTLB_MISS_READ:
-	    env->exception_index = 0x040;
+            cs->exception_index = 0x040;
 	    break;
 	case MMU_DTLB_MULTIPLE:
 	case MMU_ITLB_MULTIPLE:
-	    env->exception_index = 0x140;
+            cs->exception_index = 0x140;
 	    break;
 	case MMU_ITLB_VIOLATION:
-	    env->exception_index = 0x0a0;
+            cs->exception_index = 0x0a0;
 	    break;
 	case MMU_DTLB_MISS_WRITE:
-	    env->exception_index = 0x060;
+            cs->exception_index = 0x060;
 	    break;
 	case MMU_DTLB_INITIAL_WRITE:
-	    env->exception_index = 0x080;
+            cs->exception_index = 0x080;
 	    break;
 	case MMU_DTLB_VIOLATION_READ:
-	    env->exception_index = 0x0a0;
+            cs->exception_index = 0x0a0;
 	    break;
 	case MMU_DTLB_VIOLATION_WRITE:
-	    env->exception_index = 0x0c0;
+            cs->exception_index = 0x0c0;
 	    break;
 	case MMU_IADDR_ERROR:
 	case MMU_DADDR_ERROR_READ:
-	    env->exception_index = 0x0e0;
+            cs->exception_index = 0x0e0;
 	    break;
 	case MMU_DADDR_ERROR_WRITE:
-	    env->exception_index = 0x100;
+            cs->exception_index = 0x100;
 	    break;
 	default:
             cpu_abort(env, "Unhandled MMU fault");
@@ -702,8 +699,10 @@  void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, hwaddr addr,
             if (entry->vpn == vpn
                 && (!use_asid || entry->asid == asid || entry->sh)) {
 	        if (utlb_match_entry) {
+                    CPUState *cs = CPU(sh_env_get_cpu(s));
+
 		    /* Multiple TLB Exception */
-		    s->exception_index = 0x140;
+                    cs->exception_index = 0x140;
 		    s->tea = addr;
 		    break;
 	        }
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 35f9067..03633f0 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -69,7 +69,9 @@  void helper_ldtlb(CPUSH4State *env)
 static inline void QEMU_NORETURN raise_exception(CPUSH4State *env, int index,
                                                  uintptr_t retaddr)
 {
-    env->exception_index = index;
+    CPUState *cs = CPU(sh_env_get_cpu(env));
+
+    cs->exception_index = index;
     if (retaddr) {
         cpu_restore_state(env, retaddr);
     }
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 57c20af..a393ef0 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -24,13 +24,17 @@ 
 
 void helper_raise_exception(CPUSPARCState *env, int tt)
 {
-    env->exception_index = tt;
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
+
+    cs->exception_index = tt;
     cpu_loop_exit(env);
 }
 
 void helper_debug(CPUSPARCState *env)
 {
-    env->exception_index = EXCP_DEBUG;
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
+
+    cs->exception_index = EXCP_DEBUG;
     cpu_loop_exit(env);
 }
 
@@ -232,7 +236,7 @@  void helper_power_down(CPUSPARCState *env)
     CPUState *cs = CPU(sparc_env_get_cpu(env));
 
     cs->halted = 1;
-    env->exception_index = EXCP_HLT;
+    cs->exception_index = EXCP_HLT;
     env->pc = env->npc;
     env->npc = env->pc + 4;
     cpu_loop_exit(env);
diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
index d532238..f350a90 100644
--- a/target-sparc/int32_helper.c
+++ b/target-sparc/int32_helper.c
@@ -62,7 +62,7 @@  void sparc_cpu_do_interrupt(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
-    int cwp, intno = env->exception_index;
+    int cwp, intno = cs->exception_index;
 
     /* Compute PSR before exposing state.  */
     if (env->cc_op != CC_OP_FLAGS) {
@@ -105,12 +105,12 @@  void sparc_cpu_do_interrupt(CPUState *cs)
 #endif
 #if !defined(CONFIG_USER_ONLY)
     if (env->psret == 0) {
-        if (env->exception_index == 0x80 &&
+        if (cs->exception_index == 0x80 &&
             env->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
             qemu_system_shutdown_request();
         } else {
             cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
-                      env->exception_index);
+                      cs->exception_index);
         }
         return;
     }
@@ -125,7 +125,7 @@  void sparc_cpu_do_interrupt(CPUState *cs)
     env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
     env->pc = env->tbr;
     env->npc = env->pc + 4;
-    env->exception_index = -1;
+    cs->exception_index = -1;
 
 #if !defined(CONFIG_USER_ONLY)
     /* IRQ acknowledgment */
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index bf7dd86..1744245 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -63,7 +63,7 @@  void sparc_cpu_do_interrupt(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
-    int intno = env->exception_index;
+    int intno = cs->exception_index;
     trap_state *tsptr;
 
     /* Compute PSR before exposing state.  */
@@ -112,7 +112,7 @@  void sparc_cpu_do_interrupt(CPUState *cs)
 #if !defined(CONFIG_USER_ONLY)
     if (env->tl >= env->maxtl) {
         cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
-                  " Error state", env->exception_index, env->tl, env->maxtl);
+                  " Error state", cs->exception_index, env->tl, env->maxtl);
         return;
     }
 #endif
@@ -160,7 +160,7 @@  void sparc_cpu_do_interrupt(CPUState *cs)
     env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
     env->pc = env->tbr;
     env->npc = env->pc + 4;
-    env->exception_index = -1;
+    cs->exception_index = -1;
 }
 
 trap_state *cpu_tsptr(CPUSPARCState* env)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 2f55af9..af7c289 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1284,6 +1284,7 @@  void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
                        int sign)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     uint64_t ret = 0;
 #if defined(DEBUG_ASI)
     target_ulong last_addr = addr;
@@ -1317,7 +1318,7 @@  uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
             dump_asi("read ", last_addr, asi, size, ret);
 #endif
             /* env->exception_index is set in get_physical_address_data(). */
-            helper_raise_exception(env, env->exception_index);
+            helper_raise_exception(env, cs->exception_index);
         }
 
         /* convert nonfaulting load ASIs to normal load ASIs */
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 0d88326..ea72657 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -28,12 +28,10 @@ 
 int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                                int mmu_idx)
 {
-    SPARCCPU *cpu = SPARC_CPU(cs);
-
     if (rw & 2) {
-        cpu->env.exception_index = TT_TFAULT;
+        cs->exception_index = TT_TFAULT;
     } else {
-        cpu->env.exception_index = TT_DFAULT;
+        cs->exception_index = TT_DFAULT;
     }
     return 1;
 }
@@ -238,9 +236,9 @@  int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
         return 0;
     } else {
         if (rw & 2) {
-            env->exception_index = TT_TFAULT;
+            cs->exception_index = TT_TFAULT;
         } else {
-            env->exception_index = TT_DFAULT;
+            cs->exception_index = TT_DFAULT;
         }
         return 1;
     }
@@ -489,6 +487,7 @@  static int get_physical_address_data(CPUSPARCState *env,
                                      hwaddr *physical, int *prot,
                                      target_ulong address, int rw, int mmu_idx)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     unsigned int i;
     uint64_t context;
     uint64_t sfsr = 0;
@@ -553,10 +552,10 @@  static int get_physical_address_data(CPUSPARCState *env,
 
             if (do_fault) {
                 /* faults above are reported with TT_DFAULT. */
-                env->exception_index = TT_DFAULT;
+                cs->exception_index = TT_DFAULT;
             } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
                 do_fault = 1;
-                env->exception_index = TT_DPROT;
+                cs->exception_index = TT_DPROT;
 
                 trace_mmu_helper_dprot(address, context, mmu_idx, env->tl);
             }
@@ -600,7 +599,7 @@  static int get_physical_address_data(CPUSPARCState *env,
      * - JPS1: SFAR updated and some fields of SFSR updated
      */
     env->dmmu.tag_access = (address & ~0x1fffULL) | context;
-    env->exception_index = TT_DMISS;
+    cs->exception_index = TT_DMISS;
     return 1;
 }
 
@@ -608,6 +607,7 @@  static int get_physical_address_code(CPUSPARCState *env,
                                      hwaddr *physical, int *prot,
                                      target_ulong address, int mmu_idx)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     unsigned int i;
     uint64_t context;
 
@@ -651,7 +651,7 @@  static int get_physical_address_code(CPUSPARCState *env,
 
                 /* FIXME: ASI field in SFSR must be set */
                 env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
-                env->exception_index = TT_TFAULT;
+                cs->exception_index = TT_TFAULT;
 
                 env->immu.tag_access = (address & ~0x1fffULL) | context;
 
@@ -669,7 +669,7 @@  static int get_physical_address_code(CPUSPARCState *env,
 
     /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
     env->immu.tag_access = (address & ~0x1fffULL) | context;
-    env->exception_index = TT_TMISS;
+    cs->exception_index = TT_TMISS;
     return 1;
 }
 
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 5cd2378..cd2cbef 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -16,7 +16,9 @@ 
 
 void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
 {
-    env->exception_index = excp;
+    CPUState *cs = CPU(uc32_env_get_cpu(env));
+
+    cs->exception_index = excp;
     cpu_loop_exit(env);
 }
 
diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
index 408f1b0..2e26fd1 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -79,7 +79,7 @@  void uc32_cpu_do_interrupt(CPUState *cs)
     uint32_t addr;
     int new_mode;
 
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case UC32_EXCP_PRIV:
         new_mode = ASR_MODE_PRIV;
         addr = 0x08;
@@ -99,7 +99,7 @@  void uc32_cpu_do_interrupt(CPUState *cs)
         addr = 0x18;
         break;
     default:
-        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+        cpu_abort(env, "Unhandled exception 0x%x\n", cs->exception_index);
         return;
     }
     /* High vectors.  */
@@ -256,9 +256,9 @@  int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
     env->cp0.c3_faultstatus = ret;
     env->cp0.c4_faultaddr = address;
     if (access_type == 2) {
-        env->exception_index = UC32_EXCP_ITRAP;
+        cs->exception_index = UC32_EXCP_ITRAP;
     } else {
-        env->exception_index = UC32_EXCP_DTRAP;
+        cs->exception_index = UC32_EXCP_DTRAP;
     }
     return ret;
 }
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index a0f9993..f55095e 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -169,6 +169,8 @@  static void handle_interrupt(CPUXtensaState *env)
             (env->config->level_mask[level] &
              env->sregs[INTSET] &
              env->sregs[INTENABLE])) {
+        CPUState *cs = CPU(xtensa_env_get_cpu(env));
+
         if (level > 1) {
             env->sregs[EPC1 + level - 1] = env->pc;
             env->sregs[EPS2 + level - 2] = env->sregs[PS];
@@ -185,10 +187,10 @@  static void handle_interrupt(CPUXtensaState *env)
                 } else {
                     env->sregs[EPC1] = env->pc;
                 }
-                env->exception_index = EXC_DOUBLE;
+                cs->exception_index = EXC_DOUBLE;
             } else {
                 env->sregs[EPC1] = env->pc;
-                env->exception_index =
+                cs->exception_index =
                     (env->sregs[PS] & PS_UM) ? EXC_USER : EXC_KERNEL;
             }
             env->sregs[PS] |= PS_EXCM;
@@ -202,7 +204,7 @@  void xtensa_cpu_do_interrupt(CPUState *cs)
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
 
-    if (env->exception_index == EXC_IRQ) {
+    if (cs->exception_index == EXC_IRQ) {
         qemu_log_mask(CPU_LOG_INT,
                 "%s(EXC_IRQ) level = %d, cintlevel = %d, "
                 "pc = %08x, a0 = %08x, ps = %08x, "
@@ -215,7 +217,7 @@  void xtensa_cpu_do_interrupt(CPUState *cs)
         handle_interrupt(env);
     }
 
-    switch (env->exception_index) {
+    switch (cs->exception_index) {
     case EXC_WINDOW_OVERFLOW4:
     case EXC_WINDOW_UNDERFLOW4:
     case EXC_WINDOW_OVERFLOW8:
@@ -228,15 +230,15 @@  void xtensa_cpu_do_interrupt(CPUState *cs)
     case EXC_DEBUG:
         qemu_log_mask(CPU_LOG_INT, "%s(%d) "
                 "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
-                __func__, env->exception_index,
+                __func__, cs->exception_index,
                 env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
-        if (env->config->exception_vector[env->exception_index]) {
+        if (env->config->exception_vector[cs->exception_index]) {
             env->pc = relocated_vector(env,
-                    env->config->exception_vector[env->exception_index]);
+                    env->config->exception_vector[cs->exception_index]);
             env->exception_taken = 1;
         } else {
             qemu_log("%s(pc = %08x) bad exception_index: %d\n",
-                    __func__, env->pc, env->exception_index);
+                    __func__, env->pc, cs->exception_index);
         }
         break;
 
@@ -245,7 +247,7 @@  void xtensa_cpu_do_interrupt(CPUState *cs)
 
     default:
         qemu_log("%s(pc = %08x) unknown exception_index: %d\n",
-                __func__, env->pc, env->exception_index);
+                __func__, env->pc, cs->exception_index);
         break;
     }
     check_interrupts(env);
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index cf97025..2e006e4 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -96,7 +96,9 @@  static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
 
 void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
 {
-    env->exception_index = excp;
+    CPUState *cs = CPU(xtensa_env_get_cpu(env));
+
+    cs->exception_index = excp;
     if (excp == EXCP_DEBUG) {
         env->exception_taken = 0;
     }
diff --git a/user-exec.c b/user-exec.c
index dec636e..dbb9c8d 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -41,7 +41,9 @@ 
 static void exception_action(CPUArchState *env1)
 {
 #if defined(TARGET_I386)
-    raise_exception_err(env1, env1->exception_index, env1->error_code);
+    CPUState *cpu = ENV_GET_CPU(env1);
+
+    raise_exception_err(env1, cpu->exception_index, env1->error_code);
 #else
     cpu_loop_exit(env1);
 #endif
@@ -71,7 +73,7 @@  void cpu_resume_from_signal(CPUArchState *env1, void *puc)
         sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
 #endif
     }
-    env1->exception_index = -1;
+    cpu->exception_index = -1;
     siglongjmp(cpu->jmp_env, 1);
 }