Re: [PATCH v2] target/riscv: allow menvcfg/henvcfg LPE and SSE bits on RV32

Alistair <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
On Sun, 2026-07-26 at 11:05 +0300, A-Shehab wrote:
> The Zicfilp landing-pad enable (LPE, bit 2) and Zicfiss shadow-stack
> enable (SSE, bit 3) controls live in the low 32 bits of menvcfg and
> henvcfg, and the CFI specification defines them for both RV32 and
> RV64.
> 
> QEMU only adds MENVCFG_LPE/MENVCFG_SSE (and the henvcfg equivalents)
> to
> the writable mask inside the "riscv_cpu_mxl(env) == MXL_RV64" block,
> so
> on RV32 these bits are silently dropped and the features cannot be
> enabled. This is inconsistent with write_senvcfg(), which already
> handles SENVCFG_LPE/SENVCFG_SSE regardless of MXLEN.
> 
> Hoist the LPE/SSE mask handling out of the RV64-only block in
> write_menvcfg() and write_henvcfg() so the bits become writable on
> RV32
> as well. The upper-half writers (write_menvcfgh/write_henvcfgh) are
> unaffected because these bits reside in the low 32 bits.
> 
> Reproducible on qemu-system-riscv32 -cpu
> rv32,zicfilp=true,zicfiss=true:
> an M-mode write of menvcfg.{LPE,SSE} reads back as zero, while the
> same
> program on rv64 keeps the bits set.
> 
> Fixes: 4923f672e3d7 ("target/riscv: Introduce elp state and enabling
> controls for zicfilp")
> Fixes: 8205bc127a83 ("target/riscv: introduce ssp and enabling
> controls for zicfiss")
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/4045
> Signed-off-by: A-Shehab <[email protected]>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
> v2: Rebase on current master; the file moved from target/riscv/csr.c
> to
>     target/riscv/tcg/csr.c (noted by Daniel Henrique Barboza). No
>     functional change.
> 
> v1:
> https://lore.kernel.org/qemu-devel/[email protected]/
> 
>  target/riscv/tcg/csr.c | 45 +++++++++++++++++++++++++---------------
> --
>  1 file changed, 27 insertions(+), 18 deletions(-)
> 
> diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> index 36f2004bc5..0182e4c408 100644
> --- a/target/riscv/tcg/csr.c
> +++ b/target/riscv/tcg/csr.c
> @@ -3216,6 +3216,19 @@ static RISCVException
> write_menvcfg(CPURISCVState *env, int csrno,
>                      MENVCFG_CBZE;
>      bool stce_changed = false;
>  
> +    /*
> +     * menvcfg.LPE (Zicfilp) and menvcfg.SSE (Zicfiss) reside in the
> low
> +     * 32 bits and are defined for both RV32 and RV64, so they must
> be
> +     * writable regardless of MXLEN.
> +     */
> +    if (cfg->ext_zicfilp) {
> +        mask |= MENVCFG_LPE;
> +    }
> +
> +    if (cfg->ext_zicfiss) {
> +        mask |= MENVCFG_SSE;
> +    }
> +
>      if (riscv_cpu_mxl(env) == MXL_RV64) {
>          mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
>                  (cfg->ext_sstc ? MENVCFG_STCE : 0) |
> @@ -3223,14 +3236,6 @@ static RISCVException
> write_menvcfg(CPURISCVState *env, int csrno,
>                  (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
>                  (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
>  
> -        if (env_archcpu(env)->cfg.ext_zicfilp) {
> -            mask |= MENVCFG_LPE;
> -        }
> -
> -        if (env_archcpu(env)->cfg.ext_zicfiss) {
> -            mask |= MENVCFG_SSE;
> -        }
> -
>          /* Update PMM field only if the value is valid according to
> Zjpm v1.0 */
>          if (env_archcpu(env)->cfg.ext_smnpm &&
>              get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
> @@ -3378,20 +3383,24 @@ static RISCVException
> write_henvcfg(CPURISCVState *env, int csrno,
>          return ret;
>      }
>  
> +    /*
> +     * henvcfg.LPE (Zicfilp) and henvcfg.SSE (Zicfiss) reside in the
> low
> +     * 32 bits and are defined for both RV32 and RV64, so they must
> be
> +     * writable regardless of MXLEN.
> +     */
> +    if (cfg->ext_zicfilp) {
> +        mask |= HENVCFG_LPE;
> +    }
> +
> +    /* H can light up SSE for VS only if HS had it from menvcfg */
> +    if (cfg->ext_zicfiss && get_field(env->menvcfg, MENVCFG_SSE)) {
> +        mask |= HENVCFG_SSE;
> +    }
> +
>      if (riscv_cpu_mxl(env) == MXL_RV64) {
>          mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
> HENVCFG_ADUE |
>                                  HENVCFG_DTE);
>  
> -        if (env_archcpu(env)->cfg.ext_zicfilp) {
> -            mask |= HENVCFG_LPE;
> -        }
> -
> -        /* H can light up SSE for VS only if HS had it from menvcfg
> */
> -        if (env_archcpu(env)->cfg.ext_zicfiss &&
> -            get_field(env->menvcfg, MENVCFG_SSE)) {
> -            mask |= HENVCFG_SSE;
> -        }
> -
>          /* Update PMM field only if the value is valid according to
> Zjpm v1.0 */
>          if (env_archcpu(env)->cfg.ext_ssnpm &&
>              get_field(val, HENVCFG_PMM) != PMM_FIELD_RESERVED) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.