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

login
register
mail settings
Submitter Andreas Färber
Date June 29, 2013, 8:01 p.m.
Message ID <1372536117-28167-34-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/255770/
State New
Headers show

Comments

Andreas Färber - June 29, 2013, 8:01 p.m.
Since all targets now assign a softmmu-only field, we can drop helpers
cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd().

Prepares for changing cpu_memory_rw_debug() argument to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 exec.c                      | 20 ++++++------
 hw/i386/kvmvapic.c          |  6 ++--
 include/exec/cpu-all.h      |  5 ---
 include/qom/cpu.h           | 74 +++++++++++++--------------------------------
 target-alpha/cpu-qom.h      |  1 +
 target-alpha/cpu.c          |  7 +++--
 target-alpha/helper.c       |  5 +--
 target-arm/cpu-qom.h        |  2 ++
 target-arm/cpu.c            |  5 ++-
 target-arm/helper.c         |  8 +++--
 target-cris/cpu-qom.h       |  2 ++
 target-cris/cpu.c           |  3 ++
 target-cris/helper.c        |  7 +++--
 target-i386/cpu-qom.h       |  2 ++
 target-i386/cpu.c           |  3 +-
 target-i386/helper.c        |  4 ++-
 target-lm32/cpu-qom.h       |  1 +
 target-lm32/cpu.c           |  5 ++-
 target-lm32/helper.c        |  6 ++--
 target-m68k/cpu-qom.h       |  1 +
 target-m68k/cpu.c           |  3 ++
 target-m68k/helper.c        |  2 +-
 target-microblaze/cpu-qom.h |  1 +
 target-microblaze/cpu.c     |  5 ++-
 target-microblaze/helper.c  |  4 ++-
 target-mips/cpu-qom.h       |  1 +
 target-mips/cpu.c           |  5 ++-
 target-mips/helper.c        |  7 +++--
 target-moxie/cpu.c          |  5 ++-
 target-moxie/cpu.h          |  1 +
 target-moxie/helper.c       | 11 +++----
 target-openrisc/cpu.c       |  5 ++-
 target-openrisc/cpu.h       |  1 +
 target-openrisc/mmu.c       |  5 ++-
 target-ppc/cpu-qom.h        |  1 +
 target-ppc/mmu_helper.c     |  4 ++-
 target-s390x/cpu-qom.h      |  1 +
 target-s390x/cpu.c          |  3 ++
 target-s390x/helper.c       |  5 +--
 target-sh4/cpu-qom.h        |  1 +
 target-sh4/cpu.c            |  3 ++
 target-sh4/helper.c         |  5 +--
 target-sparc/cpu-qom.h      |  1 +
 target-sparc/cpu.c          |  5 ++-
 target-sparc/mmu_helper.c   | 11 ++++---
 target-unicore32/cpu-qom.h  |  1 +
 target-unicore32/cpu.c      |  3 ++
 target-unicore32/softmmu.c  |  7 +++--
 target-xtensa/cpu-qom.h     |  1 +
 target-xtensa/cpu.c         |  3 ++
 target-xtensa/helper.c      |  7 +++--
 target-xtensa/xtensa-semi.c |  4 +--
 52 files changed, 168 insertions(+), 121 deletions(-)

Patch

diff --git a/exec.c b/exec.c
index 56a1d84..359dc64 100644
--- a/exec.c
+++ b/exec.c
@@ -411,14 +411,14 @@  void cpu_exec_init(CPUArchState *env)
 
 #if defined(TARGET_HAS_ICE)
 #if defined(CONFIG_USER_ONLY)
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
     tb_invalidate_phys_page_range(pc, pc + 1, 0);
 }
 #else
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
-    tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) |
+    tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
             (pc & ~TARGET_PAGE_MASK));
 }
 #endif
@@ -521,15 +521,17 @@  int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
     bp->flags = flags;
 
     /* keep all GDB-injected breakpoints in front */
-    if (flags & BP_GDB)
+    if (flags & BP_GDB) {
         QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
-    else
+    } else {
         QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
+    }
 
-    breakpoint_invalidate(env, pc);
+    breakpoint_invalidate(ENV_GET_CPU(env), pc);
 
-    if (breakpoint)
+    if (breakpoint) {
         *breakpoint = bp;
+    }
     return 0;
 #else
     return -ENOSYS;
