Priv spec chapter "Svpbmt Extension for Page-Based Memory Types, Version
1.0" mentions that "The Svpbmt extension depends on the Sv39
extension.".

We're not doing any satp checks when enabling svpbmt.  This causes
problems with the riscv32 'max' CPU that happens to be enabling svpbmt
even though it doesn't support the required satp mode.  In fact all rv32
CPUs are allowing menvcfg.PBMTE writes, which doesn't make sense for
them in any circunstance since svpbmt is not possible for rv32 at this
moment [1].

This also impacts rv64 CPUs that are running in satp 'bare' mode and are
reporting svpbmt in the riscv,isa.

All these problems can be solved by disabling svpbmt if satp_mode is not
at least sv39.  The problem reported in [1] goes away because we'll
never enable MENVCFG_PBMTE write mask in write_menvcfgh().  We're also
become consistent with how svpbmt is enabled for rv64.

In case the user enables svpbmt in the command line using an invalid setup,
not just disable svpbmt but also throw a warning:

$ ./build/qemu-system-riscv64 -M virt,dumpdtb=fdt.dtb \
    -cpu max,sv39=off,sv48=off,sv57=off,sv64=off,svpbmt=on
qemu-system-riscv64: warning: svpbmt requires at least satp sv39, current satp 
mode: none

[1] https://gitlab.com/qemu-project/qemu/-/work_items/3473

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3473
Signed-off-by: Daniel Henrique Barboza <[email protected]>
---
 target/riscv/tcg/tcg-cpu.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a358d91ca5..5b3e36d9ab 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -887,6 +887,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
         return;
     }
 
+#ifndef CONFIG_USER_ONLY
+    if (cpu->cfg.ext_svpbmt && cpu->cfg.max_satp_mode < VM_1_10_SV39) {
+        cpu->cfg.ext_svpbmt = false;
+        if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_svpbmt))) {
+            warn_report("svpbmt requires at least satp sv39, "
+                        "current satp mode: %s",
+                        satp_mode_str(cpu->cfg.max_satp_mode,
+                                     riscv_cpu_is_32bit(cpu)));
+        }
+    }
+#endif
     /*
      * Disable isa extensions based on priv spec after we
      * validated and set everything we need.
-- 
2.43.0


Reply via email to