aboutsummaryrefslogtreecommitdiff
path: root/target/riscv
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <dbarboza@ventanamicro.com>2024-03-06 14:19:24 -0300
committerAlistair Francis <alistair.francis@wdc.com>2024-03-08 20:48:03 +1000
commit944b6dfd3d67236882f2bc09d1d30ed923268e16 (patch)
tree7f9f7493e97ec1268e60b518bb4baa1190f57a88 /target/riscv
parente231ec8f677d94ee38316bce8e8bad3e324b0434 (diff)
trans_rvv.c.inc: mark_vs_dirty() before loads and stores
While discussing a problem with how we're (not) setting vstart_eq_zero Richard had the following to say w.r.t the conditional mark_vs_dirty() calls on load/store functions [1]: "I think it's required to have stores set dirty unconditionally, before the operation. Consider a store that traps on the 2nd element, leaving vstart = 2, and exiting to the main loop via exception. The exception enters the kernel page fault handler. The kernel may need to fault in the page for the process, and in the meantime task switch. If vs dirty is not already set, the kernel won't know to save vector state on task switch." Do a mark_vs_dirty() before both loads and stores. [1] https://lore.kernel.org/qemu-riscv/72c7503b-0f43-44b8-aa82-fbafed2aac0c@linaro.org/ Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20240306171932.549549-2-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv')
-rw-r--r--target/riscv/insn_trans/trans_rvv.c.inc23
1 files changed, 8 insertions, 15 deletions
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 742008f58b..b838b8ea5b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -652,16 +652,14 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
}
+ mark_vs_dirty(s);
+
fn(dest, mask, base, tcg_env, desc);
if (!is_store && s->ztso) {
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
}
- if (!is_store) {
- mark_vs_dirty(s);
- }
-
gen_set_label(over);
return true;
}
@@ -817,11 +815,9 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
- fn(dest, mask, base, stride, tcg_env, desc);
+ mark_vs_dirty(s);
- if (!is_store) {
- mark_vs_dirty(s);
- }
+ fn(dest, mask, base, stride, tcg_env, desc);
gen_set_label(over);
return true;
@@ -924,11 +920,9 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
tcg_gen_addi_ptr(index, tcg_env, vreg_ofs(s, vs2));
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
- fn(dest, mask, base, index, tcg_env, desc);
+ mark_vs_dirty(s);
- if (!is_store) {
- mark_vs_dirty(s);
- }
+ fn(dest, mask, base, index, tcg_env, desc);
gen_set_label(over);
return true;
@@ -1122,11 +1116,10 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
base = get_gpr(s, rs1, EXT_NONE);
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
+ mark_vs_dirty(s);
+
fn(dest, base, tcg_env, desc);
- if (!is_store) {
- mark_vs_dirty(s);
- }
gen_set_label(over);
return true;