[PATCH 1/2] target/riscv: preserve RV32 henvcfgh on henvcfg writes

Bruno Sa posted 2 patches 2 days, 1 hour ago
[PATCH 1/2] target/riscv: preserve RV32 henvcfgh on henvcfg writes
Posted by Bruno Sa 2 days, 1 hour ago
On RV32, STCE/ADUE/PBMTE/DTE are implemented in henvcfgh. A write to
henvcfg should therefore only update the low 32 bits of env->henvcfg.

The current write_henvcfg() path overwrites env->henvcfg with the
low-half value and clears any bits previously written via henvcfgh.

Preserve the upper 32 bits on RV32 henvcfg writes and keep the existing
RV64 behaviour unchanged.

Signed-off-by: Bruno Sa <bruno.vilaca.sa@gmail.com>
---
 target/riscv/csr.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 7948188356..d322bdbd47 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3326,7 +3326,15 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
         }
     }
 
-    env->henvcfg = val & mask;
+    if (riscv_cpu_mxl(env) == MXL_RV32) {
+        /*
+         * RV32 stores STCE/ADUE/PBMTE/DTE in henvcfgh, so a low-half henvcfg
+         * write must not clobber the upper 32 bits.
+         */
+        env->henvcfg = (env->henvcfg & ~0xFFFFFFFFULL) | (val & mask);
+    } else {
+        env->henvcfg = val & mask;
+    }
     if ((env->henvcfg & HENVCFG_DTE) == 0) {
         env->vsstatus &= ~MSTATUS_SDT;
     }
-- 
2.43.0
Re: [PATCH 1/2] target/riscv: preserve RV32 henvcfgh on henvcfg writes
Posted by Alistair Francis 1 day, 16 hours ago
On Fri, Apr 10, 2026 at 3:27 AM Bruno Sa <bruno.vilaca.sa@gmail.com> wrote:
>
> On RV32, STCE/ADUE/PBMTE/DTE are implemented in henvcfgh. A write to
> henvcfg should therefore only update the low 32 bits of env->henvcfg.
>
> The current write_henvcfg() path overwrites env->henvcfg with the
> low-half value and clears any bits previously written via henvcfgh.
>
> Preserve the upper 32 bits on RV32 henvcfg writes and keep the existing
> RV64 behaviour unchanged.
>
> Signed-off-by: Bruno Sa <bruno.vilaca.sa@gmail.com>

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

Alistair

> ---
>  target/riscv/csr.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 7948188356..d322bdbd47 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3326,7 +3326,15 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
>          }
>      }
>
> -    env->henvcfg = val & mask;
> +    if (riscv_cpu_mxl(env) == MXL_RV32) {
> +        /*
> +         * RV32 stores STCE/ADUE/PBMTE/DTE in henvcfgh, so a low-half henvcfg
> +         * write must not clobber the upper 32 bits.
> +         */
> +        env->henvcfg = (env->henvcfg & ~0xFFFFFFFFULL) | (val & mask);
> +    } else {
> +        env->henvcfg = val & mask;
> +    }
>      if ((env->henvcfg & HENVCFG_DTE) == 0) {
>          env->vsstatus &= ~MSTATUS_SDT;
>      }
> --
> 2.43.0
>
>