From: Bruno Sa Date: Thu, 9 Apr 2026 15:53:42 +0000 (+0100) Subject: target/riscv: preserve RV32 henvcfgh on henvcfg writes X-Git-Tag: v11.1.0-rc0~149^2~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d161bfb075d5e51f1358e02e286de6891ebd0c4a;p=thirdparty%2Fqemu.git target/riscv: preserve RV32 henvcfgh on henvcfg writes 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 Reviewed-by: Alistair Francis Message-ID: <20260409155344.2849233-2-bruno.vilaca.sa@gmail.com> Signed-off-by: Alistair Francis --- diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a75281539bd..cfd076b3681 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3353,7 +3353,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; }