From dcd028517749835a618bb1fe8dca32d82318e1c1 Mon Sep 17 00:00:00 2001 From: SeungJu Cheon Date: Thu, 25 Jun 2026 17:15:21 +0900 Subject: [PATCH] target/riscv: Apply UXL WARL handling to vsstatus write_mstatus() already handles the reserved UXL value by writing a legal value instead. Apply the same handling when writing vsstatus so that reserved UXL values follow the same WARL behavior. Factor the common logic into a local helper riscv_write_uxl() and use it for both mstatus and vsstatus. Suggested-by: Daniel Henrique Barboza Fixes: f310df58bd2 ("target/riscv: Enable uxl field write") Signed-off-by: SeungJu Cheon Reviewed-by: Daniel Henrique Barboza Message-ID: <20260625081521.595683-1-suunj1331@gmail.com> Signed-off-by: Alistair Francis --- target/riscv/csr.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 7fb0ad5bc1..7168a4dc12 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -2021,6 +2021,20 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp, return val; } +static uint64_t riscv_write_uxl(CPURISCVState *env, uint64_t val, + uint64_t field) +{ + RISCVMXL xl = riscv_cpu_mxl(env); + uint64_t uxl = get_field(val, field); + + if (uxl == MXL_RV128) { + uxl = xl == MXL_RV128 ? MXL_RV64 : xl; + val = set_field(val, field, uxl); + } + + return val; +} + static RISCVException write_mstatus(CPURISCVState *env, int csrno, target_ulong val, uintptr_t ra) { @@ -2067,17 +2081,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, if (xl != MXL_RV32 || env->debugger) { if ((val & MSTATUS64_UXL) != 0) { - uint64_t uxl = val & MSTATUS64_UXL >> 32; mask |= MSTATUS64_UXL; - - /* - * uxl = 3 is reserved so write the current xl instead. - * In case xl = MXL_RV128 (3) write MXL_RV64. - */ - if (uxl == 3) { - uxl = xl == MXL_RV128 ? MXL_RV64 : xl; - val = deposit64(val, 32, 2, uxl); - } + val = riscv_write_uxl(env, val, MSTATUS64_UXL); } } @@ -5239,6 +5244,8 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno, uint64_t mask = (target_ulong)-1; if ((val & VSSTATUS64_UXL) == 0) { mask &= ~VSSTATUS64_UXL; + } else { + val = riscv_write_uxl(env, val, VSSTATUS64_UXL); } if ((env->henvcfg & HENVCFG_DTE)) { if ((val & SSTATUS_SDT) != 0) {