aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/cpu_helper.c
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2019-06-25 04:08:38 +1000
committerPalmer Dabbelt <palmer@sifive.com>2019-06-25 22:37:04 -0700
commitc13b169f1a3dd158d6c75727cdc388f95988db39 (patch)
treed23c2fd911b809c36128fa626e36076a31253826 /target/riscv/cpu_helper.c
parent591bddea8d874e1500921de0353818e5586618f5 (diff)
RISC-V: Clear load reservations on context switch and SC
This prevents a load reservation from being placed in one context/process, then being used in another, resulting in an SC succeeding incorrectly and breaking atomics. Signed-off-by: Joel Sing <joel@sing.id.au> Reviewed-by: Palmer Dabbelt <palmer@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv/cpu_helper.c')
-rw-r--r--target/riscv/cpu_helper.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e1b079e69c..e32b6126af 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -132,6 +132,16 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
}
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
+
+ /*
+ * Clear the load reservation - otherwise a reservation placed in one
+ * context/process can be used by another, resulting in an SC succeeding
+ * incorrectly. Version 2.2 of the ISA specification explicitly requires
+ * this behaviour, while later revisions say that the kernel "should" use
+ * an SC instruction to force the yielding of a load reservation on a
+ * preemptive context switch. As a result, do both.
+ */
+ env->load_res = -1;
}
/* get_physical_address - get the physical address for this virtual address