Skip to content

SRET never clears mstatus.MPRV (should always clear it) #231

@SolAstrius

Description

@SolAstrius

SRET doesn't clear mstatus.MPRV, but it should always clear it.

The privileged spec, on xRET:

"When executing an xRET instruction, supposing xPP holds the value y, xIE is set to xPIE; the privilege mode is changed to y; xPIE is set to 1; and xPP is set to the least-privileged supported mode (U if U-mode is implemented, else M). If y!=M, xRET also sets MPRV=0."

and again in the MPRV description:

"An MRET or SRET instruction that changes the privilege mode to a mode less privileged than M also sets MPRV=0."

In riscv_emulate_opc_system() the MRET path does this (it clears MPRV when next_priv < M), but the SRET path doesn't clear MPRV at all. And for SRET the return mode y is just SPP, which is one bit - so it's always U or S, always less privileged than M. That means SRET should clear MPRV unconditionally, and right now it never does.

Low impact in practice, since MPRV is written from M-mode and an SRET arriving with MPRV still set is an unusual flow, but it's a real spec deviation: a stale MPRV=1 after SRET keeps loads/stores using MPP's translation/protection in S/U mode.

Fix is a one-liner in the SRET case mirroring MRET: clear CSR_STATUS_MPRV.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions