CSRRS/CSRRC to read-only time accepted when rs1 != x0 holds zero
Affected revision
RVVM staging branch, verified against the current staging snapshot on
2026-09-06; x86-64 host, RV64 Linux guest user-mode execution.
Summary
A minimal static guest probe installs a SIGILL handler and executes three forms against the read-only time CSR:
csrrs rd, time, x0 (canonical read-only access, legal)
csrrs rd, time, t0 with t0 = 0 (write-form access, illegal)
csrrc rd, time, t0 with t0 = 0 (write-form access, illegal) On native RV64 Linux and qemu-riscv64:
csrrs_x0_trap=0
csrrs_x0_out=<time value>
csrrs_zero_reg_trap=1
csrrc_zero_reg_trap=1
sigill_seen=1
Only the canonical rs1 = x0 read form is accepted; the two forms with rs1 = t0 (even though t0 contains zero) trap. On RVVM userland, all three forms are accepted and return the timer value. RVVM appears to use "source value == 0" as a proxy for "source register is x0", which is not correct: write-detection must be based on the register number, not the runtime value.
Why this is a real defect
The native reference is stable and reproducible; QEMU matches the same semantic shape; the witness is minimal; and this is a CSR decode / write-detection bug rather than a generic accessibility mismatch.
Existing reports
I searched the public issue tracker and found no existing report for this defect.
CSRRS/CSRRCto read-onlytimeaccepted whenrs1 != x0holds zeroAffected revision
RVVM
stagingbranch, verified against the current staging snapshot on2026-09-06; x86-64 host, RV64 Linux guest user-mode execution.
Summary
A minimal static guest probe installs a
SIGILLhandler and executes three forms against the read-onlytimeCSR:csrrs rd, time, x0(canonical read-only access, legal)csrrs rd, time, t0witht0 = 0(write-form access, illegal)csrrc rd, time, t0witht0 = 0(write-form access, illegal) On native RV64 Linux andqemu-riscv64:Only the canonical
rs1 = x0read form is accepted; the two forms withrs1 = t0(even thought0contains zero) trap. On RVVM userland, all three forms are accepted and return the timer value. RVVM appears to use "source value == 0" as a proxy for "source register is x0", which is not correct: write-detection must be based on the register number, not the runtime value.Why this is a real defect
The native reference is stable and reproducible; QEMU matches the same semantic shape; the witness is minimal; and this is a CSR decode / write-detection bug rather than a generic accessibility mismatch.
Existing reports
I searched the public issue tracker and found no existing report for this defect.