Patchwork [RFC,qom-cpu,04/41] cpu: Turn cpu_handle_mmu_fault() into a CPUClass hook

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

Comments

Andreas Färber - Sept. 4, 2013, 9:04 a.m.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/qom/cpu.h             |  3 +++
 target-alpha/cpu.c            |  4 +++-
 target-alpha/cpu.h            |  5 ++---
 target-alpha/helper.c         | 12 ++++++++----
 target-alpha/mem_helper.c     |  3 ++-
 target-arm/cpu.c              |  4 +++-
 target-arm/cpu.h              |  5 ++---
 target-arm/helper.c           | 13 +++++++++----
 target-arm/op_helper.c        |  3 ++-
 target-cris/cpu.c             |  4 +++-
 target-cris/cpu.h             |  3 +--
 target-cris/helper.c          | 24 +++++++++++++-----------
 target-cris/op_helper.c       |  3 ++-
 target-i386/cpu.c             |  4 +++-
 target-i386/cpu.h             |  3 +--
 target-i386/helper.c          | 19 ++++++++++++-------
 target-i386/mem_helper.c      |  3 ++-
 target-lm32/cpu.c             |  4 +++-
 target-lm32/cpu.h             |  3 +--
 target-lm32/helper.c          |  4 +++-
 target-lm32/op_helper.c       |  3 ++-
 target-m68k/cpu.c             |  4 +++-
 target-m68k/cpu.h             |  3 +--
 target-m68k/helper.c          | 17 ++++++++++-------
 target-m68k/op_helper.c       |  3 ++-
 target-microblaze/cpu.c       |  4 +++-
 target-microblaze/cpu.h       |  3 +--
 target-microblaze/helper.c    | 14 ++++++++------
 target-microblaze/op_helper.c |  3 ++-
 target-mips/cpu.c             |  4 +++-
 target-mips/cpu.h             |  5 ++---
 target-mips/helper.c          | 15 +++++++++------
 target-mips/op_helper.c       |  3 ++-
 target-moxie/cpu.c            |  4 +++-
 target-moxie/cpu.h            |  2 +-
 target-moxie/helper.c         | 19 +++++++++++--------
 target-openrisc/cpu.c         |  4 +++-
 target-openrisc/cpu.h         |  4 +---
 target-openrisc/mmu.c         | 14 +++++++-------
 target-openrisc/mmu_helper.c  |  3 ++-
 target-ppc/cpu.h              |  4 ++--
 target-ppc/translate_init.c   |  4 +++-
 target-ppc/user_only_helper.c |  6 ++++--
 target-s390x/cpu.c            |  4 +++-
 target-s390x/cpu.h            |  5 ++---
 target-s390x/helper.c         | 20 ++++++++++++--------
 target-s390x/mem_helper.c     |  3 ++-
 target-sh4/cpu.c              |  4 +++-
 target-sh4/cpu.h              |  5 ++---
 target-sh4/helper.c           | 13 +++++++++----
 target-sh4/op_helper.c        |  3 ++-
 target-sparc/cpu.c            |  4 +++-
 target-sparc/cpu.h            |  3 +--
 target-sparc/ldst_helper.c    |  3 ++-
 target-sparc/mmu_helper.c     | 18 ++++++++++++------
 target-unicore32/cpu.c        |  4 +++-
 target-unicore32/cpu.h        |  5 ++---
 target-unicore32/helper.c     |  5 ++++-
 target-unicore32/op_helper.c  |  3 ++-
 target-unicore32/softmmu.c    |  6 ++++--
 user-exec.c                   |  9 +++++++--
 61 files changed, 238 insertions(+), 150 deletions(-)
