On Sat, Mar 25, 2023 at 10:42 PM Richard Henderson <richard.hender...@linaro.org> wrote: > > Table 9.5 "Effect of MPRV..." specifies that MPV=1 uses VS-level > vsstatus.SUM instead of HS-level sstatus.SUM. > > For HLV/HSV instructions, the HS-level register does not apply, but > the VS-level register presumably does, though this is not mentioned > explicitly in the manual. However, it matches the behavior for MPV. > > Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu_helper.c | 12 ++++++++---- > target/riscv/op_helper.c | 6 +++++- > 2 files changed, 13 insertions(+), 5 deletions(-) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 6c42f9c6fd..0017ecbf37 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -42,11 +42,16 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) > > /* All priv -> mmu_idx mapping are here */ > if (!ifetch) { > - if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) { > + uint64_t status = env->mstatus; > + > + if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) { > mode = get_field(env->mstatus, MSTATUS_MPP); > virt = get_field(env->mstatus, MSTATUS_MPV); > + if (virt) { > + status = env->vsstatus; > + } > } > - if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) { > + if (mode == PRV_S && get_field(status, MSTATUS_SUM)) { > mode = MMUIdx_S_SUM; > } > } > @@ -838,8 +843,7 @@ static int get_physical_address(CPURISCVState *env, > hwaddr *physical, > } > widened = 2; > } > - /* status.SUM will be ignored if execute on background */ > - sum = mmuidx_sum(mmu_idx) || use_background || is_debug; > + sum = mmuidx_sum(mmu_idx) || is_debug; > switch (vm) { > case VM_1_10_SV32: > levels = 2; ptidxbits = 10; ptesize = 4; break; > diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c > index db7252e09d..93d4ae8b3e 100644 > --- a/target/riscv/op_helper.c > +++ b/target/riscv/op_helper.c > @@ -437,7 +437,11 @@ static int check_access_hlsv(CPURISCVState *env, bool x, > uintptr_t ra) > riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra); > } > > - return get_field(env->hstatus, HSTATUS_SPVP) | MMU_2STAGE_BIT; > + int mode = get_field(env->hstatus, HSTATUS_SPVP); > + if (!x && mode == PRV_S && get_field(env->vsstatus, MSTATUS_SUM)) { > + mode = MMUIdx_S_SUM; > + } > + return mode | MMU_2STAGE_BIT; > } > > target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr) > -- > 2.34.1 > >