SSPUSH and SSPOPCHK form their effective address from ssp rather than a GPR, so they bypass get_address() and the pointer-masking ignore transformation is never applied. With pointer masking enabled, a tagged ssp raises a store/AMO page fault, while SSAMOSWAP through the same tagged pointer succeeds.
Apply gen_pm_adjust_addr() to the ssp-derived address. ssp itself is still written back unmasked, and the SSPOPCHK comparison of the loaded value against rs1 is unchanged. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/4758 Co-developed-by: Tarun Patanjali <[email protected]> Signed-off-by: Tarun Patanjali <[email protected]> Co-developed-by: Chris Elwood <[email protected]> Signed-off-by: Chris Elwood <[email protected]> Signed-off-by: Rishab Pradeep <[email protected]> --- target/riscv/tcg/insn_trans/trans_rvzicfiss.c.inc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/riscv/tcg/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/tcg/insn_trans/trans_rvzicfiss.c.inc index d47a9f9c7d..c2dddcc8bb 100644 --- a/target/riscv/tcg/insn_trans/trans_rvzicfiss.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvzicfiss.c.inc @@ -29,6 +29,7 @@ static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a) } TCGv addr = tcg_temp_new(); + TCGv maddr = tcg_temp_new(); TCGLabel *skip = gen_new_label(); uint32_t tmp = (get_xl(ctx) == MXL_RV64) ? 8 : 4; TCGv data = tcg_temp_new(); @@ -36,8 +37,9 @@ static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a) TCGv_i64 wide_addr = tcg_temp_new_i64(); tcg_gen_ld_i64(wide_addr, tcg_env, offsetof(CPURISCVState, ssp)); tcg_gen_trunc_i64_tl(addr, wide_addr); + gen_pm_adjust_addr(ctx, maddr, addr); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); - tcg_gen_qemu_ld_tl(data, addr, SS_MMU_INDEX(ctx), + tcg_gen_qemu_ld_tl(data, maddr, SS_MMU_INDEX(ctx), mxl_memop(ctx) | MO_ALIGN); TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); tcg_gen_brcond_tl(TCG_COND_EQ, data, rs1, skip); @@ -60,6 +62,7 @@ static bool trans_sspush(DisasContext *ctx, arg_sspush *a) } TCGv addr = tcg_temp_new(); + TCGv maddr = tcg_temp_new(); int tmp = (get_xl(ctx) == MXL_RV64) ? -8 : -4; TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); TCGv_i64 wide_addr = tcg_temp_new_i64(); @@ -67,7 +70,8 @@ static bool trans_sspush(DisasContext *ctx, arg_sspush *a) tcg_gen_ld_i64(wide_addr, tcg_env, offsetof(CPURISCVState, ssp)); tcg_gen_trunc_i64_tl(addr, wide_addr); tcg_gen_addi_tl(addr, addr, tmp); - tcg_gen_qemu_st_tl(data, addr, SS_MMU_INDEX(ctx), + gen_pm_adjust_addr(ctx, maddr, addr); + tcg_gen_qemu_st_tl(data, maddr, SS_MMU_INDEX(ctx), mxl_memop(ctx) | MO_ALIGN); tcg_gen_ext_tl_i64(wide_addr, addr); tcg_gen_st_i64(wide_addr, tcg_env, offsetof(CPURISCVState, ssp)); -- 2.54.0 (Apple Git-157)