Jia Liu - Sept. 4, 2013, 12:46 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>
> ---
>  include/qom/cpu.h             |  3 +++
>  target-alpha/cpu.c            |  4 +++-
>  target-alpha/cpu.h            |  5 ++---
>  target-alpha/helper.c         | 12 ++++++++----
>  target-alpha/mem_helper.c     |  3 ++-
>  target-arm/cpu.c              |  4 +++-
>  target-arm/cpu.h              |  5 ++---
>  target-arm/helper.c           | 13 +++++++++----
>  target-arm/op_helper.c        |  3 ++-
>  target-cris/cpu.c             |  4 +++-
>  target-cris/cpu.h             |  3 +--
>  target-cris/helper.c          | 24 +++++++++++++-----------
>  target-cris/op_helper.c       |  3 ++-
>  target-i386/cpu.c             |  4 +++-
>  target-i386/cpu.h             |  3 +--
>  target-i386/helper.c          | 19 ++++++++++++-------
>  target-i386/mem_helper.c      |  3 ++-
>  target-lm32/cpu.c             |  4 +++-
>  target-lm32/cpu.h             |  3 +--
>  target-lm32/helper.c          |  4 +++-
>  target-lm32/op_helper.c       |  3 ++-
>  target-m68k/cpu.c             |  4 +++-
>  target-m68k/cpu.h             |  3 +--
>  target-m68k/helper.c          | 17 ++++++++++-------
>  target-m68k/op_helper.c       |  3 ++-
>  target-microblaze/cpu.c       |  4 +++-
>  target-microblaze/cpu.h       |  3 +--
>  target-microblaze/helper.c    | 14 ++++++++------
>  target-microblaze/op_helper.c |  3 ++-
>  target-mips/cpu.c             |  4 +++-
>  target-mips/cpu.h             |  5 ++---
>  target-mips/helper.c          | 15 +++++++++------
>  target-mips/op_helper.c       |  3 ++-
>  target-moxie/cpu.c            |  4 +++-
>  target-moxie/cpu.h            |  2 +-
>  target-moxie/helper.c         | 19 +++++++++++--------
>  target-openrisc/cpu.c         |  4 +++-
>  target-openrisc/cpu.h         |  4 +---
>  target-openrisc/mmu.c         | 14 +++++++-------
>  target-openrisc/mmu_helper.c  |  3 ++-
>  target-ppc/cpu.h              |  4 ++--
>  target-ppc/translate_init.c   |  4 +++-
>  target-ppc/user_only_helper.c |  6 ++++--
>  target-s390x/cpu.c            |  4 +++-
>  target-s390x/cpu.h            |  5 ++---
>  target-s390x/helper.c         | 20 ++++++++++++--------
>  target-s390x/mem_helper.c     |  3 ++-
>  target-sh4/cpu.c              |  4 +++-
>  target-sh4/cpu.h              |  5 ++---
>  target-sh4/helper.c           | 13 +++++++++----
>  target-sh4/op_helper.c        |  3 ++-
>  target-sparc/cpu.c            |  4 +++-
>  target-sparc/cpu.h            |  3 +--
>  target-sparc/ldst_helper.c    |  3 ++-
>  target-sparc/mmu_helper.c     | 18 ++++++++++++------
>  target-unicore32/cpu.c        |  4 +++-
>  target-unicore32/cpu.h        |  5 ++---
>  target-unicore32/helper.c     |  5 ++++-
>  target-unicore32/op_helper.c  |  3 ++-
>  target-unicore32/softmmu.c    |  6 ++++--
>  user-exec.c                   |  9 +++++++--
>  61 files changed, 238 insertions(+), 150 deletions(-)
>
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 3d6b66e..4d974f3 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -84,6 +84,7 @@ struct TranslationBlock;
>   * #TranslationBlock.
>   * @synchronize_from_tb: Callback for synchronizing state from a TCG
>   * #TranslationBlock.
> + * @handle_mmu_fault: Callback for handling an MMU fault.
>   * @get_phys_page_debug: Callback for obtaining a physical address.
>   * @gdb_read_register: Callback for letting GDB read a register.
>   * @gdb_write_register: Callback for letting GDB write a register.
> @@ -120,6 +121,8 @@ typedef struct CPUClass {
>      void (*get_tb_cpu_state)(const CPUState *cpu, vaddr *pc, vaddr *cs_base,
>                               int *flags);
>      void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
> +    int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw,
> +                            int mmu_index);
>      hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
>      int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
>      int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
> index bb1eddc..e880983 100644
> --- a/target-alpha/cpu.c
> +++ b/target-alpha/cpu.c
> @@ -330,7 +330,9 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = alpha_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = alpha_cpu_gdb_read_register;
>      cc->gdb_write_register = alpha_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = alpha_cpu_handle_mmu_fault;
> +#else
>      cc->do_unassigned_access = alpha_cpu_unassigned_access;
>      cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
>      dc->vmsd = &vmstate_alpha_cpu;
> diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
> index a4abce8..dd117d9 100644
> --- a/target-alpha/cpu.h
> +++ b/target-alpha/cpu.h
> @@ -435,9 +435,8 @@ int cpu_alpha_exec(CPUAlphaState *s);
>     is returned if the signal was handled by the virtual CPU.  */
>  int cpu_alpha_signal_handler(int host_signum, void *pinfo,
>                               void *puc);
> -int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
> -                                int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
> +int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                               int mmu_idx);
>  void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
>  void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
>  void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
> diff --git a/target-alpha/helper.c b/target-alpha/helper.c
> index fc61bb0..ef2dc25 100644
> --- a/target-alpha/helper.c
> +++ b/target-alpha/helper.c
> @@ -168,11 +168,13 @@ void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
>  }
>
>  #if defined(CONFIG_USER_ONLY)
> -int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address,
> +int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>                                 int rw, int mmu_idx)
>  {
> -    env->exception_index = EXCP_MMFAULT;
> -    env->trap_arg0 = address;
> +    AlphaCPU *cpu = ALPHA_CPU(cs);
> +
> +    cpu->env.exception_index = EXCP_MMFAULT;
> +    cpu->env.trap_arg0 = address;
>      return 1;
>  }
>  #else
> @@ -325,9 +327,11 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      return (fail >= 0 ? -1 : phys);
>  }
>
> -int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw,
> +int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw,
>                                 int mmu_idx)
>  {
> +    AlphaCPU *cpu = ALPHA_CPU(cs);
> +    CPUAlphaState *env = &cpu->env;
>      target_ulong phys;
>      int prot, fail;
>
> diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
> index 7160a1c..d140688 100644
> --- a/target-alpha/mem_helper.c
> +++ b/target-alpha/mem_helper.c
> @@ -145,9 +145,10 @@ void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
>  void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
>                int mmu_idx, uintptr_t retaddr)
>  {
> +    AlphaCPU *cpu = alpha_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = alpha_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret != 0)) {
>          if (retaddr) {
>              cpu_restore_state(env, retaddr);
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 53bf337..4c6fe17 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -938,7 +938,9 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = arm_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = arm_cpu_gdb_read_register;
>      cc->gdb_write_register = arm_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_arm_cpu;
>  #endif
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 161b9fd..ce98dda 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -266,9 +266,8 @@ uint32_t do_arm_semihosting(CPUARMState *env);
>     is returned if the signal was handled by the virtual CPU.  */
>  int cpu_arm_signal_handler(int host_signum, void *pinfo,
>                             void *puc);
> -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
> -                              int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
> +int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                             int mmu_idx);
>
>  #define CPSR_M (0x1f)
>  #define CPSR_T (1 << 5)
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index e51ef20..9d0d8b4 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2078,9 +2078,12 @@ void arm_cpu_do_interrupt(CPUState *cs)
>      env->exception_index = -1;
>  }
>
> -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
> -                              int mmu_idx)
> +int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                             int mmu_idx)
>  {
> +    ARMCPU *cpu = ARM_CPU(cs);
> +    CPUARMState *env = &cpu->env;
> +
>      if (rw == 2) {
>          env->exception_index = EXCP_PREFETCH_ABORT;
>          env->cp15.c6_insn = address;
> @@ -3026,9 +3029,11 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address,
>      }
>  }
>
> -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
> -                              int access_type, int mmu_idx)
> +int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
> +                             int access_type, int mmu_idx)
>  {
> +    ARMCPU *cpu = ARM_CPU(cs);
> +    CPUARMState *env = &cpu->env;
>      hwaddr phys_addr;
>      target_ulong page_size;
>      int prot;
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index a918e5b..13d34fb 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -74,9 +74,10 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
>  void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    ARMCPU *cpu = arm_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-cris/cpu.c b/target-cris/cpu.c
> index 39a25ed..504d6a4 100644
> --- a/target-cris/cpu.c
> +++ b/target-cris/cpu.c
> @@ -290,7 +290,9 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = cris_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = cris_cpu_gdb_read_register;
>      cc->gdb_write_register = cris_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = cris_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
>  #endif
>
> diff --git a/target-cris/cpu.h b/target-cris/cpu.h
> index 9f1fa38..9e9cb8c 100644
> --- a/target-cris/cpu.h
> +++ b/target-cris/cpu.h
> @@ -239,9 +239,8 @@ static inline CPUCRISState *cpu_init(const char *cpu_model)
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
>
> -int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
> +int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
>                                int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault
>
>  /* Support function regs.  */
>  #define SFR_RW_GC_CFG      0][0
> diff --git a/target-cris/helper.c b/target-cris/helper.c
> index d274b38..72dc839 100644
> --- a/target-cris/helper.c
> +++ b/target-cris/helper.c
> @@ -50,14 +50,14 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
>      cris_cpu_do_interrupt(cs);
>  }
>
> -int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
> +int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                int mmu_idx)
>  {
> -    CRISCPU *cpu = cris_env_get_cpu(env);
> +    CRISCPU *cpu = CRIS_CPU(cs);
>
> -    env->exception_index = 0xaa;
> -    env->pregs[PR_EDA] = address;
> -    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
> +    cpu->env.exception_index = 0xaa;
> +    cpu->env.pregs[PR_EDA] = address;
> +    cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
>  }
>
> @@ -73,23 +73,25 @@ static void cris_shift_ccs(CPUCRISState *env)
>      env->pregs[PR_CCS] = ccs;
>  }
>
> -int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
> +int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                int mmu_idx)
>  {
> -    D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
> +    CRISCPU *cpu = CRIS_CPU(cs);
> +    CPUCRISState *env = &cpu->env;
>      struct cris_mmu_result res;
>      int prot, miss;
>      int r = -1;
>      target_ulong phy;
>
> -    D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
> +    D(printf("%s addr=%" VADDR_PRIx " pc=%x rw=%x\n",
> +             __func__, address, env->pc, rw));
>      miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
>                                rw, mmu_idx, 0);
>      if (miss) {
>          if (env->exception_index == EXCP_BUSFAULT) {
>              cpu_abort(env,
>                        "CRIS: Illegal recursive bus fault."
> -                      "addr=%x rw=%d\n",
> +                      "addr=%" VADDR_PRIx " rw=%d\n",
>                        address, rw);
>          }
>
> @@ -109,8 +111,8 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
>          r = 0;
>      }
>      if (r > 0) {
> -        D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
> -              __func__, r, cpu->interrupt_request, address, res.phy,
> +        D_LOG("%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x"
> +              " pc=%x\n", __func__, r, cs->interrupt_request, address, res.phy,
>                res.bf_vec, env->pc);
>      }
>      return r;
> diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
> index b580513..4a6215d 100644
> --- a/target-cris/op_helper.c
> +++ b/target-cris/op_helper.c
> @@ -57,11 +57,12 @@
>  void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    CRISCPU *cpu = cris_env_get_cpu(env);
>      int ret;
>
>      D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
>            env->pc, env->pregs[PR_EDA], (void *)retaddr);
> -    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = cris_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 995d5ff..3ed5a11 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2743,7 +2743,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
>      cc->gdb_write_register = x86_cpu_gdb_write_register;
>      cc->get_arch_id = x86_cpu_get_arch_id;
>      cc->get_paging_enabled = x86_cpu_get_paging_enabled;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
> +#else
>      cc->get_memory_mapping = x86_cpu_get_memory_mapping;
>      cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
>      cc->write_elf64_note = x86_cpu_write_elf64_note;
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 999a46c..3620699 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1042,9 +1042,8 @@ void host_cpuid(uint32_t function, uint32_t count,
>                  uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
>
>  /* helper.c */
> -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
> +int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr,
>                               int is_write, int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
>  void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
>
>  static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 7c58e27..b25dafc 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -485,9 +485,12 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
>
>  #if defined(CONFIG_USER_ONLY)
>
> -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
> +int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
>                               int is_write, int mmu_idx)
>  {
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
> +
>      /* user mode only emulation */
>      is_write &= 1;
>      env->cr[2] = addr;
> @@ -508,13 +511,15 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
>  # endif
>
>  /* return value:
> -   -1 = cannot handle fault
> -   0  = nothing more to do
> -   1  = generate PF fault
> -*/
> -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
> + * -1 = cannot handle fault
> + * 0  = nothing more to do
> + * 1  = generate PF fault
> + */
> +int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
>                               int is_write1, int mmu_idx)
>  {
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>      uint64_t ptep, pte;
>      target_ulong pde_addr, pte_addr;
>      int error_code, is_dirty, prot, page_size, is_write, is_user;
> @@ -524,7 +529,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
>
>      is_user = mmu_idx == MMU_USER_IDX;
>  #if defined(DEBUG_MMU)
> -    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
> +    printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
>             addr, is_write1, is_user, env->eip);
>  #endif
>      is_write = is_write1 & 1;
> diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
> index 319a219..5b25ccd 100644
> --- a/target-i386/mem_helper.c
> +++ b/target-i386/mem_helper.c
> @@ -135,9 +135,10 @@ void helper_boundl(CPUX86State *env, target_ulong a0, int v)
>  void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    X86CPU *cpu = x86_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (ret) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
> index 7976d39..607e332 100644
> --- a/target-lm32/cpu.c
> +++ b/target-lm32/cpu.c
> @@ -108,7 +108,9 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = lm32_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = lm32_cpu_gdb_read_register;
>      cc->gdb_write_register = lm32_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_lm32_cpu;
>  #endif
> diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
> index a34f047..a94fd79 100644
> --- a/target-lm32/cpu.h
> +++ b/target-lm32/cpu.h
> @@ -207,9 +207,8 @@ static inline CPULM32State *cpu_init(const char *cpu_model)
>  #define cpu_gen_code cpu_lm32_gen_code
>  #define cpu_signal_handler cpu_lm32_signal_handler
>
> -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
> +int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
>                                int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault
>
>  #include "exec/cpu-all.h"
>  #include "exec/exec-all.h"
> diff --git a/target-lm32/helper.c b/target-lm32/helper.c
> index 15bc615..55a3de6 100644
> --- a/target-lm32/helper.c
> +++ b/target-lm32/helper.c
> @@ -20,9 +20,11 @@
>  #include "cpu.h"
>  #include "qemu/host-utils.h"
>
> -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
> +int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                int mmu_idx)
>  {
> +    LM32CPU *cpu = LM32_CPU(cs);
> +    CPULM32State *env = &cpu->env;
>      int prot;
>
>      address &= TARGET_PAGE_MASK;
> diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
> index 8f5ef55..215215e 100644
> --- a/target-lm32/op_helper.c
> +++ b/target-lm32/op_helper.c
> @@ -80,9 +80,10 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
>  void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    LM32CPU *cpu = lm32_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = lm32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
> index 6dbfe89..e46b647 100644
> --- a/target-m68k/cpu.c
> +++ b/target-m68k/cpu.c
> @@ -222,7 +222,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
>      cc->get_tb_cpu_state = m68k_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = m68k_cpu_gdb_read_register;
>      cc->gdb_write_register = m68k_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
>  #endif
>      dc->vmsd = &vmstate_m68k_cpu;
> diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
> index 5c7992e..b8ad269 100644
> --- a/target-m68k/cpu.h
> +++ b/target-m68k/cpu.h
> @@ -233,9 +233,8 @@ static inline CPUM68KState *cpu_init(const char *cpu_model)
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
>
> -int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw,
> +int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
>                                int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault
>
>  #include "exec/cpu-all.h"
>  #include "exec/exec-all.h"
> diff --git a/target-m68k/helper.c b/target-m68k/helper.c
> index 00a7a08..25a0570 100644
> --- a/target-m68k/helper.c
> +++ b/target-m68k/helper.c
> @@ -278,11 +278,13 @@ void m68k_switch_sp(CPUM68KState *env)
>
>  #if defined(CONFIG_USER_ONLY)
>
> -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
> -                               int mmu_idx)
> +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                              int mmu_idx)
>  {
> -    env->exception_index = EXCP_ACCESS;
> -    env->mmu.ar = address;
> +    M68kCPU *cpu = M68K_CPU(cs);
> +
> +    cpu->env.exception_index = EXCP_ACCESS;
> +    cpu->env.mmu.ar = address;
>      return 1;
>  }
>
> @@ -296,14 +298,15 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      return addr;
>  }
>
> -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
> -                               int mmu_idx)
> +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                              int mmu_idx)
>  {
> +    M68kCPU *cpu = M68K_CPU(cs);
>      int prot;
>
>      address &= TARGET_PAGE_MASK;
>      prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> -    tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
> +    tlb_set_page(&cpu->env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
>      return 0;
>  }
>
> diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
> index 30f7d8b..bc10f38 100644
> --- a/target-m68k/op_helper.c
> +++ b/target-m68k/op_helper.c
> @@ -59,9 +59,10 @@ extern int semihosting_enabled;
>  void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    M68kCPU *cpu = m68k_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = m68k_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
> index fbcdcc4..8b248f4 100644
> --- a/target-microblaze/cpu.c
> +++ b/target-microblaze/cpu.c
> @@ -178,7 +178,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = mb_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = mb_cpu_gdb_read_register;
>      cc->gdb_write_register = mb_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = mb_cpu_handle_mmu_fault;
> +#else
>      cc->do_unassigned_access = mb_cpu_unassigned_access;
>      cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
>  #endif
> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
> index d80f812..1177e51 100644
> --- a/target-microblaze/cpu.h
> +++ b/target-microblaze/cpu.h
> @@ -316,9 +316,8 @@ static inline CPUMBState *cpu_init(const char *cpu_model)
>  #define MMU_USER_IDX    2
>  /* See NB_MMU_MODES further up the file.  */
>
> -int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw,
> +int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
>                              int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
>
>  static inline int cpu_interrupts_enabled(CPUMBState *env)
>  {
> diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
> index 4fa9ce9..d03f369 100644
> --- a/target-microblaze/helper.c
> +++ b/target-microblaze/helper.c
> @@ -36,21 +36,23 @@ void mb_cpu_do_interrupt(CPUState *cs)
>      env->regs[14] = env->sregs[SR_PC];
>  }
>
> -int cpu_mb_handle_mmu_fault(CPUMBState * env, target_ulong address, int rw,
> +int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                              int mmu_idx)
>  {
> -    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
> +    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
>
> -    env->exception_index = 0xaa;
> -    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
> +    cpu->env.exception_index = 0xaa;
> +    cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
>  }
>
>  #else /* !CONFIG_USER_ONLY */
>
> -int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw,
> -                             int mmu_idx)
> +int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                            int mmu_idx)
>  {
> +    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
> +    CPUMBState *env = &cpu->env;
>      unsigned int hit;
>      unsigned int mmu_available;
>      int r = 1;
> diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
> index 14baa84..b70b2ea 100644
> --- a/target-microblaze/op_helper.c
> +++ b/target-microblaze/op_helper.c
> @@ -44,9 +44,10 @@
>  void tlb_fill(CPUMBState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = mb_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-mips/cpu.c b/target-mips/cpu.c
> index 4aa06bb..2fd5591 100644
> --- a/target-mips/cpu.c
> +++ b/target-mips/cpu.c
> @@ -153,7 +153,9 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
>      cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
>      cc->gdb_read_register = mips_cpu_gdb_read_register;
>      cc->gdb_write_register = mips_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = mips_cpu_handle_mmu_fault;
> +#else
>      cc->do_unassigned_access = mips_cpu_unassigned_access;
>      cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
>  #endif
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 91217ed..b71a711 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -649,9 +649,8 @@ void cpu_mips_stop_count(CPUMIPSState *env);
>  void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
>
>  /* helper.c */
> -int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
> -                               int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
> +int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                              int mmu_idx);
>  #if !defined(CONFIG_USER_ONLY)
>  void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
>  hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
> diff --git a/target-mips/helper.c b/target-mips/helper.c
> index 33e0e88..d8e9166 100644
> --- a/target-mips/helper.c
> +++ b/target-mips/helper.c
> @@ -268,9 +268,11 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>  }
>  #endif
>
> -int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
> -                               int mmu_idx)
> +int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                              int mmu_idx)
>  {
> +    MIPSCPU *cpu = MIPS_CPU(cs);
> +    CPUMIPSState *env = &cpu->env;
>  #if !defined(CONFIG_USER_ONLY)
>      hwaddr physical;
>      int prot;
> @@ -279,9 +281,9 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
>      int ret = 0;
>
>  #if 0
> -    log_cpu_state(CPU(mips_env_get_cpu(env)), 0);
> +    log_cpu_state(cs, 0);
>  #endif
> -    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
> +    qemu_log("%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
>                __func__, env->active_tc.PC, address, rw, mmu_idx);
>
>      rw &= 1;
> @@ -293,8 +295,9 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
>      access_type = ACCESS_INT;
>      ret = get_physical_address(env, &physical, &prot,
>                                 address, rw, access_type);
> -    qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n",
> -              __func__, address, ret, physical, prot);
> +    qemu_log("%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
> +             " prot %d\n",
> +             __func__, address, ret, physical, prot);
>      if (ret == TLBRET_MATCH) {
>          tlb_set_page(env, address & TARGET_PAGE_MASK,
>                       physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 8e3a6d7..34ac4c6 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -2134,9 +2134,10 @@ static void do_unaligned_access(CPUMIPSState *env, target_ulong addr,
>  void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    MIPSCPU *cpu = mips_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = mips_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (ret) {
>          do_raise_exception_err(env, env->exception_index,
>                                 env->error_code, retaddr);
> diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
> index 9983c99..e07a4df 100644
> --- a/target-moxie/cpu.c
> +++ b/target-moxie/cpu.c
> @@ -119,7 +119,9 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
>      cc->dump_state = moxie_cpu_dump_state;
>      cc->set_pc = moxie_cpu_set_pc;
>      cc->get_tb_cpu_state = moxie_cpu_get_tb_cpu_state;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = moxie_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_moxie_cpu;
>  #endif
> diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
> index 7e33efe..fb2a97e 100644
> --- a/target-moxie/cpu.h
> +++ b/target-moxie/cpu.h
> @@ -139,7 +139,7 @@ static inline CPUMoxieState *cpu_init(const char *cpu_model)
>  #include "exec/cpu-all.h"
>  #include "exec/exec-all.h"
>
> -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
> +int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
>                                 int rw, int mmu_idx);
>
>  #endif /* _CPU_MOXIE_H */
> diff --git a/target-moxie/helper.c b/target-moxie/helper.c
> index 7859102..8160475 100644
> --- a/target-moxie/helper.c
> +++ b/target-moxie/helper.c
> @@ -49,9 +49,10 @@
>  void tlb_fill(CPUMoxieState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    MoxieCPU *cpu = moxie_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_moxie_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = moxie_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              cpu_restore_state(env, retaddr);
> @@ -103,27 +104,29 @@ void helper_debug(CPUMoxieState *env)
>
>  #if defined(CONFIG_USER_ONLY)
>
> -void moxie_cpu_do_interrupt(CPUState *env)
> +void moxie_cpu_do_interrupt(CPUState *cs)
>  {
>      env->exception_index = -1;
>  }
>
> -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
> +int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>                                 int rw, int mmu_idx)
>  {
> -    MoxieCPU *cpu = moxie_env_get_cpu(env);
> +    MoxieCPU *cpu = MOXIE_CPU(cs);
>
> -    env->exception_index = 0xaa;
> -    env->debug1 = address;
> -    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
> +    cpu->env.exception_index = 0xaa;
> +    cpu->env.debug1 = address;
> +    cpu_dump_state(cs, stderr, fprintf, 0);
>      return 1;
>  }
>
>  #else /* !CONFIG_USER_ONLY */
>
> -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
> +int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>                                 int rw, int mmu_idx)
>  {
> +    MoxieCPU *cpu = MOXIE_CPU(cs);
> +    CPUMoxieState *env = &cpu->env;
>      MoxieMMUResult res;
>      int prot, miss;
>      target_ulong phy;
> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
> index 107e5f9..ee1591d 100644
> --- a/target-openrisc/cpu.c
> +++ b/target-openrisc/cpu.c
> @@ -188,7 +188,9 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = openrisc_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = openrisc_cpu_gdb_read_register;
>      cc->gdb_write_register = openrisc_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = openrisc_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
>      dc->vmsd = &vmstate_openrisc_cpu;
>  #endif
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> index a41c271..8745072 100644
> --- a/target-openrisc/cpu.h
> +++ b/target-openrisc/cpu.h
> @@ -353,15 +353,13 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
>  int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
>  void openrisc_translate_init(void);
> -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
> -                                  target_ulong address,
> +int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
>                                    int rw, int mmu_idx);
>  int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
>
>  #define cpu_list cpu_openrisc_list
>  #define cpu_exec cpu_openrisc_exec
>  #define cpu_gen_code cpu_openrisc_gen_code
> -#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
>  #define cpu_signal_handler cpu_openrisc_signal_handler
>
>  #ifndef CONFIG_USER_ONLY
> diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
> index 57f5616..0f13c5d 100644
> --- a/target-openrisc/mmu.c
> +++ b/target-openrisc/mmu.c
> @@ -181,19 +181,19 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
>  }
>
>  #ifndef CONFIG_USER_ONLY
> -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
> -                                  target_ulong address, int rw, int mmu_idx)
> +int openrisc_cpu_handle_mmu_fault(CPUState *cs,
> +                                  vaddr address, int rw, int mmu_idx)
>  {
> +    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
>      int ret = 0;
>      hwaddr physical = 0;
>      int prot = 0;
> -    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
>
>      ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot,
>                                       address, rw);
>
>      if (ret == TLBRET_MATCH) {
> -        tlb_set_page(env, address & TARGET_PAGE_MASK,
> +        tlb_set_page(&cpu->env, address & TARGET_PAGE_MASK,
>                       physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
>                       mmu_idx, TARGET_PAGE_SIZE);
>          ret = 0;
> @@ -205,11 +205,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
>      return ret;
>  }
>  #else
> -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
> -                                  target_ulong address, int rw, int mmu_idx)
> +int openrisc_cpu_handle_mmu_fault(CPUState *cs,
> +                                  vaddr address, int rw, int mmu_idx)
>  {
> +    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
>      int ret = 0;
> -    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
>
>      cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
>      ret = 1;
> diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
> index e46b092..b023a5f 100644
> --- a/target-openrisc/mmu_helper.c
> +++ b/target-openrisc/mmu_helper.c
> @@ -39,9 +39,10 @@
>  void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
>                int mmu_idx, uintptr_t retaddr)
>  {
> +    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = openrisc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>
>      if (ret) {
>          if (retaddr) {
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 2ebf0a1..3b03ae6 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1098,8 +1098,8 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo,
>                              void *puc);
>  void ppc_hw_interrupt (CPUPPCState *env);
>  #if defined(CONFIG_USER_ONLY)
> -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
> -                         int mmu_idx);
> +int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                             int mmu_idx);
>  #endif
>
>  #if !defined(CONFIG_USER_ONLY)
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 338d8fe..8b6fbb5 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8595,7 +8595,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = ppc_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = ppc_cpu_gdb_read_register;
>      cc->gdb_write_register = ppc_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_ppc_cpu;
>  #endif
> diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
> index 56e686e..a7c99e0 100644
> --- a/target-ppc/user_only_helper.c
> +++ b/target-ppc/user_only_helper.c
> @@ -20,9 +20,11 @@
>
>  #include "cpu.h"
>
> -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
> -                         int mmu_idx)
> +int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                             int mmu_idx)
>  {
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
>      int exception, error_code;
>
>      if (rw == 2) {
> diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
> index a4a5370..ad0d5bc 100644
> --- a/target-s390x/cpu.c
> +++ b/target-s390x/cpu.c
> @@ -257,7 +257,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
>      cc->get_tb_cpu_state = s390_cpu_get_tb_cpu_state;
>      cc->gdb_read_register = s390_cpu_gdb_read_register;
>      cc->gdb_write_register = s390_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = s390_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
>      cc->write_elf64_note = s390_cpu_write_elf64_note;
>      cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote;
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index cad092b..a09e4f9 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -308,9 +308,8 @@ int cpu_s390x_exec(CPUS390XState *s);
>     is returned if the signal was handled by the virtual CPU.  */
>  int cpu_s390x_signal_handler(int host_signum, void *pinfo,
>                             void *puc);
> -int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
> -                                int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
> +int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                              int mmu_idx);
>
>  #include "ioinst.h"
>
> diff --git a/target-s390x/helper.c b/target-s390x/helper.c
> index 61abfd7..361d713 100644
> --- a/target-s390x/helper.c
> +++ b/target-s390x/helper.c
> @@ -94,14 +94,16 @@ void s390_cpu_do_interrupt(CPUState *cs)
>      env->exception_index = -1;
>  }
>
> -int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
> -                               int rw, int mmu_idx)
> +int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
> +                              int rw, int mmu_idx)
>  {
> -    env->exception_index = EXCP_PGM;
> -    env->int_pgm_code = PGM_ADDRESSING;
> +    S390CPU *cpu = S390_CPU(cs);
> +
> +    cpu->env.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.  */
> -    env->__excp_addr = address;
> +    cpu->env.__excp_addr = address;
>      return 1;
>  }
>
> @@ -377,14 +379,16 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>      return r;
>  }
>
> -int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
> -                               int rw, int mmu_idx)
> +int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr,
> +                              int rw, int mmu_idx)
>  {
> +    S390CPU *cpu = S390_CPU(cs);
> +    CPUS390XState *env = &cpu->env;
>      uint64_t asc = env->psw.mask & PSW_MASK_ASC;
>      target_ulong vaddr, raddr;
>      int prot;
>
> -    DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
> +    DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
>              __func__, orig_vaddr, rw, mmu_idx);
>
>      orig_vaddr &= TARGET_PAGE_MASK;
> diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
> index 1422ae9..747ba46 100644
> --- a/target-s390x/mem_helper.c
> +++ b/target-s390x/mem_helper.c
> @@ -47,9 +47,10 @@
>  void tlb_fill(CPUS390XState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    S390CPU *cpu = s390_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = s390_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret != 0)) {
>          if (likely(retaddr)) {
>              /* now we have a real cpu fault */
> diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
> index 647a527..7f98f80 100644
> --- a/target-sh4/cpu.c
> +++ b/target-sh4/cpu.c
> @@ -320,7 +320,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
>      cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
>      cc->gdb_read_register = superh_cpu_gdb_read_register;
>      cc->gdb_write_register = superh_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = superh_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
>  #endif
>      dc->vmsd = &vmstate_sh_cpu;
> diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
> index 42ecdd7..8abd0cc 100644
> --- a/target-sh4/cpu.h
> +++ b/target-sh4/cpu.h
> @@ -193,9 +193,8 @@ SuperHCPU *cpu_sh4_init(const char *cpu_model);
>  int cpu_sh4_exec(CPUSH4State * s);
>  int cpu_sh4_signal_handler(int host_signum, void *pinfo,
>                             void *puc);
> -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
> -                             int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault
> +int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                                int mmu_idx);
>
>  void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  #if !defined(CONFIG_USER_ONLY)
> diff --git a/target-sh4/helper.c b/target-sh4/helper.c
> index 9ac2825..3f8f1fa 100644
> --- a/target-sh4/helper.c
> +++ b/target-sh4/helper.c
> @@ -39,9 +39,12 @@ void superh_cpu_do_interrupt(CPUState *cs)
>      env->exception_index = -1;
>  }
>
> -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
> -                             int mmu_idx)
> +int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                                int mmu_idx)
>  {
> +    SuperHCPU *cpu = SUPERH_CPU(cs);
> +    CPUSH4State *env = &cpu->env;
> +
>      env->tea = address;
>      env->exception_index = -1;
>      switch (rw) {
> @@ -447,9 +450,11 @@ static int get_physical_address(CPUSH4State * env, target_ulong * physical,
>      return get_mmu_address(env, physical, prot, address, rw, access_type);
>  }
>
> -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
> -                             int mmu_idx)
> +int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                                int mmu_idx)
>  {
> +    SuperHCPU *cpu = SUPERH_CPU(cs);
> +    CPUSH4State *env = &cpu->env;
>      target_ulong physical;
>      int prot, ret, access_type;
>
> diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
> index e955e81..35f9067 100644
> --- a/target-sh4/op_helper.c
> +++ b/target-sh4/op_helper.c
> @@ -41,9 +41,10 @@
>  void tlb_fill(CPUSH4State *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    SuperHCPU *cpu = sh_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = superh_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (ret) {
>          /* now we have a real cpu fault */
>          if (retaddr) {
> diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
> index 49a4469..c8d8c55 100644
> --- a/target-sparc/cpu.c
> +++ b/target-sparc/cpu.c
> @@ -857,7 +857,9 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
>      cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
>      cc->gdb_read_register = sparc_cpu_gdb_read_register;
>      cc->gdb_write_register = sparc_cpu_gdb_write_register;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault;
> +#else
>      cc->do_unassigned_access = sparc_cpu_unassigned_access;
>      cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
>  #endif
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index f078851..cfa1e0d 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -519,9 +519,8 @@ SPARCCPU *cpu_sparc_init(const char *cpu_model);
>  void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
>  void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  /* mmu_helper.c */
> -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
> +int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
>                                 int mmu_idx);
> -#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault
>  target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
>  void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
>
> diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
> index 2936b58..2f55af9 100644
> --- a/target-sparc/ldst_helper.c
> +++ b/target-sparc/ldst_helper.c
> @@ -2432,9 +2432,10 @@ static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
>  void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr)
>  {
> +    SPARCCPU *cpu = sparc_env_get_cpu(env);
>      int ret;
>
> -    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = sparc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (ret) {
>          if (retaddr) {
>              cpu_restore_state(env, retaddr);
> diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
> index 9eb096e..0d88326 100644
> --- a/target-sparc/mmu_helper.c
> +++ b/target-sparc/mmu_helper.c
> @@ -25,13 +25,15 @@
>
>  #if defined(CONFIG_USER_ONLY)
>
> -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
> +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                 int mmu_idx)
>  {
> +    SPARCCPU *cpu = SPARC_CPU(cs);
> +
>      if (rw & 2) {
> -        env1->exception_index = TT_TFAULT;
> +        cpu->env.exception_index = TT_TFAULT;
>      } else {
> -        env1->exception_index = TT_DFAULT;
> +        cpu->env.exception_index = TT_DFAULT;
>      }
>      return 1;
>  }
> @@ -197,9 +199,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
>  }
>
>  /* Perform address translation */
> -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
> +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                 int mmu_idx)
>  {
> +    SPARCCPU *cpu = SPARC_CPU(cs);
> +    CPUSPARCState *env = &cpu->env;
>      hwaddr paddr;
>      target_ulong vaddr;
>      target_ulong page_size;
> @@ -211,7 +215,7 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
>      vaddr = address;
>      if (error_code == 0) {
>  #ifdef DEBUG_MMU
> -        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
> +        printf("Translate at %" VADDR_PRIx " -> " TARGET_FMT_plx ", vaddr "
>                 TARGET_FMT_lx "\n", address, paddr, vaddr);
>  #endif
>          tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
> @@ -703,9 +707,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
>  }
>
>  /* Perform address translation */
> -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
> +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
>                                 int mmu_idx)
>  {
> +    SPARCCPU *cpu = SPARC_CPU(cs);
> +    CPUSPARCState *env = &cpu->env;
>      target_ulong vaddr;
>      hwaddr paddr;
>      target_ulong page_size;
> diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
> index e5fddcf..dcf3b16 100644
> --- a/target-unicore32/cpu.c
> +++ b/target-unicore32/cpu.c
> @@ -170,7 +170,9 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
>      cc->mmu_index = uc32_cpu_mmu_index;
>      cc->set_pc = uc32_cpu_set_pc;
>      cc->get_tb_cpu_state = uc32_cpu_get_tb_cpu_state;
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +    cc->handle_mmu_fault = uc32_cpu_handle_mmu_fault;
> +#else
>      cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
>  #endif
>      dc->vmsd = &vmstate_uc32_cpu;
> diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
> index 75f5fa9..25b119f 100644
> --- a/target-unicore32/cpu.h
> +++ b/target-unicore32/cpu.h
> @@ -125,13 +125,10 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
>  #define cpu_init                        uc32_cpu_init
>  #define cpu_exec                        uc32_cpu_exec
>  #define cpu_signal_handler              uc32_cpu_signal_handler
> -#define cpu_handle_mmu_fault            uc32_cpu_handle_mmu_fault
>
>  CPUUniCore32State *uc32_cpu_init(const char *cpu_model);
>  int uc32_cpu_exec(CPUUniCore32State *s);
>  int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
> -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int rw,
> -                              int mmu_idx);
>
>  /* MMU modes definitions */
>  #define MMU_MODE0_SUFFIX _kernel
> @@ -142,6 +139,8 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int
>  #include "cpu-qom.h"
>  #include "exec/exec-all.h"
>
> +int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> +                              int mmu_idx);
>  void uc32_translate_init(void);
>  void switch_mode(CPUUniCore32State *, int);
>
> diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
> index 61eb2c3..4e90cf3 100644
> --- a/target-unicore32/helper.c
> +++ b/target-unicore32/helper.c
> @@ -250,9 +250,12 @@ void uc32_cpu_do_interrupt(CPUState *cs)
>      cpu_abort(env, "NO interrupt in user mode\n");
>  }
>
> -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
> +int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>                                int access_type, int mmu_idx)
>  {
> +    UniCore32CPU *cpu = UNICORE32_CPU(cs);
> +    CPUUniCore32State *env = &cpu->env;
> +
>      cpu_abort(env, "NO mmu fault in user mode\n");
>      return 1;
>  }
> diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
> index 4f9f41e..5cd2378 100644
> --- a/target-unicore32/op_helper.c
> +++ b/target-unicore32/op_helper.c
> @@ -258,9 +258,10 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
>  void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write,
>                int mmu_idx, uintptr_t retaddr)
>  {
> +    UniCore32CPU *cpu = uc32_env_get_cpu(env);
>      int ret;
>
> -    ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx);
> +    ret = uc32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
>      if (unlikely(ret)) {
>          if (retaddr) {
>              /* now we have a real cpu fault */
> diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
> index 1e13a85..408f1b0 100644
> --- a/target-unicore32/softmmu.c
> +++ b/target-unicore32/softmmu.c
> @@ -208,9 +208,11 @@ do_fault:
>      return code;
>  }
>
> -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
> +int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>                                int access_type, int mmu_idx)
>  {
> +    UniCore32CPU *cpu = UNICORE32_CPU(cs);
> +    CPUUniCore32State *env = &cpu->env;
>      uint32_t phys_addr;
>      target_ulong page_size;
>      int prot;
> @@ -230,7 +232,7 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
>              ret = get_phys_addr_ucv2(env, address, access_type, is_user,
>                                      &phys_addr, &prot, &page_size);
>              if (is_user) {
> -                DPRINTF("user space access: ret %x, address %x, "
> +                DPRINTF("user space access: ret %x, address %" VADDR_PRIx ", "
>                          "access_type %x, phys_addr %x, prot %x\n",
>                          ret, address, access_type, phys_addr, prot);
>              }
> diff --git a/user-exec.c b/user-exec.c
> index 82bfa66..d850d41 100644
> --- a/user-exec.c
> +++ b/user-exec.c
> @@ -82,6 +82,8 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>                                      int is_write, sigset_t *old_set,
>                                      void *puc)
>  {
> +    CPUState *cpu;
> +    CPUClass *cc;
>      CPUArchState *env;
>      int ret;
>
> @@ -99,9 +101,12 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>         are still valid segv ones */
>      address = h2g_nocheck(address);
>
> -    env = current_cpu->env_ptr;
> +    cpu = current_cpu;
> +    cc = CPU_GET_CLASS(cpu);
> +    env = cpu->env_ptr;
>      /* see if it is an MMU fault */
> -    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
> +    g_assert(cc->handle_mmu_fault);
> +    ret = cc->handle_mmu_fault(cpu, address, is_write, MMU_USER_IDX);
>      if (ret < 0) {
>          return 0; /* not an MMU fault */
>      }

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

> --
> 1.8.1.4
>

Patch

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 3d6b66e..4d974f3 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -84,6 +84,7 @@  struct TranslationBlock;
  * #TranslationBlock.
  * @synchronize_from_tb: Callback for synchronizing state from a TCG
  * #TranslationBlock.
+ * @handle_mmu_fault: Callback for handling an MMU fault.
  * @get_phys_page_debug: Callback for obtaining a physical address.
  * @gdb_read_register: Callback for letting GDB read a register.
  * @gdb_write_register: Callback for letting GDB write a register.
@@ -120,6 +121,8 @@  typedef struct CPUClass {
     void (*get_tb_cpu_state)(const CPUState *cpu, vaddr *pc, vaddr *cs_base,
                              int *flags);
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
+    int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw,
+                            int mmu_index);
     hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
     int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
     int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index bb1eddc..e880983 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -330,7 +330,9 @@  static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = alpha_cpu_get_tb_cpu_state;
     cc->gdb_read_register = alpha_cpu_gdb_read_register;
     cc->gdb_write_register = alpha_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = alpha_cpu_handle_mmu_fault;
+#else
     cc->do_unassigned_access = alpha_cpu_unassigned_access;
     cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_alpha_cpu;
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index a4abce8..dd117d9 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -435,9 +435,8 @@  int cpu_alpha_exec(CPUAlphaState *s);
    is returned if the signal was handled by the virtual CPU.  */
 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
                              void *puc);
-int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
-                                int mmu_idx);
-#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
+int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                               int mmu_idx);
 void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index fc61bb0..ef2dc25 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -168,11 +168,13 @@  void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
 }
 
 #if defined(CONFIG_USER_ONLY)
