qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alistair Francis <alistair23@gmail.com>
To: "Loïc Lefort" <loic@rivosinc.com>
Cc: qemu-devel@nongnu.org, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>,
	 Weiwei Li <liwei1518@gmail.com>,
	qemu-riscv@nongnu.org,  Palmer Dabbelt <palmer@dabbelt.com>,
	Alistair Francis <alistair.francis@wdc.com>,
	 Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Subject: Re: [PATCH v2 1/5] target/riscv: pmp: don't allow RLB to bypass rule privileges
Date: Fri, 4 Apr 2025 11:01:01 +1000	[thread overview]
Message-ID: <CAKmqyKMcNC061cMmumd-jW_AWPCnFHePxWEMxxX5FZAynGE-zg@mail.gmail.com> (raw)
In-Reply-To: <20250313193011.720075-2-loic@rivosinc.com>

On Fri, Mar 14, 2025 at 5:32 AM Loïc Lefort <loic@rivosinc.com> wrote:
>
> When Smepmp is supported, mseccfg.RLB allows bypassing locks when writing CSRs
> but should not affect interpretation of actual PMP rules.
>
> This is not the case with the current implementation where pmp_hart_has_privs
> calls pmp_is_locked which implements mseccfg.RLB bypass.
>
> This commit implements the correct behavior by removing mseccfg.RLB bypass from
> pmp_is_locked.
>
> RLB bypass when writing CSRs is implemented by adding a new pmp_is_readonly
> function that calls pmp_is_locked and check mseccfg.RLB. pmp_write_cfg and
> pmpaddr_csr_write are changed to use this new function.
>
> Signed-off-by: Loïc Lefort <loic@rivosinc.com>

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

Alistair

