From: Alexey Baturo <baturo.ale...@gmail.com> Signed-off-by: Alexey Baturo <baturo.ale...@gmail.com> --- target/riscv/cpu.h | 2 ++ target/riscv/cpu_helper.c | 19 +++++++++++++++++++ target/riscv/insn_trans/trans_rvh.c.inc | 11 +++++++++++ target/riscv/translate.c | 4 ++++ 4 files changed, 36 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 11e3a6d647..6bbd9c6c25 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -634,6 +634,7 @@ FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1) /* If pointer masking should be applied and address sign extended */ FIELD(TB_FLAGS, PM_PMM, 29, 2) FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1) +FIELD(TB_FLAGS, PM_VPMM, 32, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -773,6 +774,7 @@ bool riscv_cpu_is_32bit(RISCVCPU *cpu); bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env); int riscv_pm_get_pmlen(RISCVPmPmm pmm); RISCVException riscv_csrr(CPURISCVState *env, int csrno, diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 78b461a5cf..4065809d9f 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -213,6 +213,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); + flags = FIELD_DP64(flags, TB_FLAGS, PM_VPMM, riscv_pm_get_virt_pmm(env)); *pflags = flags; } @@ -260,6 +261,24 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) return pmm; } +RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env) +{ + RISCVPmPmm pmm = PMM_FIELD_DISABLED; +#ifndef CONFIG_USER_ONLY + int priv_mode = cpu_address_mode(env); + if (priv_mode == PRV_U) { + pmm = get_field(env->hstatus, HSTATUS_HUPMM); + } else { + if (get_field(env->hstatus, HSTATUS_SPVP)) { + pmm = get_field(env->henvcfg, HENVCFG_PMM); + } else { + pmm = get_field(env->senvcfg, SENVCFG_PMM); + } + } +#endif + return pmm; +} + bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) { bool virt_mem_en = false; diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc index 03c6694430..ae067789d1 100644 --- a/target/riscv/insn_trans/trans_rvh.c.inc +++ b/target/riscv/insn_trans/trans_rvh.c.inc @@ -44,6 +44,14 @@ static bool do_hlv(DisasContext *ctx, arg_r2 *a, TCGv dest = dest_gpr(ctx, a->rd); TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); + bool is_hlvx = (func == gen_helper_hyp_hlvx_hu) || + (func == gen_helper_hyp_hlvx_wu); + + /* Apply Zjpm pointer masking */ + if (!is_hlvx) { + tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_vxl); + } + decode_save_opc(ctx, 0); func(dest, tcg_env, addr); gen_set_gpr(ctx, a->rd, dest); @@ -56,6 +64,9 @@ static bool do_hsv(DisasContext *ctx, arg_r2_s *a, TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); + /* Apply Zjpm pointer masking */ + tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_vxl); + decode_save_opc(ctx, 0); func(tcg_env, addr, data); return true; diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 32df295123..d8f83315c6 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -104,6 +104,7 @@ typedef struct DisasContext { TCGv zero; /* actual address width */ uint8_t addr_xl; + uint8_t addr_vxl; bool addr_signed; /* Ztso */ bool ztso; @@ -1239,10 +1240,13 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->cs = cs; if (get_xl(ctx) == MXL_RV32) { ctx->addr_xl = 32; + ctx->addr_vxl = 32; ctx->addr_signed = false; } else { int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); ctx->addr_xl = 64 - riscv_pm_get_pmlen(pm_pmm); + int pm_vpmm = FIELD_EX64(tb_flags, TB_FLAGS, PM_VPMM); + ctx->addr_vxl = 64 - riscv_pm_get_pmlen(pm_vpmm); ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); } ctx->ztso = cpu->cfg.ext_ztso; -- 2.39.5