From: Abhigyan Kumar <[email protected]>

According to the RISC-V spec, a 64-bit system can have M-mode in 64-bit
with S-mode being 32-bit (SXL bits or mstatus[35:34] being 1). In this
case, read_sstatus should use SXL.

QEMU doesn't allow changing the SXL bits in mstatus in M-mode. This was
because of the missing MSTATUS64_SXL mask in write_mstatus. Now, both
the SXL field in mstatus can be safely modified in M-mode and
read_sstatus correctly uses SXL not MXL.

Fixes: b550f89457 ("target/riscv: Compute mstatus.sd on demand")
Signed-off-by: Abhigyan Kumar <[email protected]>
Reviewed-by: Daniel Henrique Barboza <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Alistair Francis <[email protected]>
(cherry picked from commit ebef6685a1a29b0b106b6ff3931ffc22c489e0ae)
Signed-off-by: Michael Tokarev <[email protected]>

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c41f23c0f96..4015f023d10 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2037,6 +2037,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
     }
 
     if (xl != MXL_RV32 || env->debugger) {
+        if ((val & MSTATUS64_SXL) != 0) {
+            mask |= MSTATUS64_SXL;
+            val = riscv_write_uxl(env, val, MSTATUS64_SXL);
+        }
+
         if ((val & MSTATUS64_UXL) != 0) {
             mask |= MSTATUS64_UXL;
             val = riscv_write_uxl(env, val, MSTATUS64_UXL);
@@ -3897,8 +3902,8 @@ static RISCVException read_sstatus(CPURISCVState *env, 
int csrno,
     if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
         mask |= SSTATUS_SDT;
     }
-    /* TODO: Use SXL not MXL. */
-    *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
+
+    *val = add_status_sd(riscv_cpu_sxl(env), env->mstatus & mask);
     return RISCV_EXCP_NONE;
 }
 
-- 
2.47.3


Reply via email to