@samitouri / QOSamiQemu / commits / 38937473da

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 }