Repository navigation
[BUG] Rocket DefaultSmallConfig traps S-mode fetch from an X-only PMP region #3810
Description
I found a self-checking bare-metal RV64 test where Rocket DefaultSmallConfig traps an S-mode instruction fetch from a PMP NAPOT region that has execute permission.
The test configures a 4 KiB PMP NAPOT region around fetch_target with X=1, enters S-mode with mret, and jumps to fetch_target. The fetch should be allowed, but Rocket DefaultSmallConfig traps and the test exits with tohost=15, which is the test's fail_allowed_trapped path.
The same ELF passes on Spike, Rocket DefaultConfig, and SmallBoomConfig.
Test case
The test configures:
.equ INIT_CFG0, 7964
.equ FINAL_CFG0, 7964
.equ EXPECT_TRAP, 0The PMP setup uses pmpaddr0 for a 4 KiB NAPOT region around fetch_target, and pmpaddr1 as a catch-all allow entry:
la t0, fetch_region
srli t0, t0, 2
li t1, 0x1ff
or t0, t0, t1
csrw pmpaddr0, t0
li t0, -1
csrw pmpaddr1, t0
li t0, INIT_CFG0
csrw pmpcfg0, t0The test then enters S-mode and jumps to the protected target:
la t0, fetch_probe_entry
csrw mepc, t0
li t0, MSTATUS_MPP_MASK
csrc mstatus, t0
li t0, MSTATUS_MPP_S
csrs mstatus, t0
mret
fetch_probe_entry:
la t0, fetch_target
jalr zero, 0(t0)Expected: no trap, test exits with tohost=0.
Observed on Rocket DefaultSmallConfig:
*** FAILED *** (tohost = 15)
*** FAILED *** via dtm (code = 15, seed 1780795169) after 161126 cycles
Reproduction commands
Run the test case under different configurations:
timeout 90 ./riscv-isa-sim/install/bin/spike --isa=rv64imac_zicsr --priv=msu ./fetch_allowed_x_should_pass.elf
echo $?
timeout 90 ../../cores/rocket-chip/out/emulator/freechips.rocketchip.system.TestHarness/freechips.rocketchip.system.DefaultSmallConfig/verilator/elf.dest/emulator \
+max-cycles=2000000 \
./fetch_allowed_x_should_pass.elf
echo $?
timeout 90 ../../cores/rocket-chip/out/emulator/freechips.rocketchip.system.TestHarness/freechips.rocketchip.system.DefaultConfig/verilator/elf.dest/emulator \
+max-cycles=2000000 \
./fetch_allowed_x_should_pass.elf
echo $?
timeout 90 ../../cores/chipyard/sims/verilator/simulator-chipyard-SmallBoomConfig \
+max-cycles=2000000 \
./fetch_allowed_x_should_pass.elf
echo $?Result matrix
| Test | Spike | Rocket DefaultSmallConfig | Rocket DefaultConfig | SmallBoomConfig |
|---|---|---|---|---|
fetch_allowed_x_should_pass.elf |
pass, exit 0 | fail, tohost=15 |
pass, exit 0 | pass, exit 0 |
Expected behavior
The target PMP entry has execute permission, so the S-mode instruction fetch should complete and the test should exit with tohost=0.
The RISC-V privileged specification says PMP checks apply to S/U effective-privilege instruction fetches, and the PMP X bit grants instruction-execute permission.
Test Case: testcase.zip
Activity