diff mbox series

target/riscv: fix csr check for cycle{h}, instret{h}, time{h}, hpmcounter3~31{h}

Message ID 20220702134149.14384-1-liweiwei@iscas.ac.cn (mailing list archive)
State New, archived
Headers show
Series target/riscv: fix csr check for cycle{h}, instret{h}, time{h}, hpmcounter3~31{h} | expand

Commit Message

Weiwei Li July 2, 2022, 1:41 p.m. UTC
- improve the field extract progress
- add stand-alone check for mcuonteren when in less-privileged mode
- add check for scounteren when 'S' is enabled and current priv is PRV_U

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 target/riscv/csr.c | 76 ++++++++++++++--------------------------------
 1 file changed, 22 insertions(+), 54 deletions(-)

Comments

Alistair Francis July 21, 2022, 4:31 a.m. UTC | #1
On Sat, Jul 2, 2022 at 11:42 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> - improve the field extract progress
> - add stand-alone check for mcuonteren when in less-privileged mode
> - add check for scounteren when 'S' is enabled and current priv is PRV_U
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>

+ Atish

Alistair

> ---
>  target/riscv/csr.c | 76 ++++++++++++++--------------------------------
>  1 file changed, 22 insertions(+), 54 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6dbe9b541f..a4719cbf35 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -72,66 +72,34 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
>  #if !defined(CONFIG_USER_ONLY)
>      CPUState *cs = env_cpu(env);
>      RISCVCPU *cpu = RISCV_CPU(cs);
> +    uint32_t field = 0;
>
>      if (!cpu->cfg.ext_counters) {
>          /* The Counters extensions is not enabled */
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
>
> -    if (riscv_cpu_virt_enabled(env)) {
> -        switch (csrno) {
> -        case CSR_CYCLE:
> -            if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> -                get_field(env->mcounteren, COUNTEREN_CY)) {
> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -            }
> -            break;
> -        case CSR_TIME:
> -            if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> -                get_field(env->mcounteren, COUNTEREN_TM)) {
> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -            }
> -            break;
> -        case CSR_INSTRET:
> -            if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> -                get_field(env->mcounteren, COUNTEREN_IR)) {
> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -            }
> -            break;
> -        case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> -            if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
> -                get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -            }
> -            break;
> -        }
> -        if (riscv_cpu_mxl(env) == MXL_RV32) {
> -            switch (csrno) {
> -            case CSR_CYCLEH:
> -                if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> -                    get_field(env->mcounteren, COUNTEREN_CY)) {
> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -                }
> -                break;
> -            case CSR_TIMEH:
> -                if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> -                    get_field(env->mcounteren, COUNTEREN_TM)) {
> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -                }
> -                break;
> -            case CSR_INSTRETH:
> -                if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> -                    get_field(env->mcounteren, COUNTEREN_IR)) {
> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -                }
> -                break;
> -            case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> -                if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
> -                    get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> -                }
> -                break;
> -            }
> +    if (csrno <= CSR_HPMCOUNTER31 && csrno >= CSR_CYCLE) {
> +        field = 1 << (csrno - CSR_CYCLE);
> +    } else if (riscv_cpu_mxl(env) == MXL_RV32 && csrno <= CSR_HPMCOUNTER31H &&
> +               csrno >= CSR_CYCLEH) {
> +        field = 1 << (csrno - CSR_CYCLEH);
> +    }
> +
> +    if (env->priv < PRV_M && !get_field(env->mcounteren, field)) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
> +
> +    if (riscv_cpu_virt_enabled(env) && !get_field(env->hcounteren, field)) {
> +        return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> +    }
> +
> +    if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
> +        !get_field(env->scounteren, field)) {
> +        if (riscv_cpu_virt_enabled(env)) {
> +            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> +        } else {
> +            return RISCV_EXCP_ILLEGAL_INST;
>          }
>      }
>  #endif
> --
> 2.17.1
>
>
Atish Patra July 26, 2022, 11:34 p.m. UTC | #2
On Wed, Jul 20, 2022 at 9:32 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Sat, Jul 2, 2022 at 11:42 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
> >
> > - improve the field extract progress

This part is already improved with the PMU series.

https://www.mail-archive.com/qemu-devel@nongnu.org/msg895143.html

> > - add stand-alone check for mcuonteren when in less-privileged mode
> > - add check for scounteren when 'S' is enabled and current priv is PRV_U
> >

These two parts are fine. I am resending the remaining patches for the
PMU series.
Can you please rebase your top and resend it ?

> > Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> > Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>
> + Atish
>
> Alistair
>
> > ---
> >  target/riscv/csr.c | 76 ++++++++++++++--------------------------------
> >  1 file changed, 22 insertions(+), 54 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 6dbe9b541f..a4719cbf35 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -72,66 +72,34 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
> >  #if !defined(CONFIG_USER_ONLY)
> >      CPUState *cs = env_cpu(env);
> >      RISCVCPU *cpu = RISCV_CPU(cs);
> > +    uint32_t field = 0;
> >
> >      if (!cpu->cfg.ext_counters) {
> >          /* The Counters extensions is not enabled */
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >
> > -    if (riscv_cpu_virt_enabled(env)) {
> > -        switch (csrno) {
> > -        case CSR_CYCLE:
> > -            if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> > -                get_field(env->mcounteren, COUNTEREN_CY)) {
> > -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -            }
> > -            break;
> > -        case CSR_TIME:
> > -            if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> > -                get_field(env->mcounteren, COUNTEREN_TM)) {
> > -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -            }
> > -            break;
> > -        case CSR_INSTRET:
> > -            if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> > -                get_field(env->mcounteren, COUNTEREN_IR)) {
> > -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -            }
> > -            break;
> > -        case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -            if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
> > -                get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
> > -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -            }
> > -            break;
> > -        }
> > -        if (riscv_cpu_mxl(env) == MXL_RV32) {
> > -            switch (csrno) {
> > -            case CSR_CYCLEH:
> > -                if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> > -                    get_field(env->mcounteren, COUNTEREN_CY)) {
> > -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -                }
> > -                break;
> > -            case CSR_TIMEH:
> > -                if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> > -                    get_field(env->mcounteren, COUNTEREN_TM)) {
> > -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -                }
> > -                break;
> > -            case CSR_INSTRETH:
> > -                if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> > -                    get_field(env->mcounteren, COUNTEREN_IR)) {
> > -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -                }
> > -                break;
> > -            case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> > -                if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
> > -                    get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
> > -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -                }
> > -                break;
> > -            }
> > +    if (csrno <= CSR_HPMCOUNTER31 && csrno >= CSR_CYCLE) {
> > +        field = 1 << (csrno - CSR_CYCLE);
> > +    } else if (riscv_cpu_mxl(env) == MXL_RV32 && csrno <= CSR_HPMCOUNTER31H &&
> > +               csrno >= CSR_CYCLEH) {
> > +        field = 1 << (csrno - CSR_CYCLEH);
> > +    }
> > +
> > +    if (env->priv < PRV_M && !get_field(env->mcounteren, field)) {
> > +        return RISCV_EXCP_ILLEGAL_INST;
> > +    }
> > +
> > +    if (riscv_cpu_virt_enabled(env) && !get_field(env->hcounteren, field)) {
> > +        return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > +    }
> > +
> > +    if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
> > +        !get_field(env->scounteren, field)) {
> > +        if (riscv_cpu_virt_enabled(env)) {
> > +            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > +        } else {
> > +            return RISCV_EXCP_ILLEGAL_INST;
> >          }
> >      }
> >  #endif
> > --
> > 2.17.1
> >
> >
Weiwei Li July 27, 2022, 1:52 a.m. UTC | #3
在 2022/7/27 上午7:34, Atish Patra 写道:
> On Wed, Jul 20, 2022 at 9:32 PM Alistair Francis <alistair23@gmail.com> wrote:
>> On Sat, Jul 2, 2022 at 11:42 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>>> - improve the field extract progress
> This part is already improved with the PMU series.
>
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg895143.html
Yeah, I have replied on this patch a few days ago.
>
>>> - add stand-alone check for mcuonteren when in less-privileged mode
>>> - add check for scounteren when 'S' is enabled and current priv is PRV_U
>>>
> These two parts are fine. I am resending the remaining patches for the
> PMU series.
> Can you please rebase your top and resend it ?

Ok. I'll rebase and resend it later.

Regards,

Weiwei Li

