Describe the bug
After unlocking PMP and mret into S-mode, a second mret does not trap. NutShell still performs M-mode mret (updates mstatus and drops to U-mode).
# MPP=S, MPIE=1
mret # enter S-mode
# in S-mode:
mret # must be illegal; DUT still executes it
Expected behavior
RISC-V Privileged Spec, Trap-Return Instructions: mret is valid only in M-mode. Executing it at a lower privilege must raise an illegal-instruction exception.
- Expected: mcause=2, mtval=0x30200073
- Actual: no trap; privilege becomes U-mode
In CSR.scala, wen = (valid && func =/= CSROpType.jmp) and
csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen.
mret uses func=jmp, so wen=0 and the privilege check is skipped, while when (valid && isMret) still runs.
Environment
NutShell: 041f694
Describe the bug
After unlocking PMP and
mretinto S-mode, a secondmretdoes not trap. NutShell still performs M-modemret(updatesmstatusand drops to U-mode).Expected behavior
RISC-V Privileged Spec, Trap-Return Instructions: mret is valid only in M-mode. Executing it at a lower privilege must raise an illegal-instruction exception.
In CSR.scala, wen = (valid && func =/= CSROpType.jmp) and
csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen.
mret uses func=jmp, so wen=0 and the privilege check is skipped, while when (valid && isMret) still runs.
Environment
NutShell: 041f694