-int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address,
+int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                                int rw, int mmu_idx)
 {
-    env->exception_index = EXCP_MMFAULT;
-    env->trap_arg0 = address;
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+
+    cpu->env.exception_index = EXCP_MMFAULT;
+    cpu->env.trap_arg0 = address;
     return 1;
 }
 #else
@@ -325,9 +327,11 @@  hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     return (fail >= 0 ? -1 : phys);
 }
 
-int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw,
+int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw,
                                int mmu_idx)
 {
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
     target_ulong phys;
     int prot, fail;
 
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index 7160a1c..d140688 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -145,9 +145,10 @@  void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
+    AlphaCPU *cpu = alpha_env_get_cpu(env);
     int ret;
 
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = alpha_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (retaddr) {
             cpu_restore_state(env, retaddr);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 53bf337..4c6fe17 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -938,7 +938,9 @@  static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = arm_cpu_get_tb_cpu_state;
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 161b9fd..ce98dda 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -266,9 +266,8 @@  uint32_t do_arm_semihosting(CPUARMState *env);
    is returned if the signal was handled by the virtual CPU.  */
 int cpu_arm_signal_handler(int host_signum, void *pinfo,
                            void *puc);
-int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
-                              int mmu_idx);
-#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
+int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                             int mmu_idx);
 
 #define CPSR_M (0x1f)
 #define CPSR_T (1 << 5)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e51ef20..9d0d8b4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2078,9 +2078,12 @@  void arm_cpu_do_interrupt(CPUState *cs)
     env->exception_index = -1;
 }
 
