By the priv spec the value "3" is marked as 'Reserved' for
mstatus.UXL. write_mstatus() rejects this value, but
write_vsstatus() does not, allowing the reserved value to be
written and read back unchanged.
Handle a vsstatus.UXL = 3 write by writing the current 'xl'
instead.
Fixes: f310df58bd2 ("target/riscv: Enable uxl field write")
Signed-off-by: SeungJu Cheon <[email protected]>
---
target/riscv/csr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index dd9726fcf4..4c1da61824 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -5226,7 +5226,15 @@ static RISCVException write_vsstatus(CPURISCVState *env,
int csrno,
uint64_t mask = (target_ulong)-1;
if ((val & VSSTATUS64_UXL) == 0) {
mask &= ~VSSTATUS64_UXL;
+ } else {
+ uint64_t uxl = (val & VSSTATUS64_UXL) >> 32;
+ if (uxl == 3) {
+ int xl = riscv_cpu_mxl(env);
+ val = deposit64(val, 32, 2,
+ xl == MXL_RV128 ? MXL_RV64 : xl);
+ }
}
+
if ((env->henvcfg & HENVCFG_DTE)) {
if ((val & SSTATUS_SDT) != 0) {
val &= ~SSTATUS_SIE;
--
2.52.0