aboutsummaryrefslogtreecommitdiff
path: root/target/riscv
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@rivosinc.com>2022-03-30 09:59:13 -0700
committerAlistair Francis <alistair.francis@wdc.com>2022-04-01 08:40:42 +1000
commit5242ef887dd06659e3d516cb4000c8ed3277fb08 (patch)
treef4337ac60e09e86cec5699ad18edcabe87bbfbe0 /target/riscv
parentd5341e09135b871199073572f53bc11ae9b44897 (diff)
target/riscv: Avoid leaking "no translation" TLB entries
The ISA doesn't allow bare mappings to be cached, as the caches are translations and bare mppings are not translated. We cache these translations in QEMU in order to utilize the TLB code, but that leaks out to the guest. Suggested-by: phantom@zju.edu.cn # no name in the From field Fixes: 1e0d985fa9 ("target/riscv: Only flush TLB if SATP.ASID changes") Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20220330165913.8836-1-palmer@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv')
-rw-r--r--target/riscv/csr.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0606cd0ea8..341c2e6f23 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1844,7 +1844,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
static RISCVException write_satp(CPURISCVState *env, int csrno,
target_ulong val)
{
- target_ulong vm, mask, asid;
+ target_ulong vm, mask;
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
return RISCV_EXCP_NONE;
@@ -1853,20 +1853,22 @@ static RISCVException write_satp(CPURISCVState *env, int csrno,
if (riscv_cpu_mxl(env) == MXL_RV32) {
vm = validate_vm(env, get_field(val, SATP32_MODE));
mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
- asid = (val ^ env->satp) & SATP32_ASID;
} else {
vm = validate_vm(env, get_field(val, SATP64_MODE));
mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
- asid = (val ^ env->satp) & SATP64_ASID;
}
if (vm && mask) {
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
return RISCV_EXCP_ILLEGAL_INST;
} else {
- if (asid) {
- tlb_flush(env_cpu(env));
- }
+ /*
+ * The ISA defines SATP.MODE=Bare as "no translation", but we still
+ * pass these through QEMU's TLB emulation as it improves
+ * performance. Flushing the TLB on SATP writes with paging
+ * enabled avoids leaking those invalid cached mappings.
+ */
+ tlb_flush(env_cpu(env));
env->satp = val;
}
}