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>
Jim Shu committed
Mar 18, 2026 at 10:42 UTC
38937473da3ebdd89bbe6bbc3effc0b153ceb414
1 file changed
+14
-2
target/riscv/csr.c
+14
-2
@@ -1599,6 +1599,7 @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno,
1599
int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
1600
int i;
1601
*val = 0;
1602
+ bool virt = env->virt_enabled;
1603
1604
/* Virtualize scountovf for counter delegation */
1605
if (riscv_cpu_cfg(env)->ext_sscofpmf &&
@@ -1609,8 +1610,19 @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno,
1610
}
1611
1612
for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
1612
- if ((get_field(env->mcounteren, BIT(i))) &&
1613
- (env->mhpmevent_val[i] & MHPMEVENT_BIT_OF)) {
1613
+ if (env->priv < PRV_M) {
1614
+ if (!get_field(env->mcounteren, BIT(i))) {
1615
+ /* no mcounteren in S/HS-mode */
1616
+ continue;
1617
+ }
1618
+
1619
+ if (virt && !get_field(env->hcounteren, BIT(i))) {
1620
+ /* no hcounteren in VS-mode */
1621
+ continue;
1622
+ }
1623
+ }
1624
+
1625
+ if (env->mhpmevent_val[i] & MHPMEVENT_BIT_OF) {
1626
*val |= BIT(i);
1627
}
1628
}