@@ -560,7 +562,7 @@  void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
 #if defined(TARGET_HAS_ICE)
     QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
 
-    breakpoint_invalidate(env, breakpoint->pc);
+    breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
 
     g_free(breakpoint);
 #endif
@@ -2572,7 +2574,7 @@  int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 
     while (len > 0) {
         page = addr & TARGET_PAGE_MASK;
-        phys_addr = cpu_get_phys_page_debug(env, page);
+        phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page);
         /* if no physical page mapped, return an error */
         if (phys_addr == -1)
             return -1;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index d60864e..76fca34 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -146,6 +146,7 @@  static void update_guest_rom_state(VAPICROMState *s)
 
 static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     hwaddr paddr;
     target_ulong addr;
 
@@ -158,7 +159,7 @@  static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
      * virtual address space for the APIC mapping.
      */
     for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
-        paddr = cpu_get_phys_page_debug(env, addr);
+        paddr = cpu_get_phys_page_debug(cs, addr);
         if (paddr != APIC_DEFAULT_ADDRESS) {
             continue;
         }
@@ -271,6 +272,7 @@  instruction_ok:
 
 static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     hwaddr paddr;
     uint32_t rom_state_vaddr;
     uint32_t pos, patch, offset;
@@ -287,7 +289,7 @@  static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
 
     /* find out virtual address of the ROM */
     rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
-    paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
+    paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr);
     if (paddr == -1) {
         return -1;
     }
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 1f3c002..16eeb7a 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -430,11 +430,6 @@  void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
 
 #if !defined(CONFIG_USER_ONLY)
 
-/* Return the physical page corresponding to a virtual one. Use it
-   only for debugging because no protection checks are done. Return -1
-   if no page found. */
-hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
-
 /* memory API */
 
 extern int phys_ram_fd;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index cd10b1d..9717650 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -61,6 +61,7 @@  typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
+ * @get_phys_page_debug: Callback for obtaining a physical address.
  * @vmsd: State description for migration.
  *
  * Represents a CPU family or model.
