Commit 38937473da for qemu.org

commit 38937473da3ebdd89bbe6bbc3effc0b153ceb414
Author: Jim Shu <jim.shu@sifive.com>
Date:   Wed Mar 18 10:42:34 2026 +0800

    target/riscv: Fix scountovf CSR behavior in VS-mode and M-mode

    From Sscofpmf spec [1]:
    - In M-mode, scountovf bit X is always readable.
    - in VS mode, scountovf bit X is readable when mcounteren bit X and
      hcounteren bit X are both set, and otherwise reads as zero.

    [1] https://github.com/riscv/riscv-isa-manual/blob/main/src/sscofpmf.adoc

    Signed-off-by: Jim Shu <jim.shu@sifive.com>
    Signed-off-by: Max Chou <max.chou@sifive.com>
    Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
    Message-ID: <20260318024234.2772480-1-jim.shu@sifive.com>
    Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5064483917..a75281539b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1599,6 +1599,7 @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno,
     int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
     int i;
     *val = 0;
+    bool virt = env->virt_enabled;

     /* Virtualize scountovf for counter delegation */
     if (riscv_cpu_cfg(env)->ext_sscofpmf &&
@@ -1609,8 +1610,19 @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno,
     }

     for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
-        if ((get_field(env->mcounteren, BIT(i))) &&
-            (env->mhpmevent_val[i] & MHPMEVENT_BIT_OF)) {
+        if (env->priv < PRV_M) {
+            if (!get_field(env->mcounteren, BIT(i))) {
+                /* no mcounteren in S/HS-mode */
+                continue;
+            }
+
+            if (virt && !get_field(env->hcounteren, BIT(i))) {
+                /* no hcounteren in VS-mode */
+                continue;
+            }
+        }
+
+        if (env->mhpmevent_val[i] & MHPMEVENT_BIT_OF) {
             *val |= BIT(i);
         }
     }