> ---
>  target/riscv/pmp.c | 43 +++++++++++++++++++++++--------------------
>  1 file changed, 23 insertions(+), 20 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index b0841d44f4..e1e5ca589e 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -45,11 +45,6 @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
>   */
>  static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
>  {
> -    /* mseccfg.RLB is set */
> -    if (MSECCFG_RLB_ISSET(env)) {
> -        return 0;
> -    }
> -
>      if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
>          return 1;
>      }
> @@ -62,6 +57,15 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
>      return 0;
>  }
>
> +/*
> + * Check whether a PMP is locked for writing or not.
> + * (i.e. has LOCK flag and mseccfg.RLB is unset)
> + */
> +static int pmp_is_readonly(CPURISCVState *env, uint32_t pmp_index)
> +{
> +    return pmp_is_locked(env, pmp_index) && !MSECCFG_RLB_ISSET(env);
> +}
> +
>  /*
>   * Count the number of active rules.
>   */
> @@ -90,39 +94,38 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
>  static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
>  {
>      if (pmp_index < MAX_RISCV_PMPS) {
> -        bool locked = true;
> +        bool readonly = true;
>
>          if (riscv_cpu_cfg(env)->ext_smepmp) {
>              /* mseccfg.RLB is set */
>              if (MSECCFG_RLB_ISSET(env)) {
> -                locked = false;
> +                readonly = false;
>              }
>
>              /* mseccfg.MML is not set */
> -            if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
> -                locked = false;
> +            if (!MSECCFG_MML_ISSET(env) && !pmp_is_readonly(env, pmp_index)) {
> +                readonly = false;
>              }
>
>              /* mseccfg.MML is set */
>              if (MSECCFG_MML_ISSET(env)) {
>                  /* not adding execute bit */
>                  if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
> -                    locked = false;
> +                    readonly = false;
>                  }
>                  /* shared region and not adding X bit */
>                  if ((val & PMP_LOCK) != PMP_LOCK &&
>                      (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
> -                    locked = false;
> +                    readonly = false;
>                  }
>              }
>          } else {
> -            if (!pmp_is_locked(env, pmp_index)) {
> -                locked = false;
> -            }
> +            readonly = pmp_is_readonly(env, pmp_index);
>          }
>
> -        if (locked) {
> -            qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
> +        if (readonly) {
> +            qemu_log_mask(LOG_GUEST_ERROR,
> +                          "ignoring pmpcfg write - read only\n");
>          } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
>              /* If !mseccfg.MML then ignore writes with encoding RW=01 */
>              if ((val & PMP_WRITE) && !(val & PMP_READ) &&
> @@ -524,14 +527,14 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
>              uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
>              is_next_cfg_tor = PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg);
>
> -            if (pmp_is_locked(env, addr_index + 1) && is_next_cfg_tor) {
> +            if (pmp_is_readonly(env, addr_index + 1) && is_next_cfg_tor) {
>                  qemu_log_mask(LOG_GUEST_ERROR,
> -                              "ignoring pmpaddr write - pmpcfg + 1 locked\n");
> +                              "ignoring pmpaddr write - pmpcfg+1 read only\n");
>                  return;
>              }
>          }
>
> -        if (!pmp_is_locked(env, addr_index)) {
> +        if (!pmp_is_readonly(env, addr_index)) {
>              if (env->pmp_state.pmp[addr_index].addr_reg != val) {
>                  env->pmp_state.pmp[addr_index].addr_reg = val;
>                  pmp_update_rule_addr(env, addr_index);
> @@ -542,7 +545,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
>              }
>          } else {
>              qemu_log_mask(LOG_GUEST_ERROR,
> -                          "ignoring pmpaddr write - locked\n");
> +                          "ignoring pmpaddr write - read only\n");
>          }
>      } else {
>          qemu_log_mask(LOG_GUEST_ERROR,
> --
> 2.47.2
>
>


  parent reply	other threads:[~2025-04-04  1:02 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-13 19:30 [PATCH v2 0/5] target/riscv: Smepmp fixes to match specification Loïc Lefort
2025-03-13 19:30 ` [PATCH v2 1/5] target/riscv: pmp: don't allow RLB to bypass rule privileges Loïc Lefort
2025-03-27 17:30   ` Daniel Henrique Barboza
2025-03-29  8:33   ` LIU Zhiwei
2025-04-04  1:01   ` Alistair Francis [this message]
2025-03-13 19:30 ` [PATCH v2 2/5] target/riscv: pmp: move Smepmp operation conversion into a function Loïc Lefort
2025-03-29  8:53   ` LIU Zhiwei
2025-04-04  1:02   ` Alistair Francis
2025-03-13 19:30 ` [PATCH v2 3/5] target/riscv: pmp: fix checks on writes to pmpcfg in Smepmp MML mode Loïc Lefort
2025-03-29  9:01   ` LIU Zhiwei
2025-03-13 19:30 ` [PATCH v2 4/5] target/riscv: pmp: exit csr writes early if value was not changed Loïc Lefort
2025-03-29  9:03   ` LIU Zhiwei
2025-03-31  9:44     ` Loïc Lefort
2025-03-31 11:31       ` LIU Zhiwei
2025-04-04  1:05   ` Alistair Francis
2025-03-13 19:30 ` [PATCH v2 5/5] target/riscv: pmp: remove redundant check in pmp_is_locked Loïc Lefort
2025-03-29  9:29   ` LIU Zhiwei
2025-04-04  1:06   ` Alistair Francis
2025-03-27 16:47 ` [PATCH v2 0/5] target/riscv: Smepmp fixes to match specification Loïc Lefort
2025-04-04  1:23 ` Alistair Francis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKmqyKMcNC061cMmumd-jW_AWPCnFHePxWEMxxX5FZAynGE-zg@mail.gmail.com \
    --to=alistair23@gmail.com \
    --cc=alistair.francis@wdc.com \
    --cc=dbarboza@ventanamicro.com \
    --cc=liwei1518@gmail.com \
    --cc=loic@rivosinc.com \
    --cc=palmer@dabbelt.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=zhiwei_liu@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).