[PATCH v8 02/12] target/riscv: Implement PMU CSR predicate function for S-mode

From: Atish Patra
Date: Wed May 11 2022 - 18:00:27 EST


From: Atish Patra <atish.patra@xxxxxxx>

Currently, the predicate function for PMU related CSRs only works if
virtualization is enabled. It also does not check mcounteren bits before
before cycle/minstret/hpmcounterx access.

Support supervisor mode access in the predicate function as well.

Reviewed-by: Alistair Francis <alistair.francis@xxxxxxx>
Reviewed-by: Bin Meng <bmeng.cn@xxxxxxxxx>
Signed-off-by: Atish Patra <atish.patra@xxxxxxx>
Signed-off-by: Atish Patra <atishp@xxxxxxxxxxxx>
---
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ee3a35afa256..d175fe3f1af3 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -79,6 +79,57 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
return RISCV_EXCP_ILLEGAL_INST;
}

+ if (env->priv == PRV_S) {
+ switch (csrno) {
+ case CSR_CYCLE:
+ if (!get_field(env->mcounteren, COUNTEREN_CY)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_TIME:
+ if (!get_field(env->mcounteren, COUNTEREN_TM)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_INSTRET:
+ if (!get_field(env->mcounteren, COUNTEREN_IR)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
+ ctr_index = csrno - CSR_CYCLE;
+ if (!get_field(env->mcounteren, 1 << ctr_index)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ }
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ switch (csrno) {
+ case CSR_CYCLEH:
+ if (!get_field(env->mcounteren, COUNTEREN_CY)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_TIMEH:
+ if (!get_field(env->mcounteren, COUNTEREN_TM)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_INSTRETH:
+ if (!get_field(env->mcounteren, COUNTEREN_IR)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
+ ctr_index = csrno - CSR_CYCLEH;
+ if (!get_field(env->mcounteren, 1 << ctr_index)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ break;
+ }
+ }
+ }
+
if (riscv_cpu_virt_enabled(env)) {
switch (csrno) {
case CSR_CYCLE:
--
2.25.1