-int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
-                              int mmu_idx)
+int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                             int mmu_idx)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+
     if (rw == 2) {
         env->exception_index = EXCP_PREFETCH_ABORT;
         env->cp15.c6_insn = address;
@@ -3026,9 +3029,11 @@  static inline int get_phys_addr(CPUARMState *env, uint32_t address,
     }
 }
 
-int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
-                              int access_type, int mmu_idx)
+int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
+                             int access_type, int mmu_idx)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
     hwaddr phys_addr;
     target_ulong page_size;
     int prot;
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index a918e5b..13d34fb 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -74,9 +74,10 @@  uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
 void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    ARMCPU *cpu = arm_env_get_cpu(env);
     int ret;
 
-    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 39a25ed..504d6a4 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -290,7 +290,9 @@  static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = cris_cpu_get_tb_cpu_state;
     cc->gdb_read_register = cris_cpu_gdb_read_register;
     cc->gdb_write_register = cris_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = cris_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
 #endif
 
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 9f1fa38..9e9cb8c 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -239,9 +239,8 @@  static inline CPUCRISState *cpu_init(const char *cpu_model)
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
 
-int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
+int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
-#define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault
 
 /* Support function regs.  */
 #define SFR_RW_GC_CFG      0][0
diff --git a/target-cris/helper.c b/target-cris/helper.c
index d274b38..72dc839 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -50,14 +50,14 @@  void crisv10_cpu_do_interrupt(CPUState *cs)
     cris_cpu_do_interrupt(cs);
 }
 
