target/riscv: Avoid leaking "no translation" TLB entries
authorPalmer Dabbelt <palmer@rivosinc.com>
Wed, 30 Mar 2022 16:59:13 +0000 (09:59 -0700)
committerAlistair Francis <alistair.francis@wdc.com>
Thu, 31 Mar 2022 22:40:42 +0000 (08:40 +1000)
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>
target/riscv/csr.c

index 0606cd0ea80283cbb99e645ebf1fdc8cb53b2887..341c2e6f23cb16c5670ac2f8b400c112d2ed2b97 100644 (file)
@@ -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;
         }
     }