@@ -86,6 +87,7 @@  typedef struct CPUClass {
                                Error **errp);
     void (*set_pc)(CPUState *cpu, uint64_t value);
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
+    hwaddr (*get_phys_page_debug)(CPUState *cpu, uint64_t addr);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@@ -262,6 +264,25 @@  void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 
+#ifndef CONFIG_USER_ONLY
+/**
+ * cpu_get_phys_page_debug:
+ * @cpu: The CPU to obtain the physical page address for.
+ * @addr: The virtual address.
+ *
+ * Obtains the physical page corresponding to a virtual one.
+ * Use it only for debugging because no protection checks are done.
+ *
+ * Returns: Corresponding physical page address or -1 if no page found.
+ */
+static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    return cc->get_phys_page_debug(cpu, addr);
+}
+#endif
+
 /**
  * cpu_reset:
  * @cpu: The CPU whose state is to be reset.
@@ -280,59 +301,6 @@  void cpu_reset(CPUState *cpu);
 ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
 
 /**
- * cpu_class_set_vmsd:
- * @cc: CPU class
- * @value: Value to set. Unused for %CONFIG_USER_ONLY.
- *
- * Sets #VMStateDescription for @cc.
- *
- * The @value argument is intentionally discarded for the non-softmmu targets
- * to avoid linker errors or excessive preprocessor usage. If this behavior
- * is undesired, you should assign #CPUClass.vmsd directly instead.
- */
-#ifndef CONFIG_USER_ONLY
-static inline void cpu_class_set_vmsd(CPUClass *cc,
-                                      const struct VMStateDescription *value)
-{
-    cc->vmsd = value;
-}
-#else
-#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
-#endif
-
-#ifndef CONFIG_USER_ONLY
-static inline void cpu_class_set_do_unassigned_access(CPUClass *cc,
-                                                      CPUUnassignedAccess value)
-{
-    cc->do_unassigned_access = value;
-}
-#else
-#define cpu_class_set_do_unassigned_access(cc, value) \
-    ((cc)->do_unassigned_access = NULL)
-#endif
-
-/**
- * device_class_set_vmsd:
- * @dc: Device class
- * @value: Value to set. Unused for %CONFIG_USER_ONLY.
- *
- * Sets #VMStateDescription for @dc.
- *
- * The @value argument is intentionally discarded for the non-softmmu targets
- * to avoid linker errors or excessive preprocessor usage. If this behavior
- * is undesired, you should assign #DeviceClass.vmsd directly instead.
- */
-#ifndef CONFIG_USER_ONLY
-static inline void device_class_set_vmsd(DeviceClass *dc,
-                                         const struct VMStateDescription *value)
-{
-    dc->vmsd = value;
-}
-#else
-#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL)
-#endif
-
-/**
  * qemu_cpu_has_work:
  * @cpu: The vCPU to check.
  *
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 60125b1..50cccca 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -81,5 +81,6 @@  extern const struct VMStateDescription vmstate_alpha_cpu;
 void alpha_cpu_do_interrupt(CPUState *cpu);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                           int flags);
+hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 9679ac4..e03e74b 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -270,9 +270,12 @@  static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
     cc->set_pc = alpha_cpu_set_pc;
-    device_class_set_vmsd(dc, &vmstate_alpha_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = alpha_cpu_unassigned_access;
+    cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
+    dc->vmsd = &vmstate_alpha_cpu;
+#endif
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index ff57dd6..bef210a 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -315,12 +315,13 @@  static int get_physical_address(CPUAlphaState *env, target_ulong addr,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUAlphaState *env, target_ulong addr)
+hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    AlphaCPU *cpu = ALPHA_CPU(cs);
     target_ulong phys;
     int prot, fail;
 
-    fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
+    fail = get_physical_address(&cpu->env, addr, 0, 0, &phys, &prot);
     return (fail >= 0 ? -1 : phys);
 }
 
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 48ba605..c6d54c2 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -147,4 +147,6 @@  void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 
+hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 281e252..5f8a8f9 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -819,7 +819,10 @@  static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
-    cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_arm_cpu;
+#endif
 }
 
 static void cpu_register(const ARMCPUInfo *info)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5f639fd..da4d4a6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2749,17 +2749,19 @@  int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
+hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
     hwaddr phys_addr;
     target_ulong page_size;
     int prot;
     int ret;
 
-    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
+    ret = get_phys_addr(&cpu->env, addr, 0, 0, &phys_addr, &prot, &page_size);
 
-    if (ret != 0)
+    if (ret != 0) {
         return -1;
+    }
 
     return phys_addr;
 }
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index af7d14d..cd19070 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -79,4 +79,6 @@  void crisv10_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 
+hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index f7e8c2a..4d45b98 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -255,6 +255,9 @@  static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = cris_cpu_do_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-cris/helper.c b/target-cris/helper.c
index aba7537..44d8916 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -255,16 +255,17 @@  void cris_cpu_do_interrupt(CPUState *cs)
           env->pregs[PR_ERP]);
 }
 
-hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr)
+hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    CRISCPU *cpu = CRIS_CPU(cs);
     uint32_t phy = addr;
     struct cris_mmu_result res;
     int miss;
 
-    miss = cris_mmu_translate(&res, env, addr, 0, 0, 1);
+    miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1);
     /* If D TLB misses, try I TLB.  */
     if (miss) {
-        miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
+        miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1);
     }
 
     if (!miss) {
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7e55e5f..b762d06 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -104,4 +104,6 @@  void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
 void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 
+hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index eda2444..6b1205d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2542,12 +2542,13 @@  static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
     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;
     cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
     cc->write_elf32_note = x86_cpu_write_elf32_note;
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
+    cc->vmsd = &vmstate_x86_cpu;
 #endif
-    cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
 }
 
 static const TypeInfo x86_cpu_type_info = {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index d6f43d7..9726def 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -884,8 +884,10 @@  int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
+hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     target_ulong pde_addr, pte_addr;
     uint64_t pte;
     hwaddr paddr;
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index e3bb619..5c4810f 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -78,5 +78,6 @@  extern const struct VMStateDescription vmstate_lm32_cpu;
 void lm32_cpu_do_interrupt(CPUState *cpu);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 5a0b809..705dd55 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -87,7 +87,10 @@  static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
-    cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_lm32_cpu;
+#endif
 }
 
 static const TypeInfo lm32_cpu_type_info = {
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 615b44e..33cb463 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -37,10 +37,12 @@  int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr)
+hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    LM32CPU *cpu = LM32_CPU(cs);
+
     addr &= TARGET_PAGE_MASK;