-int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
+int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                               int mmu_idx)
 {
-    CRISCPU *cpu = cris_env_get_cpu(env);
+    CRISCPU *cpu = CRIS_CPU(cs);
 
-    env->exception_index = 0xaa;
-    env->pregs[PR_EDA] = address;
-    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
+    cpu->env.exception_index = 0xaa;
+    cpu->env.pregs[PR_EDA] = address;
+    cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
 }
 
@@ -73,23 +73,25 @@  static void cris_shift_ccs(CPUCRISState *env)
     env->pregs[PR_CCS] = ccs;
 }
 
-int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
+int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                               int mmu_idx)
 {
-    D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
     struct cris_mmu_result res;
     int prot, miss;
     int r = -1;
     target_ulong phy;
 
-    D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
+    D(printf("%s addr=%" VADDR_PRIx " pc=%x rw=%x\n",
+             __func__, address, env->pc, rw));
     miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
                               rw, mmu_idx, 0);
     if (miss) {
         if (env->exception_index == EXCP_BUSFAULT) {
             cpu_abort(env,
                       "CRIS: Illegal recursive bus fault."
-                      "addr=%x rw=%d\n",
+                      "addr=%" VADDR_PRIx " rw=%d\n",
                       address, rw);
         }
 
@@ -109,8 +111,8 @@  int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
         r = 0;
     }
     if (r > 0) {
-        D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
-              __func__, r, cpu->interrupt_request, address, res.phy,
+        D_LOG("%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x"
+              " pc=%x\n", __func__, r, cs->interrupt_request, address, res.phy,
               res.bf_vec, env->pc);
     }
     return r;
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index b580513..4a6215d 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -57,11 +57,12 @@ 
 void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    CRISCPU *cpu = cris_env_get_cpu(env);
     int ret;
 
     D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
           env->pc, env->pregs[PR_EDA], (void *)retaddr);
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = cris_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 995d5ff..3ed5a11 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2743,7 +2743,9 @@  static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->gdb_write_register = x86_cpu_gdb_write_register;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
+#else
     cc->get_memory_mapping = x86_cpu_get_memory_mapping;
     cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
     cc->write_elf64_note = x86_cpu_write_elf64_note;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 999a46c..3620699 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1042,9 +1042,8 @@  void host_cpuid(uint32_t function, uint32_t count,
                 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
 
 /* helper.c */
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr,
                              int is_write, int mmu_idx);
