@samitouri / QOSamiQemu / commits / d161bfb075

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 <bruno.vilaca.sa@gmail.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260409155344.2849233-2-bruno.vilaca.sa@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Bruno Sa committed Apr 9, 2026 at 16:53 UTC d161bfb075d5e51f1358e02e286de6891ebd0c4a
1 file changed +9 -1
target/riscv/csr.c
+9 -1
@@ -3353,7 +3353,15 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
3353 }
3354 }
3355
3356 - env->henvcfg = val & mask;
3356 + if (riscv_cpu_mxl(env) == MXL_RV32) {
3357 + /*
3358 + * RV32 stores STCE/ADUE/PBMTE/DTE in henvcfgh, so a low-half henvcfg
3359 + * write must not clobber the upper 32 bits.
3360 + */
3361 + env->henvcfg = (env->henvcfg & ~0xFFFFFFFFULL) | (val & mask);
3362 + } else {
3363 + env->henvcfg = val & mask;
3364 + }
3365 if ((env->henvcfg & HENVCFG_DTE) == 0) {
3366 env->vsstatus &= ~MSTATUS_SDT;
3367 }