diff mbox

[qom-cpu,v2,09/40] cpu: Turn cpu_handle_mmu_fault() into a CPUClass hook

Message ID 1394410549-13751-10-git-send-email-afaerber@suse.de
State New
Headers show

Commit Message

Andreas Färber March 10, 2014, 12:15 a.m. UTC
Note that while such functions may exist both for *-user and softmmu,
only *-user uses the CPUState hook, while softmmu reuses the prototype
for calling it directly.

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          | 20 ++++++++++++--------
 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(+), 151 deletions(-)

Comments

Paolo Bonzini March 10, 2014, 7:52 a.m. UTC | #1
Il 10/03/2014 01:15, Andreas Färber ha scritto:
> Note that while such functions may exist both for *-user and softmmu,
> only *-user uses the CPUState hook, while softmmu reuses the prototype
> for calling it directly.

I'm not sure I understand why you omit the hook for *-softmmu.  It 
doesn't hurt to have it, does it?

Paolo
Andreas Färber March 11, 2014, 11:47 p.m. UTC | #2
Am 10.03.2014 08:52, schrieb Paolo Bonzini:
> Il 10/03/2014 01:15, Andreas Färber ha scritto:
>> Note that while such functions may exist both for *-user and softmmu,
>> only *-user uses the CPUState hook, while softmmu reuses the prototype
>> for calling it directly.
> 
> I'm not sure I understand why you omit the hook for *-softmmu.  It
> doesn't hurt to have it, does it?

Actually I wondered the same thing while preparing v2 :) and prepared an
alternate version, but it did not really help cut down on complexity.

The hook is needed for dispatching from common code to target code, and
that part is user-only. Some targets but not all reuse the user function
from softmmu code, others have two different implementations, some don't
reuse at all. It's a mess.

Andreas
Paolo Bonzini March 12, 2014, 5:58 p.m. UTC | #3
Il 12/03/2014 00:47, Andreas Färber ha scritto:
>> > I'm not sure I understand why you omit the hook for *-softmmu.  It
>> > doesn't hurt to have it, does it?
> Actually I wondered the same thing while preparing v2 :) and prepared an
> alternate version, but it did not really help cut down on complexity.

No, I agree it doesn't.  Just in case common non-user-only code will 
need it in the future.

> The hook is needed for dispatching from common code to target code, and
> that part is user-only. Some targets but not all reuse the user function
> from softmmu code, others have two different implementations, some don't
> reuse at all. It's a mess.

Ok, that explains it. :)

Paolo
diff mbox

Patch

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f5b0d7a..5af434d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -83,6 +83,7 @@  struct TranslationBlock;
  * @set_pc: Callback for setting the Program Counter register.
  * @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.
@@ -117,6 +118,8 @@  typedef struct CPUClass {
                                Error **errp);
     void (*set_pc)(CPUState *cpu, vaddr value);
     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 cf2a315..4d8263f 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -288,7 +288,9 @@  static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = alpha_cpu_set_pc;
     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 a172124..07d9f63 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -446,9 +446,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 98ddcdf..9c94b43 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
@@ -326,9 +328,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 e1aba64..d195935 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -153,9 +153,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 d792a91..be17d72 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1013,7 +1013,9 @@  static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = arm_cpu_set_pc;
     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 4fd1e81..7f0a904 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -335,9 +335,8 @@  static inline bool is_a64(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);
 
 /* SCTLR bit meanings. Several bits have been reused in newer
  * versions of the architecture; in that case we define constants
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 09b8a32..cf23a03 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2574,9 +2574,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;
@@ -3542,9 +3545,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 7d06d2f..dfdbfb0 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 12c90ee..ff27e7f 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -283,7 +283,9 @@  static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = cris_cpu_set_pc;
     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 1287cad..6cc0616 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -247,9 +247,8 @@  static inline int cpu_mmu_index (CPUCRISState *env)
 	return !!(env->pregs[PR_CCS] & U_FLAG);
 }
 
-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 c940582..857cc99 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 533bf7c..6b2bfcb 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2806,7 +2806,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 2403321..62641af 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1067,9 +1067,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 11c7219..696bbf5 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,14 +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)
 {
-    CPUState *cs = CPU(x86_env_get_cpu(env));
+    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;
@@ -525,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 c157f52..daec499 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -266,7 +266,9 @@  static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = lm32_cpu_set_pc;
     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 e6314c0..b94d9b0 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -231,9 +231,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"
 
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index e813e7d..ce6dd45 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 7189cb5..774dc65 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -153,9 +153,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 7d66ed0..46601dc 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -200,7 +200,9 @@  static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->set_pc = m68k_cpu_set_pc;
     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 5f79d2a..dd1794f 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -237,9 +237,8 @@  static inline int cpu_mmu_index (CPUM68KState *env)
     return (env->sr & SR_S) == 0 ? 1 : 0;
 }
 
-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"
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index a364eb1..0ffb861 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -277,11 +277,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;
 }
 
@@ -295,14 +297,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 bbbfd7f..539d1d6 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 bbda0fd..86ec258 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -171,7 +171,9 @@  static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = mb_cpu_set_pc;
     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 78a7661..6ccd060 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -332,9 +332,8 @@  static inline int cpu_mmu_index (CPUMBState *env)
         return MMU_KERNEL_IDX;
 }
 
-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 0a2dc46..8c304ac 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -133,7 +133,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 6981e7a..a1d85ef 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -666,9 +666,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 2ef6633..a62496c 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2146,9 +2146,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 32c6104..03d8eb1 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -108,7 +108,9 @@  static void moxie_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = moxie_cpu_do_interrupt;
     cc->dump_state = moxie_cpu_dump_state;
     cc->set_pc = moxie_cpu_set_pc;
-#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 778cfc0..c5b12a5 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -152,7 +152,7 @@  static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
     *flags = 0;
 }
 
-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 0b2ffb2..99e4aa7 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -165,7 +165,9 @@  static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = openrisc_cpu_set_pc;
     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 ae9d17f..660bb4f 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 dd487bd..1fd0a0a 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -174,19 +174,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,
                      mmu_idx, TARGET_PAGE_SIZE);
         ret = 0;
@@ -198,11 +198,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 501dd03..acf6909 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1111,8 +1111,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 0418f06..703b3d8 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8507,7 +8507,9 @@  static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = ppc_cpu_set_pc;
     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;
 #if defined(TARGET_PPC64)
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 5dac322..993d924 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -247,7 +247,9 @@  static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = s390_cpu_set_pc;
     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 8b4a5c0..f332d41 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -320,9 +320,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 0bae0a3..e71e5fd 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -91,14 +91,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;
 }
 
@@ -379,14 +381,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 db673cf..d9dc8ae 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 8e7bcd2..88960c8 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -281,7 +281,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 808f90f..a855710 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 42c6de9..a259173 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -820,7 +820,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 340a63d..1c99db7 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 b575760..847d7c2 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2437,9 +2437,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 511eb7e..5a9748e 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;
 }
@@ -198,9 +200,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;
@@ -212,7 +216,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);
@@ -705,9 +709,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 1cfe50a..24dec13 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -148,7 +148,9 @@  static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
-#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 1db7419..50972f9 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
@@ -157,6 +154,8 @@  static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc
     }
 }
 
+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 a1f86b0..29cf575 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -242,9 +242,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 9552f69..75f7386 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -209,9 +209,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;
@@ -231,7 +233,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 */
     }