-#define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
 void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
 
 static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 7c58e27..b25dafc 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -485,9 +485,12 @@  void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
 
 #if defined(CONFIG_USER_ONLY)
 
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
                              int is_write, int mmu_idx)
 {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
     /* user mode only emulation */
     is_write &= 1;
     env->cr[2] = addr;
@@ -508,13 +511,15 @@  int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
 # endif
 
 /* return value:
-   -1 = cannot handle fault
-   0  = nothing more to do
-   1  = generate PF fault
-*/
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+ * -1 = cannot handle fault
+ * 0  = nothing more to do
+ * 1  = generate PF fault
+ */
+int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
                              int is_write1, int mmu_idx)
 {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     uint64_t ptep, pte;
     target_ulong pde_addr, pte_addr;
     int error_code, is_dirty, prot, page_size, is_write, is_user;
@@ -524,7 +529,7 @@  int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
 
     is_user = mmu_idx == MMU_USER_IDX;
 #if defined(DEBUG_MMU)
-    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
+    printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
            addr, is_write1, is_user, env->eip);
 #endif
     is_write = is_write1 & 1;
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 319a219..5b25ccd 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -135,9 +135,10 @@  void helper_boundl(CPUX86State *env, target_ulong a0, int v)
 void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
     int ret;
 
-    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 7976d39..607e332 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -108,7 +108,9 @@  static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = lm32_cpu_get_tb_cpu_state;
     cc->gdb_read_register = lm32_cpu_gdb_read_register;
     cc->gdb_write_register = lm32_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_lm32_cpu;
 #endif
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index a34f047..a94fd79 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -207,9 +207,8 @@  static inline CPULM32State *cpu_init(const char *cpu_model)
 #define cpu_gen_code cpu_lm32_gen_code
 #define cpu_signal_handler cpu_lm32_signal_handler
 
-int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
+int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
-#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault
 
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 15bc615..55a3de6 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -20,9 +20,11 @@ 
 #include "cpu.h"
 #include "qemu/host-utils.h"
 
-int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
+int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                               int mmu_idx)
 {
+    LM32CPU *cpu = LM32_CPU(cs);
+    CPULM32State *env = &cpu->env;
     int prot;
 
     address &= TARGET_PAGE_MASK;
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 8f5ef55..215215e 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -80,9 +80,10 @@  uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
 void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    LM32CPU *cpu = lm32_env_get_cpu(env);
     int ret;
 
-    ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = lm32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 6dbfe89..e46b647 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -222,7 +222,9 @@  static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->get_tb_cpu_state = m68k_cpu_get_tb_cpu_state;
     cc->gdb_read_register = m68k_cpu_gdb_read_register;
     cc->gdb_write_register = m68k_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_m68k_cpu;
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 5c7992e..b8ad269 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -233,9 +233,8 @@  static inline CPUM68KState *cpu_init(const char *cpu_model)
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
 
-int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw,
+int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
-#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault
 
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 00a7a08..25a0570 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -278,11 +278,13 @@  void m68k_switch_sp(CPUM68KState *env)
 
 #if defined(CONFIG_USER_ONLY)
 
-int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
-                               int mmu_idx)
+int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                              int mmu_idx)
 {
-    env->exception_index = EXCP_ACCESS;
-    env->mmu.ar = address;
+    M68kCPU *cpu = M68K_CPU(cs);
+
+    cpu->env.exception_index = EXCP_ACCESS;
+    cpu->env.mmu.ar = address;
     return 1;
 }
 
