On Sat, Mar 25, 2023 at 9:58 PM Richard Henderson <richard.hender...@linaro.org> wrote: > > Incorporate the virt_enabled and MPV checks into the cpu_mmu_index > function, so we don't have to keep doing it within tlb_fill and > subroutines. This also elides a flush on changes to MPV. > > Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu_helper.c | 50 +++++++++++++-------------------------- > target/riscv/csr.c | 6 +---- > 2 files changed, 18 insertions(+), 38 deletions(-) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 0adfd4a12b..6c42f9c6fd 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -37,19 +37,21 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) > #ifdef CONFIG_USER_ONLY > return 0; > #else > - if (ifetch) { > - return env->priv; > - } > + bool virt = riscv_cpu_virt_enabled(env); > + int mode = env->priv; > > /* All priv -> mmu_idx mapping are here */ > - int mode = env->priv; > - if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) { > - mode = get_field(env->mstatus, MSTATUS_MPP); > + if (!ifetch) { > + if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) { > + mode = get_field(env->mstatus, MSTATUS_MPP); > + virt = get_field(env->mstatus, MSTATUS_MPV); > + } > + if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) { > + mode = MMUIdx_S_SUM; > + } > } > - if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) { > - return MMUIdx_S_SUM; > - } > - return mode; > + > + return mode | (virt ? MMU_2STAGE_BIT : 0); > #endif > } > > @@ -1165,8 +1167,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, > hwaddr physaddr, > } > > env->badaddr = addr; > - env->two_stage_lookup = riscv_cpu_virt_enabled(env) || > - mmuidx_2stage(mmu_idx); > + env->two_stage_lookup = mmuidx_2stage(mmu_idx); > env->two_stage_indirect_lookup = false; > cpu_loop_exit_restore(cs, retaddr); > } > @@ -1191,8 +1192,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr > addr, > g_assert_not_reached(); > } > env->badaddr = addr; > - env->two_stage_lookup = riscv_cpu_virt_enabled(env) || > - mmuidx_2stage(mmu_idx); > + env->two_stage_lookup = mmuidx_2stage(mmu_idx); > env->two_stage_indirect_lookup = false; > cpu_loop_exit_restore(cs, retaddr); > } > @@ -1230,7 +1230,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, > int size, > int prot, prot2, prot_pmp; > bool pmp_violation = false; > bool first_stage_error = true; > - bool two_stage_lookup = false; > + bool two_stage_lookup = mmuidx_2stage(mmu_idx); > bool two_stage_indirect_error = false; > int ret = TRANSLATE_FAIL; > int mode = mmu_idx; > @@ -1242,22 +1242,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, > int size, > qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n", > __func__, address, access_type, mmu_idx); > > - /* MPRV does not affect the virtual-machine load/store > - instructions, HLV, HLVX, and HSV. */ > - if (mmuidx_2stage(mmu_idx)) { > - ; > - } else if (mode == PRV_M && access_type != MMU_INST_FETCH && > - get_field(env->mstatus, MSTATUS_MPRV)) { > - mode = get_field(env->mstatus, MSTATUS_MPP); > - if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) > { > - two_stage_lookup = true; > - } > - } > - > pmu_tlb_fill_incr_ctr(cpu, access_type); > - if (riscv_cpu_virt_enabled(env) || > - ((mmuidx_2stage(mmu_idx) || two_stage_lookup) && > - access_type != MMU_INST_FETCH)) { > + if (two_stage_lookup) { > /* Two stage lookup */ > ret = get_physical_address(env, &pa, &prot, address, > &env->guest_phys_fault_addr, access_type, > @@ -1352,9 +1338,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, > int size, > return false; > } else { > raise_mmu_exception(env, address, access_type, pmp_violation, > - first_stage_error, > - riscv_cpu_virt_enabled(env) || > - mmuidx_2stage(mmu_idx), > + first_stage_error, two_stage_lookup, > two_stage_indirect_error); > cpu_loop_exit_restore(cs, retaddr); > } > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index b79758a606..1b635373c6 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -1246,7 +1246,7 @@ static RISCVException write_mstatus(CPURISCVState *env, > int csrno, > RISCVMXL xl = riscv_cpu_mxl(env); > > /* flush tlb on mstatus fields that affect VM */ > - if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPV)) { > + if ((val ^ mstatus) & MSTATUS_MXR) { > tlb_flush(env_cpu(env)); > } > mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | > @@ -1294,10 +1294,6 @@ static RISCVException write_mstatush(CPURISCVState > *env, int csrno, > uint64_t valh = (uint64_t)val << 32; > uint64_t mask = MSTATUS_MPV | MSTATUS_GVA; > > - if ((valh ^ env->mstatus) & (MSTATUS_MPV)) { > - tlb_flush(env_cpu(env)); > - } > - > env->mstatus = (env->mstatus & ~mask) | (valh & mask); > > return RISCV_EXCP_NONE; > -- > 2.34.1 > >