@samitouri / QOSamiQemu / commits / bd1ee9ab3c

target/riscv: allow menvcfg/henvcfg LPE and SSE bits on RV32

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 <ahshehab24@gmail.com> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Message-ID: <20260726080537.13913-1-ahshehab24@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

A-Shehab committed Jul 26, 2026 at 11:05 UTC bd1ee9ab3c39f269d8bea8acf83ea833a69a6e10
1 file changed +27 -18
target/riscv/tcg/csr.c
+27 -18
@@ -3221,6 +3221,19 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
3221 MENVCFG_CBZE;
3222 bool stce_changed = false;
3223
3224 + /*
3225 + * menvcfg.LPE (Zicfilp) and menvcfg.SSE (Zicfiss) reside in the low
3226 + * 32 bits and are defined for both RV32 and RV64, so they must be
3227 + * writable regardless of MXLEN.
3228 + */
3229 + if (cfg->ext_zicfilp) {
3230 + mask |= MENVCFG_LPE;
3231 + }
3232 +
3233 + if (cfg->ext_zicfiss) {
3234 + mask |= MENVCFG_SSE;
3235 + }
3236 +
3237 if (riscv_cpu_mxl(env) == MXL_RV64) {
3238 mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
3239 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
@@ -3228,14 +3241,6 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
3241 (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
3242 (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
3243
3231 - if (env_archcpu(env)->cfg.ext_zicfilp) {
3232 - mask |= MENVCFG_LPE;
3233 - }
3234 -
3235 - if (env_archcpu(env)->cfg.ext_zicfiss) {
3236 - mask |= MENVCFG_SSE;
3237 - }
3238 -
3244 /* Update PMM field only if the value is valid according to Zjpm v1.0 */
3245 if (env_archcpu(env)->cfg.ext_smnpm &&
3246 get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
@@ -3383,20 +3388,24 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
3388 return ret;
3389 }
3390
3391 + /*
3392 + * henvcfg.LPE (Zicfilp) and henvcfg.SSE (Zicfiss) reside in the low
3393 + * 32 bits and are defined for both RV32 and RV64, so they must be
3394 + * writable regardless of MXLEN.
3395 + */
3396 + if (cfg->ext_zicfilp) {
3397 + mask |= HENVCFG_LPE;
3398 + }
3399 +
3400 + /* H can light up SSE for VS only if HS had it from menvcfg */
3401 + if (cfg->ext_zicfiss && get_field(env->menvcfg, MENVCFG_SSE)) {
3402 + mask |= HENVCFG_SSE;
3403 + }
3404 +
3405 if (riscv_cpu_mxl(env) == MXL_RV64) {
3406 mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3407 HENVCFG_DTE);
3408
3390 - if (env_archcpu(env)->cfg.ext_zicfilp) {
3391 - mask |= HENVCFG_LPE;
3392 - }
3393 -
3394 - /* H can light up SSE for VS only if HS had it from menvcfg */
3395 - if (env_archcpu(env)->cfg.ext_zicfiss &&
3396 - get_field(env->menvcfg, MENVCFG_SSE)) {
3397 - mask |= HENVCFG_SSE;
3398 - }
3399 -
3409 /* Update PMM field only if the value is valid according to Zjpm v1.0 */
3410 if (env_archcpu(env)->cfg.ext_ssnpm &&
3411 get_field(val, HENVCFG_PMM) != PMM_FIELD_RESERVED) {