@@ -296,14 +298,15 @@  hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     return addr;
 }
 
-int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
-                               int mmu_idx)
+int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                              int mmu_idx)
 {
+    M68kCPU *cpu = M68K_CPU(cs);
     int prot;
 
     address &= TARGET_PAGE_MASK;
     prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-    tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
+    tlb_set_page(&cpu->env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
     return 0;
 }
 
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 30f7d8b..bc10f38 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -59,9 +59,10 @@  extern int semihosting_enabled;
 void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
     int ret;
 
-    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = m68k_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index fbcdcc4..8b248f4 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -178,7 +178,9 @@  static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = mb_cpu_get_tb_cpu_state;
     cc->gdb_read_register = mb_cpu_gdb_read_register;
     cc->gdb_write_register = mb_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = mb_cpu_handle_mmu_fault;
+#else
     cc->do_unassigned_access = mb_cpu_unassigned_access;
     cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
 #endif
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index d80f812..1177e51 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -316,9 +316,8 @@  static inline CPUMBState *cpu_init(const char *cpu_model)
 #define MMU_USER_IDX    2
 /* See NB_MMU_MODES further up the file.  */
 
-int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw,
+int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                             int mmu_idx);
-#define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
 
 static inline int cpu_interrupts_enabled(CPUMBState *env)
 {
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 4fa9ce9..d03f369 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -36,21 +36,23 @@  void mb_cpu_do_interrupt(CPUState *cs)
     env->regs[14] = env->sregs[SR_PC];
 }
 
-int cpu_mb_handle_mmu_fault(CPUMBState * env, target_ulong address, int rw,
+int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                             int mmu_idx)
 {
-    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 
-    env->exception_index = 0xaa;
-    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
+    cpu->env.exception_index = 0xaa;
+    cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
 }
 
 #else /* !CONFIG_USER_ONLY */
 
-int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw,
-                             int mmu_idx)
+int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                            int mmu_idx)
 {
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
     unsigned int hit;
     unsigned int mmu_available;
     int r = 1;
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 14baa84..b70b2ea 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -44,9 +44,10 @@ 
 void tlb_fill(CPUMBState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
     int ret;
 
-    ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = mb_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 4aa06bb..2fd5591 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -153,7 +153,9 @@  static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
     cc->gdb_read_register = mips_cpu_gdb_read_register;
     cc->gdb_write_register = mips_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = mips_cpu_handle_mmu_fault;
+#else
     cc->do_unassigned_access = mips_cpu_unassigned_access;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
 #endif
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 91217ed..b71a711 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -649,9 +649,8 @@  void cpu_mips_stop_count(CPUMIPSState *env);
 void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
 
 /* helper.c */
-int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
-                               int mmu_idx);
-#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
+int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                              int mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
 void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
 hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 33e0e88..d8e9166 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -268,9 +268,11 @@  hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
-int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
-                               int mmu_idx)
+int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                              int mmu_idx)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
 #if !defined(CONFIG_USER_ONLY)
     hwaddr physical;
     int prot;
@@ -279,9 +281,9 @@  int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
     int ret = 0;
 
 #if 0
-    log_cpu_state(CPU(mips_env_get_cpu(env)), 0);
+    log_cpu_state(cs, 0);
 #endif
-    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
+    qemu_log("%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
               __func__, env->active_tc.PC, address, rw, mmu_idx);
 
     rw &= 1;
@@ -293,8 +295,9 @@  int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
     access_type = ACCESS_INT;
     ret = get_physical_address(env, &physical, &prot,
                                address, rw, access_type);
-    qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n",
-              __func__, address, ret, physical, prot);
+    qemu_log("%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
+             " prot %d\n",
+             __func__, address, ret, physical, prot);
     if (ret == TLBRET_MATCH) {
         tlb_set_page(env, address & TARGET_PAGE_MASK,
                      physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 8e3a6d7..34ac4c6 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2134,9 +2134,10 @@  static void do_unaligned_access(CPUMIPSState *env, target_ulong addr,
 void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    MIPSCPU *cpu = mips_env_get_cpu(env);
     int ret;
 
-    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = mips_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (ret) {
         do_raise_exception_err(env, env->exception_index,
                                env->error_code, retaddr);
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 9983c99..e07a4df 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -119,7 +119,9 @@  static void moxie_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = moxie_cpu_dump_state;
     cc->set_pc = moxie_cpu_set_pc;
     cc->get_tb_cpu_state = moxie_cpu_get_tb_cpu_state;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = moxie_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_moxie_cpu;
 #endif
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 7e33efe..fb2a97e 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -139,7 +139,7 @@  static inline CPUMoxieState *cpu_init(const char *cpu_model)
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
-int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
+int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
                                int rw, int mmu_idx);
 
 #endif /* _CPU_MOXIE_H */
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 7859102..8160475 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -49,9 +49,10 @@ 
 void tlb_fill(CPUMoxieState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    MoxieCPU *cpu = moxie_env_get_cpu(env);
     int ret;
 
-    ret = cpu_moxie_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = moxie_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             cpu_restore_state(env, retaddr);
@@ -103,27 +104,29 @@  void helper_debug(CPUMoxieState *env)
 
 #if defined(CONFIG_USER_ONLY)
 
-void moxie_cpu_do_interrupt(CPUState *env)
+void moxie_cpu_do_interrupt(CPUState *cs)
 {
     env->exception_index = -1;
 }
 
-int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
+int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                                int rw, int mmu_idx)
 {
-    MoxieCPU *cpu = moxie_env_get_cpu(env);
+    MoxieCPU *cpu = MOXIE_CPU(cs);
 
-    env->exception_index = 0xaa;
-    env->debug1 = address;
-    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
+    cpu->env.exception_index = 0xaa;
+    cpu->env.debug1 = address;
+    cpu_dump_state(cs, stderr, fprintf, 0);
     return 1;
 }
 
 #else /* !CONFIG_USER_ONLY */
 
-int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
+int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                                int rw, int mmu_idx)
 {
+    MoxieCPU *cpu = MOXIE_CPU(cs);
+    CPUMoxieState *env = &cpu->env;
     MoxieMMUResult res;
     int prot, miss;
     target_ulong phy;
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 107e5f9..ee1591d 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -188,7 +188,9 @@  static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = openrisc_cpu_get_tb_cpu_state;
     cc->gdb_read_register = openrisc_cpu_gdb_read_register;
     cc->gdb_write_register = openrisc_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = openrisc_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_openrisc_cpu;
 #endif
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index a41c271..8745072 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -353,15 +353,13 @@  hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
-int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
-                                  target_ulong address,
+int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
                                   int rw, int mmu_idx);
 int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_list cpu_openrisc_list
 #define cpu_exec cpu_openrisc_exec
 #define cpu_gen_code cpu_openrisc_gen_code
-#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
 #define cpu_signal_handler cpu_openrisc_signal_handler
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index 57f5616..0f13c5d 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -181,19 +181,19 @@  static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
 }
 
 #ifndef CONFIG_USER_ONLY
-int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
-                                  target_ulong address, int rw, int mmu_idx)
+int openrisc_cpu_handle_mmu_fault(CPUState *cs,
+                                  vaddr address, int rw, int mmu_idx)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     int ret = 0;
     hwaddr physical = 0;
     int prot = 0;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
     ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot,
                                      address, rw);
 
     if (ret == TLBRET_MATCH) {
-        tlb_set_page(env, address & TARGET_PAGE_MASK,
+        tlb_set_page(&cpu->env, address & TARGET_PAGE_MASK,
                      physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
                      mmu_idx, TARGET_PAGE_SIZE);
         ret = 0;
@@ -205,11 +205,11 @@  int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
     return ret;
 }
 #else
-int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
-                                  target_ulong address, int rw, int mmu_idx)
+int openrisc_cpu_handle_mmu_fault(CPUState *cs,
+                                  vaddr address, int rw, int mmu_idx)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     int ret = 0;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
     cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
     ret = 1;
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
index e46b092..b023a5f 100644
--- a/target-openrisc/mmu_helper.c
+++ b/target-openrisc/mmu_helper.c
@@ -39,9 +39,10 @@ 
 void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     int ret;
 
-    ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = openrisc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
 
     if (ret) {
         if (retaddr) {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 2ebf0a1..3b03ae6 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1098,8 +1098,8 @@  int cpu_ppc_signal_handler (int host_signum, void *pinfo,
                             void *puc);
 void ppc_hw_interrupt (CPUPPCState *env);
 #if defined(CONFIG_USER_ONLY)
-int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
-                         int mmu_idx);
+int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                             int mmu_idx);
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 338d8fe..8b6fbb5 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8595,7 +8595,9 @@  static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = ppc_cpu_get_tb_cpu_state;
     cc->gdb_read_register = ppc_cpu_gdb_read_register;
     cc->gdb_write_register = ppc_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_ppc_cpu;
 #endif
diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
index 56e686e..a7c99e0 100644
--- a/target-ppc/user_only_helper.c
+++ b/target-ppc/user_only_helper.c
@@ -20,9 +20,11 @@ 
 
 #include "cpu.h"
 
-int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
-                         int mmu_idx)
+int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                             int mmu_idx)
 {
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     int exception, error_code;
 
     if (rw == 2) {
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index a4a5370..ad0d5bc 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -257,7 +257,9 @@  static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_tb_cpu_state = s390_cpu_get_tb_cpu_state;
     cc->gdb_read_register = s390_cpu_gdb_read_register;
     cc->gdb_write_register = s390_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = s390_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
     cc->write_elf64_note = s390_cpu_write_elf64_note;
     cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote;
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index cad092b..a09e4f9 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -308,9 +308,8 @@  int cpu_s390x_exec(CPUS390XState *s);
    is returned if the signal was handled by the virtual CPU.  */
 int cpu_s390x_signal_handler(int host_signum, void *pinfo,
                            void *puc);
-int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
-                                int mmu_idx);
-#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
+int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                              int mmu_idx);
 
 #include "ioinst.h"
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 61abfd7..361d713 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -94,14 +94,16 @@  void s390_cpu_do_interrupt(CPUState *cs)
     env->exception_index = -1;
 }
 
-int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
-                               int rw, int mmu_idx)
+int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
+                              int rw, int mmu_idx)
 {
-    env->exception_index = EXCP_PGM;
-    env->int_pgm_code = PGM_ADDRESSING;
+    S390CPU *cpu = S390_CPU(cs);
+
+    cpu->env.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.  */
-    env->__excp_addr = address;
+    cpu->env.__excp_addr = address;
     return 1;
 }
 
@@ -377,14 +379,16 @@  int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
     return r;
 }
 
-int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
-                               int rw, int mmu_idx)
+int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr,
+                              int rw, int mmu_idx)
 {
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
     target_ulong vaddr, raddr;
     int prot;
 
-    DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
+    DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
             __func__, orig_vaddr, rw, mmu_idx);
 
     orig_vaddr &= TARGET_PAGE_MASK;
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 1422ae9..747ba46 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -47,9 +47,10 @@ 
 void tlb_fill(CPUS390XState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    S390CPU *cpu = s390_env_get_cpu(env);
     int ret;
 
-    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = s390_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 647a527..7f98f80 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -320,7 +320,9 @@  static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
     cc->gdb_read_register = superh_cpu_gdb_read_register;
     cc->gdb_write_register = superh_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = superh_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_sh_cpu;
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 42ecdd7..8abd0cc 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -193,9 +193,8 @@  SuperHCPU *cpu_sh4_init(const char *cpu_model);
 int cpu_sh4_exec(CPUSH4State * s);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
                            void *puc);
-int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
-                             int mmu_idx);
-#define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault
+int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                                int mmu_idx);
 
 void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 9ac2825..3f8f1fa 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -39,9 +39,12 @@  void superh_cpu_do_interrupt(CPUState *cs)
     env->exception_index = -1;
 }
 
-int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
-                             int mmu_idx)
+int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                                int mmu_idx)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
+
     env->tea = address;
     env->exception_index = -1;
     switch (rw) {
@@ -447,9 +450,11 @@  static int get_physical_address(CPUSH4State * env, target_ulong * physical,
     return get_mmu_address(env, physical, prot, address, rw, access_type);
 }
 
-int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
-                             int mmu_idx)
+int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                                int mmu_idx)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
     target_ulong physical;
     int prot, ret, access_type;
 
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index e955e81..35f9067 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -41,9 +41,10 @@ 
 void tlb_fill(CPUSH4State *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    SuperHCPU *cpu = sh_env_get_cpu(env);
     int ret;
 
-    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = superh_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (ret) {
         /* now we have a real cpu fault */
         if (retaddr) {
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 49a4469..c8d8c55 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -857,7 +857,9 @@  static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
     cc->gdb_read_register = sparc_cpu_gdb_read_register;
     cc->gdb_write_register = sparc_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault;
+#else
     cc->do_unassigned_access = sparc_cpu_unassigned_access;
     cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
 #endif
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index f078851..cfa1e0d 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -519,9 +519,8 @@  SPARCCPU *cpu_sparc_init(const char *cpu_model);
 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 /* mmu_helper.c */
-int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
+int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                                int mmu_idx);
-#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault
 target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
 
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 2936b58..2f55af9 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2432,9 +2432,10 @@  static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
 void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
+    SPARCCPU *cpu = sparc_env_get_cpu(env);
     int ret;
 
-    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = sparc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             cpu_restore_state(env, retaddr);
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 9eb096e..0d88326 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -25,13 +25,15 @@ 
 
 #if defined(CONFIG_USER_ONLY)
 
-int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
+int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                                int mmu_idx)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+
     if (rw & 2) {
-        env1->exception_index = TT_TFAULT;
+        cpu->env.exception_index = TT_TFAULT;
     } else {
-        env1->exception_index = TT_DFAULT;
+        cpu->env.exception_index = TT_DFAULT;
     }
     return 1;
 }
@@ -197,9 +199,11 @@  static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
 }
 
 /* Perform address translation */
-int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
+int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                                int mmu_idx)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     hwaddr paddr;
     target_ulong vaddr;
     target_ulong page_size;
@@ -211,7 +215,7 @@  int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
     vaddr = address;
     if (error_code == 0) {
 #ifdef DEBUG_MMU
-        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
+        printf("Translate at %" VADDR_PRIx " -> " TARGET_FMT_plx ", vaddr "
                TARGET_FMT_lx "\n", address, paddr, vaddr);
 #endif
         tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
@@ -703,9 +707,11 @@  static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
 }
 
 /* Perform address translation */
-int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
+int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                                int mmu_idx)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     target_ulong vaddr;
     hwaddr paddr;
     target_ulong page_size;
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index e5fddcf..dcf3b16 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -170,7 +170,9 @@  static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->mmu_index = uc32_cpu_mmu_index;
     cc->set_pc = uc32_cpu_set_pc;
     cc->get_tb_cpu_state = uc32_cpu_get_tb_cpu_state;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = uc32_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_uc32_cpu;
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 75f5fa9..25b119f 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -125,13 +125,10 @@  void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
 #define cpu_init                        uc32_cpu_init
 #define cpu_exec                        uc32_cpu_exec
 #define cpu_signal_handler              uc32_cpu_signal_handler
-#define cpu_handle_mmu_fault            uc32_cpu_handle_mmu_fault
 
 CPUUniCore32State *uc32_cpu_init(const char *cpu_model);
 int uc32_cpu_exec(CPUUniCore32State *s);
 int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
-int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int rw,
-                              int mmu_idx);
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
@@ -142,6 +139,8 @@  int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int
 #include "cpu-qom.h"
 #include "exec/exec-all.h"
 
+int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                              int mmu_idx);
 void uc32_translate_init(void);
 void switch_mode(CPUUniCore32State *, int);
 
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 61eb2c3..4e90cf3 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -250,9 +250,12 @@  void uc32_cpu_do_interrupt(CPUState *cs)
     cpu_abort(env, "NO interrupt in user mode\n");
 }
 
-int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
+int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                               int access_type, int mmu_idx)
 {
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
+
     cpu_abort(env, "NO mmu fault in user mode\n");
     return 1;
 }
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 4f9f41e..5cd2378 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -258,9 +258,10 @@  uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
 void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
+    UniCore32CPU *cpu = uc32_env_get_cpu(env);
     int ret;
 
-    ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    ret = uc32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
index 1e13a85..408f1b0 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -208,9 +208,11 @@  do_fault:
     return code;
 }
 
-int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
+int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                               int access_type, int mmu_idx)
 {
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
     uint32_t phys_addr;
     target_ulong page_size;
     int prot;
@@ -230,7 +232,7 @@  int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
             ret = get_phys_addr_ucv2(env, address, access_type, is_user,
                                     &phys_addr, &prot, &page_size);
             if (is_user) {
-                DPRINTF("user space access: ret %x, address %x, "
+                DPRINTF("user space access: ret %x, address %" VADDR_PRIx ", "
                         "access_type %x, phys_addr %x, prot %x\n",
                         ret, address, access_type, phys_addr, prot);
             }
diff --git a/user-exec.c b/user-exec.c
index 82bfa66..d850d41 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -82,6 +82,8 @@  static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
+    CPUState *cpu;
+    CPUClass *cc;
     CPUArchState *env;
     int ret;
 
@@ -99,9 +101,12 @@  static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
        are still valid segv ones */
     address = h2g_nocheck(address);
 
-    env = current_cpu->env_ptr;
+    cpu = current_cpu;
+    cc = CPU_GET_CLASS(cpu);
+    env = cpu->env_ptr;
     /* see if it is an MMU fault */
-    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
+    g_assert(cc->handle_mmu_fault);
+    ret = cc->handle_mmu_fault(cpu, address, is_write, MMU_USER_IDX);
     if (ret < 0) {
         return 0; /* not an MMU fault */
     }