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

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

Comments

Andreas Färber - Sept. 4, 2013, 9:04 a.m.
Default to 0.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cputlb.c                      |  7 +++----
 include/exec/softmmu_header.h |  4 ++--
 include/qom/cpu.h             | 15 +++++++++++++++
 qom/cpu.c                     |  6 ++++++
 target-alpha/cpu.c            | 14 ++++++++++++++
 target-alpha/cpu.h            | 11 -----------
 target-alpha/translate.c      |  2 +-
 target-arm/cpu.c              |  8 ++++++++
 target-arm/cpu.h              |  4 ----
 target-cris/cpu.c             |  8 ++++++++
 target-cris/cpu.h             |  4 ----
 target-cris/translate.c       |  6 +++---
 target-cris/translate_v10.c   |  2 +-
 target-i386/cpu.c             | 11 +++++++++++
 target-i386/cpu.h             |  6 ------
 target-i386/translate.c       |  2 +-
 target-lm32/cpu.h             |  4 ----
 target-m68k/cpu.c             |  8 ++++++++
 target-m68k/cpu.h             |  4 ----
 target-microblaze/cpu.c       | 15 +++++++++++++++
 target-microblaze/cpu.h       | 11 -----------
 target-microblaze/mmu.c       |  3 ++-
 target-microblaze/translate.c | 14 +++++++-------
 target-mips/cpu.c             |  8 ++++++++
 target-mips/cpu.h             |  4 ----
 target-moxie/cpu.h            |  5 -----
 target-openrisc/cpu.c         | 11 +++++++++++
 target-openrisc/cpu.h         |  8 --------
 target-openrisc/translate.c   |  2 +-
 target-ppc/cpu.h              |  4 ----
 target-ppc/translate_init.c   |  8 ++++++++
 target-s390x/cpu.c            | 12 ++++++++++++
 target-s390x/cpu.h            |  9 ---------
 target-sh4/cpu.c              |  8 ++++++++
 target-sh4/cpu.h              |  4 ----
 target-sparc/cpu.c            | 25 +++++++++++++++++++++++++
 target-sparc/cpu.h            | 19 -------------------
 target-sparc/mmu_helper.c     |  2 +-
 target-sparc/translate.c      |  2 +-
 target-unicore32/cpu.c        |  8 ++++++++
 target-unicore32/cpu.h        |  4 ----
 target-xtensa/cpu.c           |  8 ++++++++
 target-xtensa/cpu.h           |  5 -----
 43 files changed, 196 insertions(+), 129 deletions(-)