-    if (env->flags & LM32_FLAG_IGNORE_MSB) {
+    if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
         return addr & 0x7fffffff;
     } else {
         return addr;
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 858bf30..9ec8c35 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -73,5 +73,6 @@  static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 void m68k_cpu_do_interrupt(CPUState *cpu);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 1ac1893..5328fda 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -190,6 +190,9 @@  static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 54fa419..0a94ca7 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -290,7 +290,7 @@  int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
 /* MMU */
 
 /* TODO: This will need fixing once the MMU is implemented.  */
-hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
+hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
     return addr;
 }
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index ec2b989..be05858 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -74,5 +74,6 @@  static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 void mb_cpu_do_interrupt(CPUState *cs);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
+hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 5fa6f63..90cc088 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -140,8 +140,11 @@  static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access);
     cc->set_pc = mb_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = mb_cpu_unassigned_access;
+    cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_mb_cpu;
     dc->props = mb_properties;
 }
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 86aad6a..7a96335 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -265,8 +265,10 @@  void mb_cpu_do_interrupt(CPUState *cs)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUMBState * env, target_ulong addr)
+hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
     target_ulong vaddr, paddr = 0;
     struct microblaze_mmu_lookup lu;
     unsigned int hit;
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 654744a..291b061 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -77,5 +77,6 @@  static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 void mips_cpu_do_interrupt(CPUState *cpu);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index ce39c23..10f6f69 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -98,9 +98,12 @@  static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->dump_state = mips_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = mips_cpu_unassigned_access;
+    cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 6983b92..eef985b 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -254,13 +254,16 @@  static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr)
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
     hwaddr phys_addr;
     int prot;
 
-    if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
+    if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0,
+                             ACCESS_INT) != 0) {
         return -1;
+    }
     return phys_addr;
 }
 #endif
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 8e32584..42bad13 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -101,7 +101,10 @@  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;
-    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_moxie_cpu;
+#endif
 }
 
 static void moxielite_initfn(Object *obj)
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index d5030a4..09037dd 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -118,6 +118,7 @@  int cpu_moxie_exec(CPUMoxieState *s);
 void moxie_cpu_do_interrupt(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
+hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 void moxie_translate_init(void);
 int cpu_moxie_signal_handler(int host_signum, void *pinfo,
                              void *puc);
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index ea0788f..150acb5 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -118,11 +118,6 @@  int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
-    return addr;
-}
-
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
@@ -162,12 +157,14 @@  void moxie_cpu_do_interrupt(CPUState *cs)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUMoxieState *env, target_ulong addr)
+hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MoxieCPU *cpu = MOXIE_CPU(cs);
     uint32_t phy = addr;
     MoxieMMUResult res;
     int miss;
-    miss = moxie_mmu_translate(&res, env, addr, 0, 0);
+
+    miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
     if (!miss) {
         phy = res.phy;
     }
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index aa79420..2b7a40e 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -152,7 +152,10 @@  static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
-    device_class_set_vmsd(dc, &vmstate_openrisc_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
+    dc->vmsd = &vmstate_openrisc_cpu;
+#endif
 }
 
 static void cpu_register(const OpenRISCCPUInfo *info)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 82bfd03..5747655 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -349,6 +349,7 @@  int cpu_openrisc_exec(CPUOpenRISCState *s);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
+hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                   target_ulong address,
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index d354e1f..bd004eb 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -219,12 +219,11 @@  int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
 #endif
 
 #ifndef CONFIG_USER_ONLY
-hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env,
-                                           target_ulong addr)
+hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     hwaddr phys_addr;
     int prot;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
     if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
         return -1;
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 7132599..7216cc4 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -105,5 +105,6 @@  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 26f513f..afdf4f2 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1317,8 +1317,10 @@  static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     mmu_ctx_t ctx;
 
     switch (env->mmu_model) {
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 4c091e3..cac55cc 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -74,5 +74,6 @@  static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 6fd9bdd..ea29f9c 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -173,6 +173,9 @@  static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_s390_cpu;
 }
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index b425054..b1e3c23 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -417,9 +417,10 @@  int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUS390XState *env,
-                                           target_ulong vaddr)
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, uint64_t vaddr)
 {
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
     target_ulong raddr;
     int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
     int old_exc = env->exception_index;
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index c229a9a..6f50a0a 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -86,5 +86,6 @@  static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 void superh_cpu_do_interrupt(CPUState *cpu);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
+hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index d535fe8..c9d6590 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -286,6 +286,9 @@  static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index cb6a2d2..ee475c0 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -508,12 +508,13 @@  int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUSH4State * env, target_ulong addr)
+hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
     target_ulong physical;
     int prot;
 