>
>>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> + Atish
>>
>> Alistair
>>
>>> ---
>>>   target/riscv/csr.c | 76 ++++++++++++++--------------------------------
>>>   1 file changed, 22 insertions(+), 54 deletions(-)
>>>
>>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>>> index 6dbe9b541f..a4719cbf35 100644
>>> --- a/target/riscv/csr.c
>>> +++ b/target/riscv/csr.c
>>> @@ -72,66 +72,34 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
>>>   #if !defined(CONFIG_USER_ONLY)
>>>       CPUState *cs = env_cpu(env);
>>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>> +    uint32_t field = 0;
>>>
>>>       if (!cpu->cfg.ext_counters) {
>>>           /* The Counters extensions is not enabled */
>>>           return RISCV_EXCP_ILLEGAL_INST;
>>>       }
>>>
>>> -    if (riscv_cpu_virt_enabled(env)) {
>>> -        switch (csrno) {
>>> -        case CSR_CYCLE:
>>> -            if (!get_field(env->hcounteren, COUNTEREN_CY) &&
>>> -                get_field(env->mcounteren, COUNTEREN_CY)) {
>>> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -            }
>>> -            break;
>>> -        case CSR_TIME:
>>> -            if (!get_field(env->hcounteren, COUNTEREN_TM) &&
>>> -                get_field(env->mcounteren, COUNTEREN_TM)) {
>>> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -            }
>>> -            break;
>>> -        case CSR_INSTRET:
>>> -            if (!get_field(env->hcounteren, COUNTEREN_IR) &&
>>> -                get_field(env->mcounteren, COUNTEREN_IR)) {
>>> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -            }
>>> -            break;
>>> -        case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
>>> -            if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
>>> -                get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
>>> -                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -            }
>>> -            break;
>>> -        }
>>> -        if (riscv_cpu_mxl(env) == MXL_RV32) {
>>> -            switch (csrno) {
>>> -            case CSR_CYCLEH:
>>> -                if (!get_field(env->hcounteren, COUNTEREN_CY) &&
>>> -                    get_field(env->mcounteren, COUNTEREN_CY)) {
>>> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -                }
>>> -                break;
>>> -            case CSR_TIMEH:
>>> -                if (!get_field(env->hcounteren, COUNTEREN_TM) &&
>>> -                    get_field(env->mcounteren, COUNTEREN_TM)) {
>>> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -                }
>>> -                break;
>>> -            case CSR_INSTRETH:
>>> -                if (!get_field(env->hcounteren, COUNTEREN_IR) &&
>>> -                    get_field(env->mcounteren, COUNTEREN_IR)) {
>>> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -                }
>>> -                break;
>>> -            case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
>>> -                if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
>>> -                    get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
>>> -                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> -                }
>>> -                break;
>>> -            }
>>> +    if (csrno <= CSR_HPMCOUNTER31 && csrno >= CSR_CYCLE) {
>>> +        field = 1 << (csrno - CSR_CYCLE);
>>> +    } else if (riscv_cpu_mxl(env) == MXL_RV32 && csrno <= CSR_HPMCOUNTER31H &&
>>> +               csrno >= CSR_CYCLEH) {
>>> +        field = 1 << (csrno - CSR_CYCLEH);
>>> +    }
>>> +
>>> +    if (env->priv < PRV_M && !get_field(env->mcounteren, field)) {
>>> +        return RISCV_EXCP_ILLEGAL_INST;
>>> +    }
>>> +
>>> +    if (riscv_cpu_virt_enabled(env) && !get_field(env->hcounteren, field)) {
>>> +        return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> +    }
>>> +
>>> +    if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
>>> +        !get_field(env->scounteren, field)) {
>>> +        if (riscv_cpu_virt_enabled(env)) {
>>> +            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>>> +        } else {
>>> +            return RISCV_EXCP_ILLEGAL_INST;
>>>           }
>>>       }
>>>   #endif
>>> --
>>> 2.17.1
>>>
>>>
>
>
diff mbox series

Patch

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6dbe9b541f..a4719cbf35 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -72,66 +72,34 @@  static RISCVException ctr(CPURISCVState *env, int csrno)
 #if !defined(CONFIG_USER_ONLY)
     CPUState *cs = env_cpu(env);
     RISCVCPU *cpu = RISCV_CPU(cs);
+    uint32_t field = 0;
 
     if (!cpu->cfg.ext_counters) {
         /* The Counters extensions is not enabled */
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
-    if (riscv_cpu_virt_enabled(env)) {
-        switch (csrno) {
-        case CSR_CYCLE:
-            if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-                get_field(env->mcounteren, COUNTEREN_CY)) {
-                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-            }
-            break;
-        case CSR_TIME:
-            if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-                get_field(env->mcounteren, COUNTEREN_TM)) {
-                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-            }
-            break;
-        case CSR_INSTRET:
-            if (!get_field(env->hcounteren, COUNTEREN_IR) &&
-                get_field(env->mcounteren, COUNTEREN_IR)) {
-                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-            }
-            break;
-        case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-            if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
-                get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
-                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-            }
-            break;
-        }
-        if (riscv_cpu_mxl(env) == MXL_RV32) {
-            switch (csrno) {
-            case CSR_CYCLEH:
-                if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-                    get_field(env->mcounteren, COUNTEREN_CY)) {
-                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-                }
-                break;
-            case CSR_TIMEH:
-                if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-                    get_field(env->mcounteren, COUNTEREN_TM)) {
-                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-                }
-                break;
-            case CSR_INSTRETH:
-                if (!get_field(env->hcounteren, COUNTEREN_IR) &&
-                    get_field(env->mcounteren, COUNTEREN_IR)) {
-                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-                }
-                break;
-            case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
-                if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
-                    get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
-                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-                }
-                break;
-            }
+    if (csrno <= CSR_HPMCOUNTER31 && csrno >= CSR_CYCLE) {
+        field = 1 << (csrno - CSR_CYCLE);
+    } else if (riscv_cpu_mxl(env) == MXL_RV32 && csrno <= CSR_HPMCOUNTER31H &&
+               csrno >= CSR_CYCLEH) {
+        field = 1 << (csrno - CSR_CYCLEH);
+    }
+
+    if (env->priv < PRV_M && !get_field(env->mcounteren, field)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    if (riscv_cpu_virt_enabled(env) && !get_field(env->hcounteren, field)) {
+        return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+    }
+
+    if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
+        !get_field(env->scounteren, field)) {
+        if (riscv_cpu_virt_enabled(env)) {
+            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+        } else {
+            return RISCV_EXCP_ILLEGAL_INST;
         }
     }
 #endif