target/riscv/csr.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-)
Normally, riscv_csrrw_check is called when executing Zicsr instructions.
And we can only do access control for existed CSRs. So the priority of
CSR related check, from highest to lowest, should be as follows:
1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
INSTRUCTION_FAULT if not allowed
The predicates contain parts of function of both 2) and 3), So they need
to be placed in the middle of riscv_csrrw_check
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0fb042b2fd..d81f466c80 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
int read_only = get_field(csrno, 0xC00) == 3;
int csr_min_priv = csr_ops[csrno].min_priv_ver;
+
+ /* ensure the CSR extension is enabled. */
+ if (!cpu->cfg.ext_icsr) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ if (env->priv_ver < csr_min_priv) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ /* check predicate */
+ if (!csr_ops[csrno].predicate) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ if (write_mask && read_only) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ RISCVException ret = csr_ops[csrno].predicate(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
#if !defined(CONFIG_USER_ONLY)
int csr_priv, effective_priv = env->priv;
@@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
return RISCV_EXCP_ILLEGAL_INST;
}
#endif
- if (write_mask && read_only) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- /* ensure the CSR extension is enabled. */
- if (!cpu->cfg.ext_icsr) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- /* check predicate */
- if (!csr_ops[csrno].predicate) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- if (env->priv_ver < csr_min_priv) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- return csr_ops[csrno].predicate(env, csrno);
+ return RISCV_EXCP_NONE;
}
static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
--
2.17.1
On Wed, Aug 3, 2022 at 10:56 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> Normally, riscv_csrrw_check is called when executing Zicsr instructions.
> And we can only do access control for existed CSRs. So the priority of
> CSR related check, from highest to lowest, should be as follows:
> 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
> 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
> 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
> INSTRUCTION_FAULT if not allowed
>
> The predicates contain parts of function of both 2) and 3), So they need
> to be placed in the middle of riscv_csrrw_check
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
> 1 file changed, 25 insertions(+), 19 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 0fb042b2fd..d81f466c80 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> int read_only = get_field(csrno, 0xC00) == 3;
> int csr_min_priv = csr_ops[csrno].min_priv_ver;
> +
> + /* ensure the CSR extension is enabled. */
> + if (!cpu->cfg.ext_icsr) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (env->priv_ver < csr_min_priv) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + /* check predicate */
> + if (!csr_ops[csrno].predicate) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (write_mask && read_only) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + RISCVException ret = csr_ops[csrno].predicate(env, csrno);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> +
> #if !defined(CONFIG_USER_ONLY)
> int csr_priv, effective_priv = env->priv;
>
> @@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> return RISCV_EXCP_ILLEGAL_INST;
> }
> #endif
> - if (write_mask && read_only) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* ensure the CSR extension is enabled. */
> - if (!cpu->cfg.ext_icsr) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* check predicate */
> - if (!csr_ops[csrno].predicate) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - if (env->priv_ver < csr_min_priv) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - return csr_ops[csrno].predicate(env, csrno);
> + return RISCV_EXCP_NONE;
> }
>
> static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
> --
> 2.17.1
>
>
On Wed, Aug 3, 2022 at 10:56 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> Normally, riscv_csrrw_check is called when executing Zicsr instructions.
> And we can only do access control for existed CSRs. So the priority of
> CSR related check, from highest to lowest, should be as follows:
> 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
> 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
> 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
> INSTRUCTION_FAULT if not allowed
>
> The predicates contain parts of function of both 2) and 3), So they need
> to be placed in the middle of riscv_csrrw_check
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
> 1 file changed, 25 insertions(+), 19 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 0fb042b2fd..d81f466c80 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> int read_only = get_field(csrno, 0xC00) == 3;
> int csr_min_priv = csr_ops[csrno].min_priv_ver;
> +
> + /* ensure the CSR extension is enabled. */
> + if (!cpu->cfg.ext_icsr) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (env->priv_ver < csr_min_priv) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + /* check predicate */
> + if (!csr_ops[csrno].predicate) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (write_mask && read_only) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + RISCVException ret = csr_ops[csrno].predicate(env, csrno);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> +
> #if !defined(CONFIG_USER_ONLY)
> int csr_priv, effective_priv = env->priv;
>
> @@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> return RISCV_EXCP_ILLEGAL_INST;
> }
> #endif
> - if (write_mask && read_only) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* ensure the CSR extension is enabled. */
> - if (!cpu->cfg.ext_icsr) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* check predicate */
> - if (!csr_ops[csrno].predicate) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - if (env->priv_ver < csr_min_priv) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - return csr_ops[csrno].predicate(env, csrno);
> + return RISCV_EXCP_NONE;
> }
>
> static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
> --
> 2.17.1
>
>
On Wed, Aug 3, 2022 at 6:16 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> Normally, riscv_csrrw_check is called when executing Zicsr instructions.
> And we can only do access control for existed CSRs. So the priority of
> CSR related check, from highest to lowest, should be as follows:
> 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
> 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
> 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
> INSTRUCTION_FAULT if not allowed
>
> The predicates contain parts of function of both 2) and 3), So they need
> to be placed in the middle of riscv_csrrw_check
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> ---
> target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
> 1 file changed, 25 insertions(+), 19 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 0fb042b2fd..d81f466c80 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> int read_only = get_field(csrno, 0xC00) == 3;
> int csr_min_priv = csr_ops[csrno].min_priv_ver;
> +
> + /* ensure the CSR extension is enabled. */
> + if (!cpu->cfg.ext_icsr) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (env->priv_ver < csr_min_priv) {
> + return RISCV_EXCP_ILLEGAL_INST;
This line breaks nested virtualization because for nested virtualization
to work, the guest hypervisor accessing h<xyz> and vs<xyz> CSRs from
VS-mode should result in a virtual instruction trap not illegal
instruction trap.
Regards,
Anup
> + }
> +
> + /* check predicate */
> + if (!csr_ops[csrno].predicate) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + if (write_mask && read_only) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + RISCVException ret = csr_ops[csrno].predicate(env, csrno);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> +
> #if !defined(CONFIG_USER_ONLY)
> int csr_priv, effective_priv = env->priv;
>
> @@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> return RISCV_EXCP_ILLEGAL_INST;
> }
> #endif
> - if (write_mask && read_only) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* ensure the CSR extension is enabled. */
> - if (!cpu->cfg.ext_icsr) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - /* check predicate */
> - if (!csr_ops[csrno].predicate) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - if (env->priv_ver < csr_min_priv) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - }
> -
> - return csr_ops[csrno].predicate(env, csrno);
> + return RISCV_EXCP_NONE;
> }
>
> static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
> --
> 2.17.1
>
>
在 2022/8/4 上午11:38, Anup Patel 写道:
> On Wed, Aug 3, 2022 at 6:16 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>> Normally, riscv_csrrw_check is called when executing Zicsr instructions.
>> And we can only do access control for existed CSRs. So the priority of
>> CSR related check, from highest to lowest, should be as follows:
>> 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
>> 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
>> 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
>> INSTRUCTION_FAULT if not allowed
>>
>> The predicates contain parts of function of both 2) and 3), So they need
>> to be placed in the middle of riscv_csrrw_check
>>
>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> ---
>> target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
>> 1 file changed, 25 insertions(+), 19 deletions(-)
>>
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index 0fb042b2fd..d81f466c80 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
>> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
>> int read_only = get_field(csrno, 0xC00) == 3;
>> int csr_min_priv = csr_ops[csrno].min_priv_ver;
>> +
>> + /* ensure the CSR extension is enabled. */
>> + if (!cpu->cfg.ext_icsr) {
>> + return RISCV_EXCP_ILLEGAL_INST;
>> + }
>> +
>> + if (env->priv_ver < csr_min_priv) {
>> + return RISCV_EXCP_ILLEGAL_INST;
> This line breaks nested virtualization because for nested virtualization
> to work, the guest hypervisor accessing h<xyz> and vs<xyz> CSRs from
> VS-mode should result in a virtual instruction trap not illegal
> instruction trap.
>
> Regards,
> Anup
Do you mean "if (env->priv_ver < csr_min_priv)" ?
If so, I think illegal instruction trap is better, since the csr is not
implemented(or existed) when
env->priv_ver < csr_min_priv and virtual instruction trap is only raised
for implemented csr access.
Regards,
Weiwei Li
>> + }
>> +
>> + /* check predicate */
>> + if (!csr_ops[csrno].predicate) {
>> + return RISCV_EXCP_ILLEGAL_INST;
>> + }
>> +
>> + if (write_mask && read_only) {
>> + return RISCV_EXCP_ILLEGAL_INST;
>> + }
>> +
>> + RISCVException ret = csr_ops[csrno].predicate(env, csrno);
>> + if (ret != RISCV_EXCP_NONE) {
>> + return ret;
>> + }
>> +
>> #if !defined(CONFIG_USER_ONLY)
>> int csr_priv, effective_priv = env->priv;
>>
>> @@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
>> return RISCV_EXCP_ILLEGAL_INST;
>> }
>> #endif
>> - if (write_mask && read_only) {
>> - return RISCV_EXCP_ILLEGAL_INST;
>> - }
>> -
>> - /* ensure the CSR extension is enabled. */
>> - if (!cpu->cfg.ext_icsr) {
>> - return RISCV_EXCP_ILLEGAL_INST;
>> - }
>> -
>> - /* check predicate */
>> - if (!csr_ops[csrno].predicate) {
>> - return RISCV_EXCP_ILLEGAL_INST;
>> - }
>> -
>> - if (env->priv_ver < csr_min_priv) {
>> - return RISCV_EXCP_ILLEGAL_INST;
>> - }
>> -
>> - return csr_ops[csrno].predicate(env, csrno);
>> + return RISCV_EXCP_NONE;
>> }
>>
>> static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
>> --
>> 2.17.1
>>
>>
On Thu, Aug 4, 2022 at 5:59 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
>
> 在 2022/8/4 上午11:38, Anup Patel 写道:
> > On Wed, Aug 3, 2022 at 6:16 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
> >> Normally, riscv_csrrw_check is called when executing Zicsr instructions.
> >> And we can only do access control for existed CSRs. So the priority of
> >> CSR related check, from highest to lowest, should be as follows:
> >> 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
> >> 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
> >> 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
> >> INSTRUCTION_FAULT if not allowed
> >>
> >> The predicates contain parts of function of both 2) and 3), So they need
> >> to be placed in the middle of riscv_csrrw_check
> >>
> >> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> >> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> >> ---
> >> target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
> >> 1 file changed, 25 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> >> index 0fb042b2fd..d81f466c80 100644
> >> --- a/target/riscv/csr.c
> >> +++ b/target/riscv/csr.c
> >> @@ -3270,6 +3270,30 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> >> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> >> int read_only = get_field(csrno, 0xC00) == 3;
> >> int csr_min_priv = csr_ops[csrno].min_priv_ver;
> >> +
> >> + /* ensure the CSR extension is enabled. */
> >> + if (!cpu->cfg.ext_icsr) {
> >> + return RISCV_EXCP_ILLEGAL_INST;
> >> + }
> >> +
> >> + if (env->priv_ver < csr_min_priv) {
> >> + return RISCV_EXCP_ILLEGAL_INST;
> > This line breaks nested virtualization because for nested virtualization
> > to work, the guest hypervisor accessing h<xyz> and vs<xyz> CSRs from
> > VS-mode should result in a virtual instruction trap not illegal
> > instruction trap.
> >
> > Regards,
> > Anup
>
> Do you mean "if (env->priv_ver < csr_min_priv)" ?
I got confused with the csr_min_priv name. This variable holds
min priv spec verison and not the privilege level required for
the CSR.
No issues with the "if (env->priv_ver < csr_min_priv)" check.
Regards,
Anup
>
> If so, I think illegal instruction trap is better, since the csr is not
> implemented(or existed) when
>
> env->priv_ver < csr_min_priv and virtual instruction trap is only raised
> for implemented csr access.
>
> Regards,
>
> Weiwei Li
>
> >> + }
> >> +
> >> + /* check predicate */
> >> + if (!csr_ops[csrno].predicate) {
> >> + return RISCV_EXCP_ILLEGAL_INST;
> >> + }
> >> +
> >> + if (write_mask && read_only) {
> >> + return RISCV_EXCP_ILLEGAL_INST;
> >> + }
> >> +
> >> + RISCVException ret = csr_ops[csrno].predicate(env, csrno);
> >> + if (ret != RISCV_EXCP_NONE) {
> >> + return ret;
> >> + }
> >> +
> >> #if !defined(CONFIG_USER_ONLY)
> >> int csr_priv, effective_priv = env->priv;
> >>
> >> @@ -3290,25 +3314,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> >> return RISCV_EXCP_ILLEGAL_INST;
> >> }
> >> #endif
> >> - if (write_mask && read_only) {
> >> - return RISCV_EXCP_ILLEGAL_INST;
> >> - }
> >> -
> >> - /* ensure the CSR extension is enabled. */
> >> - if (!cpu->cfg.ext_icsr) {
> >> - return RISCV_EXCP_ILLEGAL_INST;
> >> - }
> >> -
> >> - /* check predicate */
> >> - if (!csr_ops[csrno].predicate) {
> >> - return RISCV_EXCP_ILLEGAL_INST;
> >> - }
> >> -
> >> - if (env->priv_ver < csr_min_priv) {
> >> - return RISCV_EXCP_ILLEGAL_INST;
> >> - }
> >> -
> >> - return csr_ops[csrno].predicate(env, csrno);
> >> + return RISCV_EXCP_NONE;
> >> }
> >>
> >> static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
> >> --
> >> 2.17.1
> >>
> >>
>
© 2016 - 2026 Red Hat, Inc.