-    get_physical_address(env, &physical, &prot, addr, 0, 0);
+    get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0);
     return physical;
 }
 
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index 033a5b5..1b39274 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -78,5 +78,6 @@  static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
 void sparc_cpu_do_interrupt(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 1e3984f..c3e2d3d 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -782,9 +782,12 @@  static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
     cc->set_pc = sparc_cpu_set_pc;
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = sparc_cpu_unassigned_access;
+    cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 3983c96..99562fb 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -310,6 +310,7 @@  target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     target_ulong va, va1, va2;
     unsigned int n, m, o;
     hwaddr pde_ptr, pa;
@@ -322,20 +323,20 @@  void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
         pde = mmu_probe(env, va, 2);
         if (pde) {
-            pa = cpu_get_phys_page_debug(env, va);
+            pa = cpu_get_phys_page_debug(cs, va);
             (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
                            " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
             for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
                 pde = mmu_probe(env, va1, 1);
                 if (pde) {
-                    pa = cpu_get_phys_page_debug(env, va1);
+                    pa = cpu_get_phys_page_debug(cs, va1);
                     (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
                                    TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
                                    va1, pa, pde);
                     for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
                         pde = mmu_probe(env, va2, 0);
                         if (pde) {
-                            pa = cpu_get_phys_page_debug(env, va2);
+                            pa = cpu_get_phys_page_debug(cs, va2);
                             (*cpu_fprintf)(f, "  VA: " TARGET_FMT_lx ", PA: "
                                            TARGET_FMT_plx " PTE: "
                                            TARGET_FMT_lx "\n",
@@ -833,8 +834,10 @@  hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
 }
 #endif
 
-hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr)
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     hwaddr phys_addr;
     int mmu_idx = cpu_mmu_index(env);
     MemoryRegionSection section;
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index 350d480..c894d55 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -63,5 +63,6 @@  static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
                          fprintf_function cpu_fprintf, int flags);
+hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 2e99bd3..c5edddb 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -139,6 +139,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
+    cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
index eadaeb1..6ebde59 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -261,9 +261,10 @@  int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env,
-        target_ulong addr)
+hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
-    cpu_abort(env, "%s not supported yet\n", __func__);
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+
+    cpu_abort(&cpu->env, "%s not supported yet\n", __func__);
     return addr;
 }
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 31e7498..944d3cc 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -83,5 +83,6 @@  static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
+hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index a388c6f..6556caa 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -108,6 +108,9 @@  static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_xtensa_cpu;
 }
 
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 6f613c66..a67c849 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -108,17 +108,18 @@  void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong addr)
+hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    XtensaCPU *cpu = XTENSA_CPU(cs);
     uint32_t paddr;
     uint32_t page_size;
     unsigned access;
 
-    if (xtensa_get_physical_addr(env, false, addr, 0, 0,
+    if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0,
                 &paddr, &page_size, &access) == 0) {
         return paddr;
     }
-    if (xtensa_get_physical_addr(env, false, addr, 2, 0,
+    if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0,
                 &paddr, &page_size, &access) == 0) {
         return paddr;
     }
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
index 5fe0361..d9dd222 100644
--- a/target-xtensa/xtensa-semi.c
+++ b/target-xtensa/xtensa-semi.c
@@ -152,6 +152,7 @@  static uint32_t errno_h2g(int host_errno)
 
 void HELPER(simcall)(CPUXtensaState *env)
 {
+    CPUState *cs = CPU(xtensa_env_get_cpu(env));
     uint32_t *regs = env->regs;
 
     switch (regs[2]) {
@@ -169,8 +170,7 @@  void HELPER(simcall)(CPUXtensaState *env)
             uint32_t len = regs[5];
 
             while (len > 0) {
-                hwaddr paddr =
-                    cpu_get_phys_page_debug(env, vaddr);
+                hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr);
                 uint32_t page_left =
                     TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1));
                 uint32_t io_sz = page_left < len ? page_left : len;