[pmp/debug]: DRET to U-mode does not clear `mstatus.MPRV`
Nobody has claimed this yet.
- Dominant language
- SystemVerilog
- Stars
- 2.1k
- Forks
- 810
- Avg merge
- 5d 23h
- Merged PRs (30d)
- 9
Description
Observed Behavior
When Ibex enters Debug Mode from M-mode with mstatus.MPRV=1 and mstatus.MPP=M, a debugger can write DCSR.PRV=U and execute DRET. After DRET, Ibex restores the architectural privilege mode to U-mode, but mstatus.MPRV remains set.
The LSU therefore continues to use M-mode as its effective privilege for PMP checks. A subsequent U-mode load to a PMP region without read permission is issued to the external data interface instead of raising a load access fault.
The following values were observed in a complete ibex_core-level Verilator test:
priv_id=U
priv_lsu=M
mstatus.MPRV=1
mstatus.MPP=M
pmp_err=0
data_req=1
The test used a non-locked NAPOT PMP region covering 0x3000–0x3fff with execute permission only. The target operation was lw t2, 0(t1) with t1=0x3000 after returning from Debug Mode.
Expected Behavior
According to the RISC-V Debug Specification, when a hart resumes at a privilege mode lower than M-mode, mstatus.MPRV is cleared.
After DRET with DCSR.PRV=U, the expected state is therefore:
priv_id=U
mstatus.MPRV=0
priv_lsu=U
The load to the execute-only PMP region should then raise a PMP load access fault, and no external data request should be issued.
Steps to reproduce the issue
- Configure PMP entry 0 as a non-locked NAPOT region covering
0x0000–0x03ffwith execute permission for the program and Debug ROM. - Configure PMP entry 1 as a non-locked NAPOT region covering
0x3000–0x3fffwith execute-only permission. - In M-mode, set
mstatus.MPRV=1andmstatus.MPP=M. - Run the core until a known instruction address and assert the external debug request until the core enters Debug Mode.
- In the Debug ROM, execute
csrw dcsr, x0to setDCSR.PRV=U, followed bydret. - Resume at the instruction after the debug entry point and execute
lw t2, 0(t1)witht1=0x3000. - Observe
priv_mode_id,priv_mode_lsu,mstatus.MPRV, the PMP error signal, and the external data request.
The complete test case reports the following target-load result on the current RTL:
target load: priv_id=0 priv_lsu=3 mprv=1 mpp=3 pmp_err=0 data_req=1
In Ibex's privilege-level encoding, 0 is U-mode and 3 is M-mode. The test intentionally terminates with an architectural assertion failure when the expected PMP fault is not observed. The current RTL exits with code 134 because of this assertion.
The relevant RTL behavior appears to be:
- The
DRETpath restorespriv_lvl_dfromdcsr_q.prv. - The corresponding
DRETpath does not clearmstatus_q.mprvwhen the restored privilege is below M-mode. priv_mode_lsu_ois computed asmstatus_q.mprv ? mstatus_q.mpp : priv_lvl_qand is passed to the data-side PMP checker.
My Environment
Ibex source revision: 57d37bf9008640415532d23ad59018b795c642aa.
The test was run with Verilator against the real ibex_core using PMPEnable=1, four PMP regions, and the external instruction and data interfaces connected to a cycle-accurate memory model.
The self-contained reproduction consists of:
ibex_core_dret_mprv_tb.svibex_core_dret_mprv_program.Srun_ibex_core_dret_mprv.sh
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the DRET path that restores priv_lvl_d from dcsr_q.prv and compare it with the mstatus_q.mprv handling; the issue identifies these signals and the priv_mode_lsu_o calculation. Run the provided ibex_core_dret_mprv_tb.sv, ibex_core_dret_mprv_program.S, and run_ibex_core_dret_mprv.sh reproduction. Done means DRET to U-mode clears MPRV, the LSU uses U-mode, and the execute-only PMP load faults without an external data request.
Written by the indexing model from the issue text.
Assessment
- Domain
- embedded-iot, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 62/100