Jia Liu - Sept. 4, 2013, 12:42 p.m.
On Wed, Sep 4, 2013 at 5:04 PM, Andreas Färber <afaerber@suse.de> wrote:
> Default to 0.
>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cputlb.c                      |  7 +++----
>  include/exec/softmmu_header.h |  4 ++--
>  include/qom/cpu.h             | 15 +++++++++++++++
>  qom/cpu.c                     |  6 ++++++
>  target-alpha/cpu.c            | 14 ++++++++++++++
>  target-alpha/cpu.h            | 11 -----------
>  target-alpha/translate.c      |  2 +-
>  target-arm/cpu.c              |  8 ++++++++
>  target-arm/cpu.h              |  4 ----
>  target-cris/cpu.c             |  8 ++++++++
>  target-cris/cpu.h             |  4 ----
>  target-cris/translate.c       |  6 +++---
>  target-cris/translate_v10.c   |  2 +-
>  target-i386/cpu.c             | 11 +++++++++++
>  target-i386/cpu.h             |  6 ------
>  target-i386/translate.c       |  2 +-
>  target-lm32/cpu.h             |  4 ----
>  target-m68k/cpu.c             |  8 ++++++++
>  target-m68k/cpu.h             |  4 ----
>  target-microblaze/cpu.c       | 15 +++++++++++++++
>  target-microblaze/cpu.h       | 11 -----------
>  target-microblaze/mmu.c       |  3 ++-
>  target-microblaze/translate.c | 14 +++++++-------
>  target-mips/cpu.c             |  8 ++++++++
>  target-mips/cpu.h             |  4 ----
>  target-moxie/cpu.h            |  5 -----
>  target-openrisc/cpu.c         | 11 +++++++++++
>  target-openrisc/cpu.h         |  8 --------
>  target-openrisc/translate.c   |  2 +-
>  target-ppc/cpu.h              |  4 ----
>  target-ppc/translate_init.c   |  8 ++++++++
>  target-s390x/cpu.c            | 12 ++++++++++++
>  target-s390x/cpu.h            |  9 ---------
>  target-sh4/cpu.c              |  8 ++++++++
>  target-sh4/cpu.h              |  4 ----
>  target-sparc/cpu.c            | 25 +++++++++++++++++++++++++
>  target-sparc/cpu.h            | 19 -------------------
>  target-sparc/mmu_helper.c     |  2 +-
>  target-sparc/translate.c      |  2 +-
>  target-unicore32/cpu.c        |  8 ++++++++
>  target-unicore32/cpu.h        |  4 ----
>  target-xtensa/cpu.c           |  8 ++++++++
>  target-xtensa/cpu.h           |  5 -----
>  43 files changed, 196 insertions(+), 129 deletions(-)
>
> diff --git a/cputlb.c b/cputlb.c
> index fff0afb..85a028f 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -316,12 +316,14 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
>   */
>  tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>  {
> +    CPUState *cpu = ENV_GET_CPU(env1);
> +    CPUClass *cc = CPU_GET_CLASS(cpu);
>      int mmu_idx, page_index, pd;
>      void *p;
>      MemoryRegion *mr;
>
>      page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
> -    mmu_idx = cpu_mmu_index(env1);
> +    mmu_idx = cc->mmu_index(cpu);
>      if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
>                   (addr & TARGET_PAGE_MASK))) {
>          cpu_ldub_code(env1, addr);
> @@ -329,9 +331,6 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>      pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
>      mr = iotlb_to_region(pd);
>      if (memory_region_is_unassigned(mr)) {
> -        CPUState *cpu = ENV_GET_CPU(env1);
> -        CPUClass *cc = CPU_GET_CLASS(cpu);
> -
>          if (cc->do_unassigned_access) {
>              cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
>          } else {
> diff --git a/include/exec/softmmu_header.h b/include/exec/softmmu_header.h
> index d8d9c81..e138b87 100644
> --- a/include/exec/softmmu_header.h
> +++ b/include/exec/softmmu_header.h
> @@ -54,12 +54,12 @@
>
>  #elif ACCESS_TYPE == (NB_MMU_MODES)
>
> -#define CPU_MMU_INDEX (cpu_mmu_index(env))
> +#define CPU_MMU_INDEX (cpu_mmu_index(ENV_GET_CPU(env)))
>  #define MMUSUFFIX _mmu
>
>  #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
>
> -#define CPU_MMU_INDEX (cpu_mmu_index(env))
> +#define CPU_MMU_INDEX (cpu_mmu_index(ENV_GET_CPU(env)))
>  #define MMUSUFFIX _cmmu
>
>  #else
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 4d022c3..c78d572 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -76,6 +76,7 @@ struct TranslationBlock;
>   * @dump_state: Callback for dumping state.
>   * @dump_statistics: Callback for dumping statistics.
>   * @get_arch_id: Callback for getting architecture-dependent CPU ID.
> + * @mmu_index: Callback for obtaining MMU index.
>   * @get_paging_enabled: Callback for inquiring whether paging is enabled.
>   * @get_memory_mapping: Callback for obtaining the memory mappings.
>   * @set_pc: Callback for setting the Program Counter register.
> @@ -109,6 +110,7 @@ typedef struct CPUClass {
>      void (*dump_statistics)(CPUState *cpu, FILE *f,
>                              fprintf_function cpu_fprintf, int flags);
>      int64_t (*get_arch_id)(CPUState *cpu);
> +    int (*mmu_index)(const CPUState *cpu);
>      bool (*get_paging_enabled)(const CPUState *cpu);
>      void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
>                                 Error **errp);
> @@ -217,6 +219,19 @@ DECLARE_TLS(CPUState *, current_cpu);
>  #define current_cpu tls_var(current_cpu)
>
>  /**
> + * cpu_mmu_index:
> + * @cpu: The CPU whose MMU index is to be obtained.
> + *
> + * Returns: MMU index for @cpu.
> + */
> +static inline int cpu_mmu_index(CPUState *cpu)
> +{
> +    CPUClass *cc = CPU_GET_CLASS(cpu);
> +
> +    return cc->mmu_index(cpu);
> +}
> +
> +/**
>   * cpu_paging_enabled:
>   * @cpu: The CPU whose state is to be inspected.
>   *
> diff --git a/qom/cpu.c b/qom/cpu.c
> index c71fa35..9b9c2c6 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -200,6 +200,11 @@ static void cpu_common_reset(CPUState *cpu)
>      cpu->halted = 0;
>  }
>
> +static int cpu_common_mmu_index(const CPUState *cs)
> +{
> +    return 0;
> +}
> +
>  static bool cpu_common_has_work(CPUState *cs)
>  {
>      return false;
> @@ -249,6 +254,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
>      k->class_by_name = cpu_common_class_by_name;
>      k->reset = cpu_common_reset;
>      k->get_arch_id = cpu_common_get_arch_id;
> +    k->mmu_index = cpu_common_mmu_index;
>      k->has_work = cpu_common_has_work;
>      k->get_paging_enabled = cpu_common_get_paging_enabled;
>      k->get_memory_mapping = cpu_common_get_memory_mapping;
> diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
> index 053afa2..15d6f1f 100644
> --- a/target-alpha/cpu.c
> +++ b/target-alpha/cpu.c
> @@ -31,6 +31,19 @@ static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.pc = value;
>  }
>
> +static int alpha_cpu_mmu_index(const CPUState *cs)
> +{
> +    AlphaCPU *cpu = ALPHA_CPU(cs);
> +
> +    if (cpu->env.pal_mode) {
> +        return MMU_KERNEL_IDX;
> +    } else if (cpu->env.ps & PS_USER_MODE) {
> +        return MMU_USER_IDX;
> +    } else {
> +        return MMU_KERNEL_IDX;
> +    }
> +}
> +
>  static bool alpha_cpu_has_work(CPUState *cs)
>  {
>      /* Here we are checking to see if the CPU should wake up from HALT.
> @@ -289,6 +302,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = alpha_cpu_has_work;
>      cc->do_interrupt = alpha_cpu_do_interrupt;
>      cc->dump_state = alpha_cpu_dump_state;
> +    cc->mmu_index = alpha_cpu_mmu_index;
>      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;
> diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
> index a172124..808fe53 100644
> --- a/target-alpha/cpu.h
> +++ b/target-alpha/cpu.h
> @@ -378,17 +378,6 @@ enum {
>      PS_USER_MODE = 8
>  };
>
> -static inline int cpu_mmu_index(CPUAlphaState *env)
> -{
> -    if (env->pal_mode) {
> -        return MMU_KERNEL_IDX;
> -    } else if (env->ps & PS_USER_MODE) {
> -        return MMU_USER_IDX;
> -    } else {
> -        return MMU_KERNEL_IDX;
> -    }
> -}
> -
>  enum {
>      IR_V0   = 0,
>      IR_T0   = 1,
> diff --git a/target-alpha/translate.c b/target-alpha/translate.c
> index 28ce436..50b4339 100644
> --- a/target-alpha/translate.c
> +++ b/target-alpha/translate.c
> @@ -3458,7 +3458,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>
>      ctx.tb = tb;
>      ctx.pc = pc_start;
> -    ctx.mem_idx = cpu_mmu_index(env);
> +    ctx.mem_idx = cpu_mmu_index(cs);
>      ctx.implver = env->implver;
>      ctx.singlestep_enabled = cs->singlestep_enabled;
>
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index f38c851..6032a2c 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -34,6 +34,13 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.regs[15] = value;
>  }
>
> +static int arm_cpu_mmu_index(const CPUState *cs)
> +{
> +    ARMCPU *cpu = ARM_CPU(cs);
> +
> +    return (cpu->env.uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
> +}
> +
>  static bool arm_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request &
> @@ -899,6 +906,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = arm_cpu_has_work;
>      cc->do_interrupt = arm_cpu_do_interrupt;
>      cc->dump_state = arm_cpu_dump_state;
> +    cc->mmu_index = arm_cpu_mmu_index;
>      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;
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index a42822b..19fa4ee 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -750,10 +750,6 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
>  #define MMU_MODE0_SUFFIX _kernel
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
> -static inline int cpu_mmu_index (CPUARMState *env)
> -{
> -    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
> -}
>
>  #include "exec/cpu-all.h"
>
> diff --git a/target-cris/cpu.c b/target-cris/cpu.c
> index 998cded..1e5b425 100644
> --- a/target-cris/cpu.c
> +++ b/target-cris/cpu.c
> @@ -33,6 +33,13 @@ static void cris_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.pc = value;
>  }
>
> +static int cris_cpu_mmu_index(const CPUState *cs)
> +{
> +    CRISCPU *cpu = CRIS_CPU(cs);
> +
> +    return (cpu->env.pregs[PR_CCS] & U_FLAG) ? 1 : 0;
> +}
> +
>  static bool cris_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
> @@ -265,6 +272,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = cris_cpu_has_work;
>      cc->do_interrupt = cris_cpu_do_interrupt;
>      cc->dump_state = cris_cpu_dump_state;
> +    cc->mmu_index = cris_cpu_mmu_index;
>      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;
> diff --git a/target-cris/cpu.h b/target-cris/cpu.h
> index 15a0497..0914103 100644
> --- a/target-cris/cpu.h
> +++ b/target-cris/cpu.h
> @@ -238,10 +238,6 @@ static inline CPUCRISState *cpu_init(const char *cpu_model)
>  #define MMU_MODE0_SUFFIX _kernel
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
> -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 mmu_idx);
> diff --git a/target-cris/translate.c b/target-cris/translate.c
> index 617e1b4..29e9f63 100644
> --- a/target-cris/translate.c
> +++ b/target-cris/translate.c
> @@ -1125,7 +1125,7 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
>
>  static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
>
>      /* If we get a fault on a delayslot we must keep the jmp state in
>         the cpu-state to be able to re-execute the jmp.  */
> @@ -1139,7 +1139,7 @@ static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
>  static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
>               unsigned int size, int sign)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
>
>      /* If we get a fault on a delayslot we must keep the jmp state in
>         the cpu-state to be able to re-execute the jmp.  */
> @@ -1169,7 +1169,7 @@ static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
>  static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
>                 unsigned int size)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
>
>      /* If we get a fault on a delayslot we must keep the jmp state in
>         the cpu-state to be able to re-execute the jmp.  */
> diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
> index d6ef084..0ade05b 100644
> --- a/target-cris/translate_v10.c
> +++ b/target-cris/translate_v10.c
> @@ -96,7 +96,7 @@ static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
>  static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
>                         unsigned int size)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
>
>      /* If we get a fault on a delayslot we must keep the jmp state in
>         the cpu-state to be able to re-execute the jmp.  */
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index fa92950..a623383 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2676,6 +2676,16 @@ static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
>      cpu->env.eip = tb->pc - tb->cs_base;
>  }
>
> +static int x86_cpu_mmu_index(const CPUState *cs)
> +{
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
> +
> +    return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
> +        ((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
> +        ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
> +}
> +
>  static bool x86_cpu_has_work(CPUState *cs)
>  {
>      X86CPU *cpu = X86_CPU(cs);
> @@ -2713,6 +2723,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
>      cc->has_work = x86_cpu_has_work;
>      cc->do_interrupt = x86_cpu_do_interrupt;
>      cc->dump_state = x86_cpu_dump_state;
> +    cc->mmu_index = x86_cpu_mmu_index;
>      cc->set_pc = x86_cpu_set_pc;
>      cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
>      cc->gdb_read_register = x86_cpu_gdb_read_register;
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 6d46c75..fd16f20 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1123,12 +1123,6 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
>  #define MMU_KERNEL_IDX  0
>  #define MMU_USER_IDX    1
>  #define MMU_KSMAP_IDX   2
> -static inline int cpu_mmu_index (CPUX86State *env)
> -{
> -    return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
> -        ((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
> -        ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
> -}
>
>  #define CC_DST  (env->cc_dst)
>  #define CC_SRC  (env->cc_src)
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 6d87900..2e8e8d5 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -8291,7 +8291,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
>      /* select memory access functions */
>      dc->mem_index = 0;
>      if (flags & HF_SOFTMMU_MASK) {
> -        dc->mem_index = (cpu_mmu_index(env) + 1) << 2;
> +        dc->mem_index = (cpu_mmu_index(cs) + 1) << 2;
>      }
>      dc->cpuid_features = env->features[FEAT_1_EDX];
>      dc->cpuid_ext_features = env->features[FEAT_1_ECX];
> diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
> index a251a02..11f54e7 100644
> --- a/target-lm32/cpu.h
> +++ b/target-lm32/cpu.h
> @@ -36,10 +36,6 @@ typedef struct CPULM32State CPULM32State;
>
>  #define NB_MMU_MODES 1
>  #define TARGET_PAGE_BITS 12
> -static inline int cpu_mmu_index(CPULM32State *env)
> -{
> -    return 0;
> -}
>
>  #define TARGET_PHYS_ADDR_SPACE_BITS 32
>  #define TARGET_VIRT_ADDR_SPACE_BITS 32
> diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
> index 7d66ed0..00454ab 100644
> --- a/target-m68k/cpu.c
> +++ b/target-m68k/cpu.c
> @@ -30,6 +30,13 @@ static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.pc = value;
>  }
>
> +static int m68k_cpu_mmu_index(const CPUState *cs)
> +{
> +    M68kCPU *cpu = M68K_CPU(cs);
> +
> +    return (cpu->env.sr & SR_S) == 0 ? MMU_USER_IDX : 0;
> +}
> +
>  static bool m68k_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request & CPU_INTERRUPT_HARD;
> @@ -197,6 +204,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
>      cc->has_work = m68k_cpu_has_work;
>      cc->do_interrupt = m68k_cpu_do_interrupt;
>      cc->dump_state = m68k_cpu_dump_state;
> +    cc->mmu_index = m68k_cpu_mmu_index;
>      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;
> diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
> index 5f79d2a..d1291d8 100644
> --- a/target-m68k/cpu.h
> +++ b/target-m68k/cpu.h
> @@ -232,10 +232,6 @@ static inline CPUM68KState *cpu_init(const char *cpu_model)
>  #define MMU_MODE0_SUFFIX _kernel
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
> -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 mmu_idx);
> diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
> index 6104939..929efd8 100644
> --- a/target-microblaze/cpu.c
> +++ b/target-microblaze/cpu.c
> @@ -33,6 +33,20 @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.sregs[SR_PC] = value;
>  }
>
> +static int mb_cpu_mmu_index(const CPUState *cs)
> +{
> +    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
> +
> +        /* Are we in nommu mode?.  */
> +        if (!(cpu->env.sregs[SR_MSR] & MSR_VM)) {
> +            return MMU_NOMMU_IDX;
> +        }
> +        if (cpu->env.sregs[SR_MSR] & MSR_UM) {
> +            return MMU_USER_IDX;
> +        }
> +        return MMU_KERNEL_IDX;
> +}
> +
>  static bool mb_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
> @@ -147,6 +161,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = mb_cpu_has_work;
>      cc->do_interrupt = mb_cpu_do_interrupt;
>      cc->dump_state = mb_cpu_dump_state;
> +    cc->mmu_index = mb_cpu_mmu_index;
>      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;
> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
> index 23f96f8..a81f899 100644
> --- a/target-microblaze/cpu.h
> +++ b/target-microblaze/cpu.h
> @@ -316,17 +316,6 @@ static inline CPUMBState *cpu_init(const char *cpu_model)
>  #define MMU_USER_IDX    2
>  /* See NB_MMU_MODES further up the file.  */
>
> -static inline int cpu_mmu_index (CPUMBState *env)
> -{
> -        /* Are we in nommu mode?.  */
> -        if (!(env->sregs[SR_MSR] & MSR_VM))
> -            return MMU_NOMMU_IDX;
> -
> -       if (env->sregs[SR_MSR] & MSR_UM)
> -            return MMU_USER_IDX;
> -        return MMU_KERNEL_IDX;
> -}
> -
>  int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw,
>                              int mmu_idx);
>  #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
> diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
> index 73bf805..9182934 100644
> --- a/target-microblaze/mmu.c
> +++ b/target-microblaze/mmu.c
> @@ -218,6 +218,7 @@ uint32_t mmu_read(CPUMBState *env, uint32_t rn)
>
>  void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
>  {
> +    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
>      unsigned int i;
>      D(qemu_log("%s rn=%d=%x old=%x\n", __func__, rn, v, env->mmu.regs[rn]));
>
> @@ -277,7 +278,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
>              }
>
>              hit = mmu_translate(&env->mmu, &lu,
> -                                v & TLB_EPN_MASK, 0, cpu_mmu_index(env));
> +                                v & TLB_EPN_MASK, 0, cpu_mmu_index(CPU(cpu)));
>              if (hit) {
>                  env->mmu.regs[MMU_R_TLBX] = lu.idx;
>              } else
> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
> index 0673176..f4dbe11 100644
> --- a/target-microblaze/translate.c
> +++ b/target-microblaze/translate.c
> @@ -440,7 +440,7 @@ static void dec_msr(DisasContext *dc)
>  {
>      TCGv t0, t1;
>      unsigned int sr, to, rn;
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      sr = dc->imm & ((1 << 14) - 1);
>      to = dc->imm & (1 << 14);
> @@ -751,7 +751,7 @@ static void dec_bit(DisasContext *dc)
>  {
>      TCGv t0, t1;
>      unsigned int op;
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      op = dc->ir & ((1 << 9) - 1);
>      switch (op) {
> @@ -874,7 +874,7 @@ static void dec_imm(DisasContext *dc)
>  static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
>                              unsigned int size)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      if (size == 1) {
>          tcg_gen_qemu_ld8u(dst, addr, mem_index);
> @@ -1093,7 +1093,7 @@ static void dec_load(DisasContext *dc)
>  static void gen_store(DisasContext *dc, TCGv addr, TCGv val,
>                        unsigned int size)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      if (size == 1)
>          tcg_gen_qemu_st8(val, addr, mem_index);
> @@ -1308,7 +1308,7 @@ static void dec_bcc(DisasContext *dc)
>  static void dec_br(DisasContext *dc)
>  {
>      unsigned int dslot, link, abs, mbar;
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      dslot = dc->ir & (1 << 20);
>      abs = dc->ir & (1 << 19);
> @@ -1440,7 +1440,7 @@ static inline void do_rte(DisasContext *dc)
>  static void dec_rts(DisasContext *dc)
>  {
>      unsigned int b_bit, i_bit, e_bit;
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>
>      i_bit = dc->ir & (1 << 21);
>      b_bit = dc->ir & (1 << 22);
> @@ -1616,7 +1616,7 @@ static void dec_null(DisasContext *dc)
>  /* Insns connected to FSL or AXI stream attached devices.  */
>  static void dec_stream(DisasContext *dc)
>  {
> -    int mem_index = cpu_mmu_index(dc->env);
> +    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
>      TCGv_i32 t_id, t_ctrl;
>      int ctrl;
>
> diff --git a/target-mips/cpu.c b/target-mips/cpu.c
> index 0a2dc46..cb916f3 100644
> --- a/target-mips/cpu.c
> +++ b/target-mips/cpu.c
> @@ -45,6 +45,13 @@ static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
>      env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
>  }
>
> +static int mips_cpu_mmu_index(const CPUState *cs)
> +{
> +    MIPSCPU *cpu = MIPS_CPU(cs);
> +
> +    return cpu->env.hflags & MIPS_HFLAG_KSU;
> +}
> +
>  static bool mips_cpu_has_work(CPUState *cs)
>  {
>      MIPSCPU *cpu = MIPS_CPU(cs);
> @@ -129,6 +136,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
>      cc->has_work = mips_cpu_has_work;
>      cc->do_interrupt = mips_cpu_do_interrupt;
>      cc->dump_state = mips_cpu_dump_state;
> +    cc->mmu_index = mips_cpu_mmu_index;
>      cc->set_pc = mips_cpu_set_pc;
>      cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
>      cc->gdb_read_register = mips_cpu_gdb_read_register;
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index dff2836..22643ff 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -516,10 +516,6 @@ extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
>  #define MMU_MODE1_SUFFIX _super
>  #define MMU_MODE2_SUFFIX _user
>  #define MMU_USER_IDX 2
> -static inline int cpu_mmu_index (CPUMIPSState *env)
> -{
> -    return env->hflags & MIPS_HFLAG_KSU;
> -}
>
>  static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
>  {
> diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
> index 778cfc0..affcfca 100644
> --- a/target-moxie/cpu.h
> +++ b/target-moxie/cpu.h
> @@ -136,11 +136,6 @@ static inline CPUMoxieState *cpu_init(const char *cpu_model)
>  #define cpu_gen_code cpu_moxie_gen_code
>  #define cpu_signal_handler cpu_moxie_signal_handler
>
> -static inline int cpu_mmu_index(CPUMoxieState *env)
> -{
> -    return 0;
> -}
> -
>  #include "exec/cpu-all.h"
>  #include "exec/exec-all.h"
>
> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
> index ca8495f..4872fcf 100644
> --- a/target-openrisc/cpu.c
> +++ b/target-openrisc/cpu.c
> @@ -27,6 +27,16 @@ static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.pc = value;
>  }
>
> +static int openrisc_cpu_mmu_index(const CPUState *cs)
> +{
> +    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
> +
> +    if (!(cpu->env.sr & SR_IME)) {
> +        return MMU_NOMMU_IDX;
> +    }
> +    return (cpu->env.sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
> +}
> +
>  static bool openrisc_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request & (CPU_INTERRUPT_HARD |
> @@ -162,6 +172,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = openrisc_cpu_has_work;
>      cc->do_interrupt = openrisc_cpu_do_interrupt;
>      cc->dump_state = openrisc_cpu_dump_state;
> +    cc->mmu_index = openrisc_cpu_mmu_index;
>      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;
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> index 4a27f22..2a1ca92 100644
> --- a/target-openrisc/cpu.h
> +++ b/target-openrisc/cpu.h
> @@ -409,14 +409,6 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
>      *flags = (env->flags & D_FLAG);
>  }
>
> -static inline int cpu_mmu_index(CPUOpenRISCState *env)
> -{
> -    if (!(env->sr & SR_IME)) {
> -        return MMU_NOMMU_IDX;
> -    }
> -    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
> -}
> -
>  #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
>
>  #include "exec/exec-all.h"
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> index 723b77d..ea242da 100644
> --- a/target-openrisc/translate.c
> +++ b/target-openrisc/translate.c
> @@ -1679,7 +1679,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
>      dc->ppc = pc_start;
>      dc->pc = pc_start;
>      dc->flags = cpu->env.cpucfgr;
> -    dc->mem_idx = cpu_mmu_index(&cpu->env);
> +    dc->mem_idx = cpu_mmu_index(cs);
>      dc->synced_flags = dc->tb_flags = tb->flags;
>      dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
>      dc->singlestep_enabled = cs->singlestep_enabled;
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 70c1ef5..9c99f0d 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1183,10 +1183,6 @@ static inline CPUPPCState *cpu_init(const char *cpu_model)
>  #define MMU_MODE1_SUFFIX _kernel
>  #define MMU_MODE2_SUFFIX _hypv
>  #define MMU_USER_IDX 0
> -static inline int cpu_mmu_index (CPUPPCState *env)
> -{
> -    return env->mmu_idx;
> -}
>
>  #include "exec/cpu-all.h"
>
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index b552451..e4bcf74 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8437,6 +8437,13 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.nip = value;
>  }
>
> +static int ppc_cpu_mmu_index(const CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +    return cpu->env.mmu_idx;
> +}
> +
>  static bool ppc_cpu_has_work(CPUState *cs)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -8573,6 +8580,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>      cc->do_interrupt = ppc_cpu_do_interrupt;
>      cc->dump_state = ppc_cpu_dump_state;
>      cc->dump_statistics = ppc_cpu_dump_statistics;
> +    cc->mmu_index = ppc_cpu_mmu_index;
>      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;
> diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
> index a4c7a33..6b200fe 100644
> --- a/target-s390x/cpu.c
> +++ b/target-s390x/cpu.c
> @@ -65,6 +65,17 @@ static void s390_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.psw.addr = value;
>  }
>
> +static int s390_cpu_mmu_index(const CPUState *cs)
> +{
> +    S390CPU *cpu = S390_CPU(cs);
> +
> +    if (cpu->env.psw.mask & PSW_MASK_PSTATE) {
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
>  static bool s390_cpu_has_work(CPUState *cs)
>  {
>      S390CPU *cpu = S390_CPU(cs);
> @@ -229,6 +240,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = s390_cpu_has_work;
>      cc->do_interrupt = s390_cpu_do_interrupt;
>      cc->dump_state = s390_cpu_dump_state;
> +    cc->mmu_index = s390_cpu_mmu_index;
>      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;
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index 3b588af..d7970e6 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -273,15 +273,6 @@ typedef struct CPUS390XState {
>  #define FLAG_MASK_64            (PSW_MASK_64     >> 32)
>  #define FLAG_MASK_32            0x00001000
>
> -static inline int cpu_mmu_index (CPUS390XState *env)
> -{
> -    if (env->psw.mask & PSW_MASK_PSTATE) {
> -        return 1;
> -    }
> -
> -    return 0;
> -}
> -
>  static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
>                                          target_ulong *cs_base, int *flags)
>  {
> diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
> index 5bf6d9f..df1c0e8 100644
> --- a/target-sh4/cpu.c
> +++ b/target-sh4/cpu.c
> @@ -39,6 +39,13 @@ static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
>      cpu->env.flags = tb->flags;
>  }
>
> +static int superh_cpu_mmu_index(const CPUState *cs)
> +{
> +    SuperHCPU *cpu = SUPERH_CPU(cs);
> +
> +    return (cpu->env.sr & SR_MD) == 0 ? 1 : 0;
> +}
> +
>  static bool superh_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request & CPU_INTERRUPT_HARD;
> @@ -291,6 +298,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = superh_cpu_has_work;
>      cc->do_interrupt = superh_cpu_do_interrupt;
>      cc->dump_state = superh_cpu_dump_state;
> +    cc->mmu_index = superh_cpu_mmu_index;
>      cc->set_pc = superh_cpu_set_pc;
>      cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
>      cc->gdb_read_register = superh_cpu_gdb_read_register;
> diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
> index 2eafc2d..6125c20 100644
> --- a/target-sh4/cpu.h
> +++ b/target-sh4/cpu.h
> @@ -240,10 +240,6 @@ static inline CPUSH4State *cpu_init(const char *cpu_model)
>  #define MMU_MODE0_SUFFIX _kernel
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
> -static inline int cpu_mmu_index (CPUSH4State *env)
> -{
> -    return (env->sr & SR_MD) == 0 ? 1 : 0;
> -}
>
>  #include "exec/cpu-all.h"
>
> diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
> index ede2c80..1d27f9e 100644
> --- a/target-sparc/cpu.c
> +++ b/target-sparc/cpu.c
> @@ -739,6 +739,30 @@ static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
>      cpu->env.npc = tb->cs_base;
>  }
>
> +static int sparc_cpu_mmu_index(const CPUState *cs)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    return MMU_USER_IDX;
> +#else
> +    SPARCCPU *cpu = SPARC_CPU(cs);
> +    CPUSPARCState *env = &cpu->env;
> +
> +#if !defined(TARGET_SPARC64)
> +    return env->psrs;
> +#else
> +    if (env->tl > 0) {
> +        return MMU_NUCLEUS_IDX;
> +    } else if (cpu_hypervisor_mode(env)) {
> +        return MMU_HYPV_IDX;
> +    } else if (cpu_supervisor_mode(env)) {
> +        return MMU_KERNEL_IDX;
> +    } else {
> +        return MMU_USER_IDX;
> +    }
> +#endif
> +#endif
> +}
> +
>  static bool sparc_cpu_has_work(CPUState *cs)
>  {
>      SPARCCPU *cpu = SPARC_CPU(cs);
> @@ -797,6 +821,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
>  #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
>      cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
>  #endif
> +    cc->mmu_index = sparc_cpu_mmu_index;
>      cc->set_pc = sparc_cpu_set_pc;
>      cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
>      cc->gdb_read_register = sparc_cpu_gdb_read_register;
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index adf6557..93590b8 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -647,25 +647,6 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1)
>  }
>  #endif
>
> -static inline int cpu_mmu_index(CPUSPARCState *env1)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    return MMU_USER_IDX;
> -#elif !defined(TARGET_SPARC64)
> -    return env1->psrs;
> -#else
> -    if (env1->tl > 0) {
> -        return MMU_NUCLEUS_IDX;
> -    } else if (cpu_hypervisor_mode(env1)) {
> -        return MMU_HYPV_IDX;
> -    } else if (cpu_supervisor_mode(env1)) {
> -        return MMU_KERNEL_IDX;
> -    } else {
> -        return MMU_USER_IDX;
> -    }
> -#endif
> -}
> -
>  static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
>  {
>  #if !defined (TARGET_SPARC64)
> diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
> index ef12a0a..9eb096e 100644
> --- a/target-sparc/mmu_helper.c
> +++ b/target-sparc/mmu_helper.c
> @@ -842,7 +842,7 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      SPARCCPU *cpu = SPARC_CPU(cs);
>      CPUSPARCState *env = &cpu->env;
>      hwaddr phys_addr;
> -    int mmu_idx = cpu_mmu_index(env);
> +    int mmu_idx = cpu_mmu_index(cs);
>      MemoryRegionSection section;
>
>      if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 36615f1..73f8b9c 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -5241,7 +5241,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
>      last_pc = dc->pc;
>      dc->npc = (target_ulong) tb->cs_base;
>      dc->cc_op = CC_OP_DYNAMIC;
> -    dc->mem_idx = cpu_mmu_index(env);
> +    dc->mem_idx = cpu_mmu_index(cs);
>      dc->def = env->def;
>      dc->fpu_enabled = tb_fpu_enabled(tb->flags);
>      dc->address_mask_32bit = tb_am_enabled(tb->flags);
> diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
> index 1cfe50a..3ed9ea3 100644
> --- a/target-unicore32/cpu.c
> +++ b/target-unicore32/cpu.c
> @@ -23,6 +23,13 @@ static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.regs[31] = value;
>  }
>
> +static int uc32_cpu_mmu_index(const CPUState *cs)
> +{
> +    UniCore32CPU *cpu = UNICORE32_CPU(cs);
> +
> +    return (cpu->env.uncached_asr & ASR_M) == ASR_MODE_USER ? MMU_USER_IDX : 0;
> +}
> +
>  static bool uc32_cpu_has_work(CPUState *cs)
>  {
>      return cs->interrupt_request &
> @@ -147,6 +154,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = uc32_cpu_has_work;
>      cc->do_interrupt = uc32_cpu_do_interrupt;
>      cc->dump_state = uc32_cpu_dump_state;
> +    cc->mmu_index = uc32_cpu_mmu_index;
>      cc->set_pc = uc32_cpu_set_pc;
>  #ifndef CONFIG_USER_ONLY
>      cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
> diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
> index 1db7419..07693d5 100644
> --- a/target-unicore32/cpu.h
> +++ b/target-unicore32/cpu.h
> @@ -137,10 +137,6 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int
>  #define MMU_MODE0_SUFFIX _kernel
>  #define MMU_MODE1_SUFFIX _user
>  #define MMU_USER_IDX 1
> -static inline int cpu_mmu_index(CPUUniCore32State *env)
> -{
> -    return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
> -}
>
>  #include "exec/cpu-all.h"
>  #include "cpu-qom.h"
> diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
> index 46573c6..f99feaa 100644
> --- a/target-xtensa/cpu.c
> +++ b/target-xtensa/cpu.c
> @@ -40,6 +40,13 @@ static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
>      cpu->env.pc = value;
>  }
>
> +static int xtensa_cpu_mmu_index(const CPUState *cs)
> +{
> +    XtensaCPU *cpu = XTENSA_CPU(cs);
> +
> +    return xtensa_get_cring(&cpu->env);
> +}
> +
>  static bool xtensa_cpu_has_work(CPUState *cs)
>  {
>      XtensaCPU *cpu = XTENSA_CPU(cs);
> @@ -142,6 +149,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
>      cc->has_work = xtensa_cpu_has_work;
>      cc->do_interrupt = xtensa_cpu_do_interrupt;
>      cc->dump_state = xtensa_cpu_dump_state;
> +    cc->mmu_index = xtensa_cpu_mmu_index;
>      cc->set_pc = xtensa_cpu_set_pc;
>      cc->gdb_read_register = xtensa_cpu_gdb_read_register;
>      cc->gdb_write_register = xtensa_cpu_gdb_write_register;
> diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
> index de27c8c..4fdaf20 100644
> --- a/target-xtensa/cpu.h
> +++ b/target-xtensa/cpu.h
> @@ -472,11 +472,6 @@ static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
>  #define MMU_MODE2_SUFFIX _ring2
>  #define MMU_MODE3_SUFFIX _ring3
>
> -static inline int cpu_mmu_index(CPUXtensaState *env)
> -{
> -    return xtensa_get_cring(env);
> -}
> -
>  #define XTENSA_TBFLAG_RING_MASK 0x3
>  #define XTENSA_TBFLAG_EXCM 0x4
>  #define XTENSA_TBFLAG_LITBASE 0x8

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

> --
> 1.8.1.4
>
Andreas Färber - Sept. 4, 2013, 12:55 p.m.
Am 04.09.2013 14:42, schrieb Jia Liu:
> On Wed, Sep 4, 2013 at 5:04 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Default to 0.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>

Paolo has indicated that patches 2 and 3 shouldn't be applied since they
touch on TCG hot paths, replacing an inline function with a dispatched
one, thereby possibly leading to performance regressions.

Unfortunately that still means for me that I need to write a boilerplate
inline function returning MMU index 0 for each of my new microcontroller
targets... :/

Andreas

Patch

diff --git a/cputlb.c b/cputlb.c
index fff0afb..85a028f 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -316,12 +316,14 @@  void tlb_set_page(CPUArchState *env, target_ulong vaddr,
  */
 tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
 {
+    CPUState *cpu = ENV_GET_CPU(env1);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     int mmu_idx, page_index, pd;
     void *p;
     MemoryRegion *mr;
 
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    mmu_idx = cpu_mmu_index(env1);
+    mmu_idx = cc->mmu_index(cpu);
     if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
                  (addr & TARGET_PAGE_MASK))) {
         cpu_ldub_code(env1, addr);
@@ -329,9 +331,6 @@  tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
     pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
     mr = iotlb_to_region(pd);
     if (memory_region_is_unassigned(mr)) {
-        CPUState *cpu = ENV_GET_CPU(env1);
-        CPUClass *cc = CPU_GET_CLASS(cpu);
-
         if (cc->do_unassigned_access) {
             cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
         } else {
diff --git a/include/exec/softmmu_header.h b/include/exec/softmmu_header.h
index d8d9c81..e138b87 100644
--- a/include/exec/softmmu_header.h
+++ b/include/exec/softmmu_header.h
@@ -54,12 +54,12 @@ 
 
 #elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(ENV_GET_CPU(env)))
 #define MMUSUFFIX _mmu
 
 #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(ENV_GET_CPU(env)))
 #define MMUSUFFIX _cmmu
 
 #else
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 4d022c3..c78d572 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -76,6 +76,7 @@  struct TranslationBlock;
  * @dump_state: Callback for dumping state.
  * @dump_statistics: Callback for dumping statistics.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
+ * @mmu_index: Callback for obtaining MMU index.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
  * @set_pc: Callback for setting the Program Counter register.
@@ -109,6 +110,7 @@  typedef struct CPUClass {
     void (*dump_statistics)(CPUState *cpu, FILE *f,
                             fprintf_function cpu_fprintf, int flags);
     int64_t (*get_arch_id)(CPUState *cpu);
+    int (*mmu_index)(const CPUState *cpu);
     bool (*get_paging_enabled)(const CPUState *cpu);
     void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
                                Error **errp);
@@ -217,6 +219,19 @@  DECLARE_TLS(CPUState *, current_cpu);
 #define current_cpu tls_var(current_cpu)
 
 /**
+ * cpu_mmu_index:
+ * @cpu: The CPU whose MMU index is to be obtained.
+ *
+ * Returns: MMU index for @cpu.
+ */
+static inline int cpu_mmu_index(CPUState *cpu)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    return cc->mmu_index(cpu);
+}
+
+/**
  * cpu_paging_enabled:
  * @cpu: The CPU whose state is to be inspected.
  *
diff --git a/qom/cpu.c b/qom/cpu.c
index c71fa35..9b9c2c6 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -200,6 +200,11 @@  static void cpu_common_reset(CPUState *cpu)
     cpu->halted = 0;
 }
 
+static int cpu_common_mmu_index(const CPUState *cs)
+{
+    return 0;
+}
+
 static bool cpu_common_has_work(CPUState *cs)
 {
     return false;
@@ -249,6 +254,7 @@  static void cpu_class_init(ObjectClass *klass, void *data)
     k->class_by_name = cpu_common_class_by_name;
     k->reset = cpu_common_reset;
     k->get_arch_id = cpu_common_get_arch_id;
+    k->mmu_index = cpu_common_mmu_index;
     k->has_work = cpu_common_has_work;
     k->get_paging_enabled = cpu_common_get_paging_enabled;
     k->get_memory_mapping = cpu_common_get_memory_mapping;
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 053afa2..15d6f1f 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -31,6 +31,19 @@  static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.pc = value;
 }
 
+static int alpha_cpu_mmu_index(const CPUState *cs)
+{
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+
+    if (cpu->env.pal_mode) {
+        return MMU_KERNEL_IDX;
+    } else if (cpu->env.ps & PS_USER_MODE) {
+        return MMU_USER_IDX;
+    } else {
+        return MMU_KERNEL_IDX;
+    }
+}
+
 static bool alpha_cpu_has_work(CPUState *cs)
 {
     /* Here we are checking to see if the CPU should wake up from HALT.
@@ -289,6 +302,7 @@  static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = alpha_cpu_has_work;
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
+    cc->mmu_index = alpha_cpu_mmu_index;
     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;
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index a172124..808fe53 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -378,17 +378,6 @@  enum {
     PS_USER_MODE = 8
 };
 
-static inline int cpu_mmu_index(CPUAlphaState *env)
-{
-    if (env->pal_mode) {
-        return MMU_KERNEL_IDX;
-    } else if (env->ps & PS_USER_MODE) {
-        return MMU_USER_IDX;
-    } else {
-        return MMU_KERNEL_IDX;
-    }
-}
-
 enum {
     IR_V0   = 0,
     IR_T0   = 1,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 28ce436..50b4339 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3458,7 +3458,7 @@  static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
 
     ctx.tb = tb;
     ctx.pc = pc_start;
-    ctx.mem_idx = cpu_mmu_index(env);
+    ctx.mem_idx = cpu_mmu_index(cs);
     ctx.implver = env->implver;
     ctx.singlestep_enabled = cs->singlestep_enabled;
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index f38c851..6032a2c 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -34,6 +34,13 @@  static void arm_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.regs[15] = value;
 }
 
+static int arm_cpu_mmu_index(const CPUState *cs)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    return (cpu->env.uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
+}
+
 static bool arm_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request &
@@ -899,6 +906,7 @@  static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = arm_cpu_has_work;
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
+    cc->mmu_index = arm_cpu_mmu_index;
     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;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index a42822b..19fa4ee 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -750,10 +750,6 @@  static inline CPUARMState *cpu_init(const char *cpu_model)
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUARMState *env)
-{
-    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
-}
 
 #include "exec/cpu-all.h"
 
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 998cded..1e5b425 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -33,6 +33,13 @@  static void cris_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.pc = value;
 }
 
+static int cris_cpu_mmu_index(const CPUState *cs)
+{
+    CRISCPU *cpu = CRIS_CPU(cs);
+
+    return (cpu->env.pregs[PR_CCS] & U_FLAG) ? 1 : 0;
+}
+
 static bool cris_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
@@ -265,6 +272,7 @@  static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt;
     cc->dump_state = cris_cpu_dump_state;
+    cc->mmu_index = cris_cpu_mmu_index;
     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;
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 15a0497..0914103 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -238,10 +238,6 @@  static inline CPUCRISState *cpu_init(const char *cpu_model)
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-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 mmu_idx);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 617e1b4..29e9f63 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -1125,7 +1125,7 @@  static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
 
 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
 
     /* If we get a fault on a delayslot we must keep the jmp state in
        the cpu-state to be able to re-execute the jmp.  */
@@ -1139,7 +1139,7 @@  static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
              unsigned int size, int sign)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
 
     /* If we get a fault on a delayslot we must keep the jmp state in
        the cpu-state to be able to re-execute the jmp.  */
@@ -1169,7 +1169,7 @@  static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
 static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
                unsigned int size)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
 
     /* If we get a fault on a delayslot we must keep the jmp state in
        the cpu-state to be able to re-execute the jmp.  */
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index d6ef084..0ade05b 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -96,7 +96,7 @@  static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
 static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
                        unsigned int size)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(cris_env_get_cpu(dc->env)));
 
     /* If we get a fault on a delayslot we must keep the jmp state in
        the cpu-state to be able to re-execute the jmp.  */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index fa92950..a623383 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2676,6 +2676,16 @@  static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
     cpu->env.eip = tb->pc - tb->cs_base;
 }
 
+static int x86_cpu_mmu_index(const CPUState *cs)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
+        ((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
+        ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
+}
+
 static bool x86_cpu_has_work(CPUState *cs)
 {
     X86CPU *cpu = X86_CPU(cs);
@@ -2713,6 +2723,7 @@  static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->has_work = x86_cpu_has_work;
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->dump_state = x86_cpu_dump_state;
+    cc->mmu_index = x86_cpu_mmu_index;
     cc->set_pc = x86_cpu_set_pc;
     cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
     cc->gdb_read_register = x86_cpu_gdb_read_register;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 6d46c75..fd16f20 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1123,12 +1123,6 @@  static inline CPUX86State *cpu_init(const char *cpu_model)
 #define MMU_KERNEL_IDX  0
 #define MMU_USER_IDX    1
 #define MMU_KSMAP_IDX   2
-static inline int cpu_mmu_index (CPUX86State *env)
-{
-    return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
-        ((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
-        ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
-}
 
 #define CC_DST  (env->cc_dst)
 #define CC_SRC  (env->cc_src)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 6d87900..2e8e8d5 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8291,7 +8291,7 @@  static inline void gen_intermediate_code_internal(X86CPU *cpu,
     /* select memory access functions */
     dc->mem_index = 0;
     if (flags & HF_SOFTMMU_MASK) {
-        dc->mem_index = (cpu_mmu_index(env) + 1) << 2;
+        dc->mem_index = (cpu_mmu_index(cs) + 1) << 2;
     }
     dc->cpuid_features = env->features[FEAT_1_EDX];
     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index a251a02..11f54e7 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -36,10 +36,6 @@  typedef struct CPULM32State CPULM32State;
 
 #define NB_MMU_MODES 1
 #define TARGET_PAGE_BITS 12
-static inline int cpu_mmu_index(CPULM32State *env)
-{
-    return 0;
-}
 
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 7d66ed0..00454ab 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -30,6 +30,13 @@  static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.pc = value;
 }
 
+static int m68k_cpu_mmu_index(const CPUState *cs)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+
+    return (cpu->env.sr & SR_S) == 0 ? MMU_USER_IDX : 0;
+}
+
 static bool m68k_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request & CPU_INTERRUPT_HARD;
@@ -197,6 +204,7 @@  static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->has_work = m68k_cpu_has_work;
     cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
+    cc->mmu_index = m68k_cpu_mmu_index;
     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;
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 5f79d2a..d1291d8 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -232,10 +232,6 @@  static inline CPUM68KState *cpu_init(const char *cpu_model)
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-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 mmu_idx);
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 6104939..929efd8 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -33,6 +33,20 @@  static void mb_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.sregs[SR_PC] = value;
 }
 
+static int mb_cpu_mmu_index(const CPUState *cs)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+
+        /* Are we in nommu mode?.  */
+        if (!(cpu->env.sregs[SR_MSR] & MSR_VM)) {
+            return MMU_NOMMU_IDX;
+        }
+        if (cpu->env.sregs[SR_MSR] & MSR_UM) {
+            return MMU_USER_IDX;
+        }
+        return MMU_KERNEL_IDX;
+}
+
 static bool mb_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
@@ -147,6 +161,7 @@  static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
+    cc->mmu_index = mb_cpu_mmu_index;
     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;
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 23f96f8..a81f899 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -316,17 +316,6 @@  static inline CPUMBState *cpu_init(const char *cpu_model)
 #define MMU_USER_IDX    2
 /* See NB_MMU_MODES further up the file.  */
 
-static inline int cpu_mmu_index (CPUMBState *env)
-{
-        /* Are we in nommu mode?.  */
-        if (!(env->sregs[SR_MSR] & MSR_VM))
-            return MMU_NOMMU_IDX;
-
-	if (env->sregs[SR_MSR] & MSR_UM)
-            return MMU_USER_IDX;
-        return MMU_KERNEL_IDX;
-}
-
 int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw,
                             int mmu_idx);
 #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index 73bf805..9182934 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -218,6 +218,7 @@  uint32_t mmu_read(CPUMBState *env, uint32_t rn)
 
 void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
 {
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
     unsigned int i;
     D(qemu_log("%s rn=%d=%x old=%x\n", __func__, rn, v, env->mmu.regs[rn]));
 
@@ -277,7 +278,7 @@  void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
             }
 
             hit = mmu_translate(&env->mmu, &lu,
-                                v & TLB_EPN_MASK, 0, cpu_mmu_index(env));
+                                v & TLB_EPN_MASK, 0, cpu_mmu_index(CPU(cpu)));
             if (hit) {
                 env->mmu.regs[MMU_R_TLBX] = lu.idx;
             } else
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 0673176..f4dbe11 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -440,7 +440,7 @@  static void dec_msr(DisasContext *dc)
 {
     TCGv t0, t1;
     unsigned int sr, to, rn;
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     sr = dc->imm & ((1 << 14) - 1);
     to = dc->imm & (1 << 14);
@@ -751,7 +751,7 @@  static void dec_bit(DisasContext *dc)
 {
     TCGv t0, t1;
     unsigned int op;
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     op = dc->ir & ((1 << 9) - 1);
     switch (op) {
@@ -874,7 +874,7 @@  static void dec_imm(DisasContext *dc)
 static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
                             unsigned int size)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     if (size == 1) {
         tcg_gen_qemu_ld8u(dst, addr, mem_index);
@@ -1093,7 +1093,7 @@  static void dec_load(DisasContext *dc)
 static void gen_store(DisasContext *dc, TCGv addr, TCGv val,
                       unsigned int size)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     if (size == 1)
         tcg_gen_qemu_st8(val, addr, mem_index);
@@ -1308,7 +1308,7 @@  static void dec_bcc(DisasContext *dc)
 static void dec_br(DisasContext *dc)
 {
     unsigned int dslot, link, abs, mbar;
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     dslot = dc->ir & (1 << 20);
     abs = dc->ir & (1 << 19);
@@ -1440,7 +1440,7 @@  static inline void do_rte(DisasContext *dc)
 static void dec_rts(DisasContext *dc)
 {
     unsigned int b_bit, i_bit, e_bit;
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
 
     i_bit = dc->ir & (1 << 21);
     b_bit = dc->ir & (1 << 22);
@@ -1616,7 +1616,7 @@  static void dec_null(DisasContext *dc)
 /* Insns connected to FSL or AXI stream attached devices.  */
 static void dec_stream(DisasContext *dc)
 {
-    int mem_index = cpu_mmu_index(dc->env);
+    int mem_index = cpu_mmu_index(CPU(mb_env_get_cpu(dc->env)));
     TCGv_i32 t_id, t_ctrl;
     int ctrl;
 
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 0a2dc46..cb916f3 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -45,6 +45,13 @@  static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
     env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
 }
 
+static int mips_cpu_mmu_index(const CPUState *cs)
+{
+    MIPSCPU *cpu = MIPS_CPU(cs);
+
+    return cpu->env.hflags & MIPS_HFLAG_KSU;
+}
+
 static bool mips_cpu_has_work(CPUState *cs)
 {
     MIPSCPU *cpu = MIPS_CPU(cs);
@@ -129,6 +136,7 @@  static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->has_work = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->dump_state = mips_cpu_dump_state;
+    cc->mmu_index = mips_cpu_mmu_index;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
     cc->gdb_read_register = mips_cpu_gdb_read_register;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index dff2836..22643ff 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -516,10 +516,6 @@  extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
 #define MMU_MODE1_SUFFIX _super
 #define MMU_MODE2_SUFFIX _user
 #define MMU_USER_IDX 2
-static inline int cpu_mmu_index (CPUMIPSState *env)
-{
-    return env->hflags & MIPS_HFLAG_KSU;
-}
 
 static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
 {
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 778cfc0..affcfca 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -136,11 +136,6 @@  static inline CPUMoxieState *cpu_init(const char *cpu_model)
 #define cpu_gen_code cpu_moxie_gen_code
 #define cpu_signal_handler cpu_moxie_signal_handler
 
-static inline int cpu_mmu_index(CPUMoxieState *env)
-{
-    return 0;
-}
-
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index ca8495f..4872fcf 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -27,6 +27,16 @@  static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.pc = value;
 }
 
+static int openrisc_cpu_mmu_index(const CPUState *cs)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+
+    if (!(cpu->env.sr & SR_IME)) {
+        return MMU_NOMMU_IDX;
+    }
+    return (cpu->env.sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
+}
+
 static bool openrisc_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request & (CPU_INTERRUPT_HARD |
@@ -162,6 +172,7 @@  static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = openrisc_cpu_has_work;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
+    cc->mmu_index = openrisc_cpu_mmu_index;
     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;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 4a27f22..2a1ca92 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -409,14 +409,6 @@  static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
     *flags = (env->flags & D_FLAG);
 }
 
-static inline int cpu_mmu_index(CPUOpenRISCState *env)
-{
-    if (!(env->sr & SR_IME)) {
-        return MMU_NOMMU_IDX;
-    }
-    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
-}
-
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
 #include "exec/exec-all.h"
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 723b77d..ea242da 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1679,7 +1679,7 @@  static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->ppc = pc_start;
     dc->pc = pc_start;
     dc->flags = cpu->env.cpucfgr;
-    dc->mem_idx = cpu_mmu_index(&cpu->env);
+    dc->mem_idx = cpu_mmu_index(cs);
     dc->synced_flags = dc->tb_flags = tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
     dc->singlestep_enabled = cs->singlestep_enabled;
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 70c1ef5..9c99f0d 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1183,10 +1183,6 @@  static inline CPUPPCState *cpu_init(const char *cpu_model)
 #define MMU_MODE1_SUFFIX _kernel
 #define MMU_MODE2_SUFFIX _hypv
 #define MMU_USER_IDX 0
-static inline int cpu_mmu_index (CPUPPCState *env)
-{
-    return env->mmu_idx;
-}
 
 #include "exec/cpu-all.h"
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index b552451..e4bcf74 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8437,6 +8437,13 @@  static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.nip = value;
 }
 
+static int ppc_cpu_mmu_index(const CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+    return cpu->env.mmu_idx;
+}
+
 static bool ppc_cpu_has_work(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -8573,6 +8580,7 @@  static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
+    cc->mmu_index = ppc_cpu_mmu_index;
     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;
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index a4c7a33..6b200fe 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -65,6 +65,17 @@  static void s390_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.psw.addr = value;
 }
 
+static int s390_cpu_mmu_index(const CPUState *cs)
+{
+    S390CPU *cpu = S390_CPU(cs);
+
+    if (cpu->env.psw.mask & PSW_MASK_PSTATE) {
+        return 1;
+    }
+
+    return 0;
+}
+
 static bool s390_cpu_has_work(CPUState *cs)
 {
     S390CPU *cpu = S390_CPU(cs);
@@ -229,6 +240,7 @@  static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = s390_cpu_has_work;
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
+    cc->mmu_index = s390_cpu_mmu_index;
     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;
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 3b588af..d7970e6 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -273,15 +273,6 @@  typedef struct CPUS390XState {
 #define FLAG_MASK_64            (PSW_MASK_64     >> 32)
 #define FLAG_MASK_32            0x00001000
 
-static inline int cpu_mmu_index (CPUS390XState *env)
-{
-    if (env->psw.mask & PSW_MASK_PSTATE) {
-        return 1;
-    }
-
-    return 0;
-}
-
 static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 5bf6d9f..df1c0e8 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -39,6 +39,13 @@  static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
     cpu->env.flags = tb->flags;
 }
 
+static int superh_cpu_mmu_index(const CPUState *cs)
+{
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+
+    return (cpu->env.sr & SR_MD) == 0 ? 1 : 0;
+}
+
 static bool superh_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request & CPU_INTERRUPT_HARD;
@@ -291,6 +298,7 @@  static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = superh_cpu_has_work;
     cc->do_interrupt = superh_cpu_do_interrupt;
     cc->dump_state = superh_cpu_dump_state;
+    cc->mmu_index = superh_cpu_mmu_index;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
     cc->gdb_read_register = superh_cpu_gdb_read_register;
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 2eafc2d..6125c20 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -240,10 +240,6 @@  static inline CPUSH4State *cpu_init(const char *cpu_model)
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUSH4State *env)
-{
-    return (env->sr & SR_MD) == 0 ? 1 : 0;
-}
 
 #include "exec/cpu-all.h"
 
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index ede2c80..1d27f9e 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -739,6 +739,30 @@  static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
     cpu->env.npc = tb->cs_base;
 }
 
+static int sparc_cpu_mmu_index(const CPUState *cs)
+{
+#if defined(CONFIG_USER_ONLY)
+    return MMU_USER_IDX;
+#else
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+
+#if !defined(TARGET_SPARC64)
+    return env->psrs;
+#else
+    if (env->tl > 0) {
+        return MMU_NUCLEUS_IDX;
+    } else if (cpu_hypervisor_mode(env)) {
+        return MMU_HYPV_IDX;
+    } else if (cpu_supervisor_mode(env)) {
+        return MMU_KERNEL_IDX;
+    } else {
+        return MMU_USER_IDX;
+    }
+#endif
+#endif
+}
+
 static bool sparc_cpu_has_work(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
@@ -797,6 +821,7 @@  static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
 #endif
+    cc->mmu_index = sparc_cpu_mmu_index;
     cc->set_pc = sparc_cpu_set_pc;
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
     cc->gdb_read_register = sparc_cpu_gdb_read_register;
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index adf6557..93590b8 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -647,25 +647,6 @@  static inline int cpu_supervisor_mode(CPUSPARCState *env1)
 }
 #endif
 
-static inline int cpu_mmu_index(CPUSPARCState *env1)
-{
-#if defined(CONFIG_USER_ONLY)
-    return MMU_USER_IDX;
-#elif !defined(TARGET_SPARC64)
-    return env1->psrs;
-#else
-    if (env1->tl > 0) {
-        return MMU_NUCLEUS_IDX;
-    } else if (cpu_hypervisor_mode(env1)) {
-        return MMU_HYPV_IDX;
-    } else if (cpu_supervisor_mode(env1)) {
-        return MMU_KERNEL_IDX;
-    } else {
-        return MMU_USER_IDX;
-    }
-#endif
-}
-
 static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
 {
 #if !defined (TARGET_SPARC64)
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index ef12a0a..9eb096e 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -842,7 +842,7 @@  hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
     hwaddr phys_addr;
-    int mmu_idx = cpu_mmu_index(env);
+    int mmu_idx = cpu_mmu_index(cs);
     MemoryRegionSection section;
 
     if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 36615f1..73f8b9c 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5241,7 +5241,7 @@  static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
     last_pc = dc->pc;
     dc->npc = (target_ulong) tb->cs_base;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->mem_idx = cpu_mmu_index(env);
+    dc->mem_idx = cpu_mmu_index(cs);
     dc->def = env->def;
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 1cfe50a..3ed9ea3 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -23,6 +23,13 @@  static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.regs[31] = value;
 }
 
+static int uc32_cpu_mmu_index(const CPUState *cs)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+
+    return (cpu->env.uncached_asr & ASR_M) == ASR_MODE_USER ? MMU_USER_IDX : 0;
+}
+
 static bool uc32_cpu_has_work(CPUState *cs)
 {
     return cs->interrupt_request &
@@ -147,6 +154,7 @@  static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = uc32_cpu_has_work;
     cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
+    cc->mmu_index = uc32_cpu_mmu_index;
     cc->set_pc = uc32_cpu_set_pc;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 1db7419..07693d5 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -137,10 +137,6 @@  int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index(CPUUniCore32State *env)
-{
-    return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
-}
 
 #include "exec/cpu-all.h"
 #include "cpu-qom.h"
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 46573c6..f99feaa 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -40,6 +40,13 @@  static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.pc = value;
 }
 
+static int xtensa_cpu_mmu_index(const CPUState *cs)
+{
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+
+    return xtensa_get_cring(&cpu->env);
+}
+
 static bool xtensa_cpu_has_work(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
@@ -142,6 +149,7 @@  static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = xtensa_cpu_has_work;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
+    cc->mmu_index = xtensa_cpu_mmu_index;
     cc->set_pc = xtensa_cpu_set_pc;
     cc->gdb_read_register = xtensa_cpu_gdb_read_register;
     cc->gdb_write_register = xtensa_cpu_gdb_write_register;
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index de27c8c..4fdaf20 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -472,11 +472,6 @@  static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
 #define MMU_MODE2_SUFFIX _ring2
 #define MMU_MODE3_SUFFIX _ring3
 
-static inline int cpu_mmu_index(CPUXtensaState *env)
-{
-    return xtensa_get_cring(env);
-}
-
 #define XTENSA_TBFLAG_RING_MASK 0x3
 #define XTENSA_TBFLAG_EXCM 0x4
 #define XTENSA_TBFLAG_LITBASE 0x8