diff options
Diffstat (limited to 'target-arm/translate-a64.c')
-rw-r--r-- | target-arm/translate-a64.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 96f14ffc7e..acf4b162bd 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -123,6 +123,23 @@ void a64_translate_init(void) #endif } +static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s) +{ + /* Return the mmu_idx to use for A64 "unprivileged load/store" insns: + * if EL1, access as if EL0; otherwise access at current EL + */ + switch (s->mmu_idx) { + case ARMMMUIdx_S12NSE1: + return ARMMMUIdx_S12NSE0; + case ARMMMUIdx_S1SE1: + return ARMMMUIdx_S1SE0; + case ARMMMUIdx_S2NS: + g_assert_not_reached(); + default: + return s->mmu_idx; + } +} + void aarch64_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -2107,7 +2124,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn) } } else { TCGv_i64 tcg_rt = cpu_reg(s, rt); - int memidx = is_unpriv ? MMU_USER_IDX : get_mem_index(s); + int memidx = is_unpriv ? get_a64_user_mem_index(s) : get_mem_index(s); if (is_store) { do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx); |