From 3dbe9ca0c511b0928a576e044e85834b23799c56 Mon Sep 17 00:00:00 2001 From: whensun Date: Mon, 6 Jul 2026 13:18:02 -0700 Subject: [PATCH] riscv: Mask unsupported menvcfg fields --- arch/riscv/cpu_bits.h | 19 +++++++++++++++++++ arch/riscv/op_helper.c | 28 ++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/arch/riscv/cpu_bits.h b/arch/riscv/cpu_bits.h index d1bc16d63..14541e18e 100644 --- a/arch/riscv/cpu_bits.h +++ b/arch/riscv/cpu_bits.h @@ -378,6 +378,25 @@ /* mintthresh bits */ #define MINTTHRESH_TH 0x000000ff +/* menvcfg fields required to be read-only zero because the related + * extensions are not implemented by tlib. */ +#define MENVCFG_STCE (1ULL << 63) /* Sstc */ +#define MENVCFG_PBMTE (1ULL << 62) /* Svpbmt */ +#define MENVCFG_CDE (1ULL << 60) /* Smcdeleg */ +#define MENVCFG_PMM (3ULL << 32) /* Smnpm */ +#define MENVCFG_CBZE (1ULL << 7) /* Zicboz */ +#define MENVCFG_CBCFE (1ULL << 6) /* Zicbom */ +#define MENVCFG_CBIE (3ULL << 4) /* Zicbom */ + +#define MENVCFG_RO_ZERO_MASK \ + (MENVCFG_STCE | \ + MENVCFG_PBMTE | \ + MENVCFG_CDE | \ + MENVCFG_PMM | \ + MENVCFG_CBZE | \ + MENVCFG_CBCFE | \ + MENVCFG_CBIE) + /* mseccfg bits */ #define MSECCFG_MML (1 << 0) #define MSECCFG_MMWP (1 << 1) diff --git a/arch/riscv/op_helper.c b/arch/riscv/op_helper.c index 833170c3c..99cb9f4c3 100644 --- a/arch/riscv/op_helper.c +++ b/arch/riscv/op_helper.c @@ -728,11 +728,21 @@ inline void csr_write_helper(CPUState *env, target_ulong val_to_write, target_ul env->vcsr = val_to_write; break; case CSR_MENVCFG: - env->menvcfg = val_to_write; + if(!riscv_has_ext(env, RISCV_FEATURE_RVU)) { + goto unhandled_csr_write; + } + env->menvcfg = val_to_write & ~((target_ulong)MENVCFG_RO_ZERO_MASK); break; case CSR_MENVCFGH: - env->menvcfgh = val_to_write; + #if defined(TARGET_RISCV32) + if(!riscv_has_ext(env, RISCV_FEATURE_RVU)) { + goto unhandled_csr_write; + } + env->menvcfgh = val_to_write & ~((target_ulong)(MENVCFG_RO_ZERO_MASK >> 32)); break; + #else + goto unhandled_csr_write; + #endif case CSR_MSECCFG: // Based on the SMEPMP documentation Version 1.0 if(!riscv_has_additional_ext(env, RISCV_FEATURE_SMEPMP)) { @@ -1009,9 +1019,19 @@ static inline target_ulong csr_read_helper(CPUState *env, target_ulong csrno) case CSR_MINTSTATUS: return env->mintstatus; case CSR_MENVCFG: - return env->menvcfg; + if(!riscv_has_ext(env, RISCV_FEATURE_RVU)) { + goto unhandled_csr_read; + } + return env->menvcfg & ~((target_ulong)MENVCFG_RO_ZERO_MASK); case CSR_MENVCFGH: - return env->menvcfgh; + #if defined(TARGET_RISCV32) + if(!riscv_has_ext(env, RISCV_FEATURE_RVU)) { + goto unhandled_csr_read; + } + return env->menvcfgh & ~((target_ulong)(MENVCFG_RO_ZERO_MASK >> 32)); + #else + goto unhandled_csr_read; + #endif case CSR_MSECCFG: if(!riscv_has_additional_ext(env, RISCV_FEATURE_SMEPMP)) { tlib_printf(LOG_LEVEL_ERROR, "CSR_MSECCFG can only be accessed when SMEPMP extension is enabled");