target/riscv: reserved bit 63 of sstateen1-3 is writable on RV64

Host environment

  • Operating system: Rocky Linux 9 (x86_64)
  • QEMU version: 11.1.2; the code is unchanged on master

Emulated/Virtualized environment

  • Operating system: bare metal
  • Machine type: virt, -cpu max (RV64)

Description of problem

On RV64, bit 63 of sstateen1, sstateen2 and sstateen3 becomes writable whenever bit 63 of the matching mstateenN is set. sstateen1-3 have no defined bits, so they must always read 0.

write_sstateen_1_3() in target/riscv/tcg/csr.c passes SMSTATEEN_STATEEN (bit 63) as the write mask:

return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);

Bit 63 is the SE control bit only in mstateenN/hstateenN, where it gates access to sstateenN. The sstateen CSRs are 32 bits wide in practice: smstateen.adoc says no sstateen high-half CSRs exist for RV32 "because it is expected the upper 32 bits of these registers will always be zeros", and "all reserved bits not yet given a defined meaning are also read-only zeros" (norm:stateen_reserved_roz). The mask appears to have been copied from the mstateen/hstateen case.

Steps to reproduce

  1. Unpack the attached tarball and run ./run.sh (it runs qemu-system-riscv64 -nographic -semihosting -machine virt -cpu max -bios sstateen1-bit63.elf).
  2. In M-mode, the test sets bit 63 of mstateen1-3, writes all ones to sstateen1-3, and reads them back.
  3. QEMU prints FAIL: sstateen1-3 bit 63 is writable (expected read-only zero). Expected: PASS: sstateen1-3 read 0.

2026-10-19-qemu-sstateen123-bit63.tar.gz

Additional information

Suggested fix: use a write mask of 0 for sstateen1-3 until bits are defined there. Found by the RISC-V architectural tests (riscv-arch-test Smstateen/Ssstateen, https://github.com/riscv/riscv-arch-test/pull/2874).