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)


Reply via email to