summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhigyan Kumar <314abh@gmail.com>2026-07-23 19:52:54 +0530
committerMichael Tokarev <mjt@tls.msk.ru>2026-08-24 21:33:02 +0300
commit44e88d1a1efeabb9ed2d7155f7d2f6eeed523596 (patch)
treee4f0ef9ab93d790d5f7ded63ee482911572ae5ae
parentef002da49447a5a9cab96a8afe036ae0c74e23e5 (diff)
downloadqemu-44e88d1a1efeabb9ed2d7155f7d2f6eeed523596.tar.gz
qemu-44e88d1a1efeabb9ed2d7155f7d2f6eeed523596.zip
target/riscv: use SXL instead of MXL for read_sstatus
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 <314abh@gmail.com> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Message-ID: <20260723142254.1683113-1-314abh@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> (cherry picked from commit ebef6685a1a29b0b106b6ff3931ffc22c489e0ae) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r--target/riscv/tcg/csr.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
index 36f2004bc5..a90449b87f 100644
--- a/target/riscv/tcg/csr.c
+++ b/target/riscv/tcg/csr.c
@@ -2067,6 +2067,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);
@@ -4014,8 +4019,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;
}