[PATCH v8 06/13] target/riscv: Only set INH fields if priv mode is available

Atish Patra posted 13 patches 5 months, 2 weeks ago
[PATCH v8 06/13] target/riscv: Only set INH fields if priv mode is available
Posted by Atish Patra 5 months, 2 weeks ago
Currently, the INH fields are set in mhpmevent uncoditionally
without checking if a particular priv mode is supported or not.

Suggested-by: Alistair Francis <alistair23@gmail.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 target/riscv/csr.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b814d176cbb8..121996edab4b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -967,13 +967,24 @@ static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
 {
     int evt_index = csrno - CSR_MCOUNTINHIBIT;
     uint64_t mhpmevt_val = val;
-
-    env->mhpmevent_val[evt_index] = val;
+    uint64_t inh_avail_mask;
 
     if (riscv_cpu_mxl(env) == MXL_RV32) {
+        env->mhpmevent_val[evt_index] = val;
         mhpmevt_val = mhpmevt_val |
                       ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
+    } else {
+        inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
+        inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
+        inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
+        inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+                           riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
+        inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+                           riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
+        mhpmevt_val = val & inh_avail_mask;
+        env->mhpmevent_val[evt_index] = mhpmevt_val;
     }
+
     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
 
     return RISCV_EXCP_NONE;
@@ -993,11 +1004,21 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
                                        target_ulong val)
 {
     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
-    uint64_t mhpmevth_val = val;
+    uint64_t mhpmevth_val;
     uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
+    target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
+                                                  MHPMEVENTH_BIT_MINH);
+
+    inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
+    inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
+    inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+                       riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
+    inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+                       riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
 
+    mhpmevth_val = val & inh_avail_mask;
     mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
-    env->mhpmeventh_val[evt_index] = val;
+    env->mhpmeventh_val[evt_index] = mhpmevth_val;
 
     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
 

-- 
2.34.1
Re: [PATCH v8 06/13] target/riscv: Only set INH fields if priv mode is available
Posted by Alistair Francis 5 months, 2 weeks ago
On Fri, Jul 12, 2024 at 8:34 AM Atish Patra <atishp@rivosinc.com> wrote:
>
> Currently, the INH fields are set in mhpmevent uncoditionally
> without checking if a particular priv mode is supported or not.
>
> Suggested-by: Alistair Francis <alistair23@gmail.com>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>

Thanks!

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 29 +++++++++++++++++++++++++----
>  1 file changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index b814d176cbb8..121996edab4b 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -967,13 +967,24 @@ static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
>  {
>      int evt_index = csrno - CSR_MCOUNTINHIBIT;
>      uint64_t mhpmevt_val = val;
> -
> -    env->mhpmevent_val[evt_index] = val;
> +    uint64_t inh_avail_mask;
>
>      if (riscv_cpu_mxl(env) == MXL_RV32) {
> +        env->mhpmevent_val[evt_index] = val;
>          mhpmevt_val = mhpmevt_val |
>                        ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
> +    } else {
> +        inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
> +        inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
> +        inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
> +        inh_avail_mask |= (riscv_has_ext(env, RVH) &&
> +                           riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
> +        inh_avail_mask |= (riscv_has_ext(env, RVH) &&
> +                           riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
> +        mhpmevt_val = val & inh_avail_mask;
> +        env->mhpmevent_val[evt_index] = mhpmevt_val;
>      }
> +
>      riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
>
>      return RISCV_EXCP_NONE;
> @@ -993,11 +1004,21 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
>                                         target_ulong val)
>  {
>      int evt_index = csrno - CSR_MHPMEVENT3H + 3;
> -    uint64_t mhpmevth_val = val;
> +    uint64_t mhpmevth_val;
>      uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
> +    target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
> +                                                  MHPMEVENTH_BIT_MINH);
> +
> +    inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
> +    inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
> +    inh_avail_mask |= (riscv_has_ext(env, RVH) &&
> +                       riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
> +    inh_avail_mask |= (riscv_has_ext(env, RVH) &&
> +                       riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
>
> +    mhpmevth_val = val & inh_avail_mask;
>      mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
> -    env->mhpmeventh_val[evt_index] = val;
> +    env->mhpmeventh_val[evt_index] = mhpmevth_val;
>
>      riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
>
>
> --
> 2.34.1
>
>