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);
}
}