Summary
OpenC910 custom addressed cache operations complete successfully on an address protected by PMP. Under the same PMP configuration, an ordinary load from the same address raises an access fault.
The minimal software-visible POC is a locked M-mode cache operation:
PMP0 = locked 4KB NAPOT deny on the target page
- ordinary
lw from the target traps
dcache.cva on the same target returns successfully
Expected result:
- the addressed cache operation should not silently complete on a PMP-denied block
Actual result on OpenC910:
- the cache operation retires successfully
Test Case
The testcase configures pmpaddr0 = 0x181ff and pmpcfg0 = 0x98, which makes the page containing 0x60080 a locked NAPOT no-access region. It then runs either the ordinary load control or the addressed cache operation on the same target address:
.include "openc910_min_common.inc"
.equ TARGET_ADDR, 0x60080
.equ TARGET_PAGE_NAPOT, 0x181ff
.equ PMP_DENY_LOCKED_NAPOT, 0x98
.text
.align 6
.global main
main:
la t0, trap_handler
csrw mtvec, t0
li t0, TARGET_ADDR
li t1, 0x1122334455667788
sd t1, 0(t0)
fence
li t0, TARGET_PAGE_NAPOT
csrw pmpaddr0, t0
li t0, PMP_DENY_LOCKED_NAPOT
csrw pmpcfg0, t0
fence
li t0, TARGET_ADDR
#if ACCESS_KIND == 5
lw t1, 0(t0) # ordinary load control
#else
.word 0x0252800b # dcache.cva t0
#endif
la a0, fail_msg
jal ra, oracle_puts
1:
j 1b
trap_handler:
csrr t0, mcause
li t1, 5
beq t0, t1, expected_trap
li t1, 7
beq t0, t1, expected_trap
la a0, unexpected_trap_msg
jal ra, oracle_puts
2:
j 2b
expected_trap:
la a0, pass_msg
jal ra, oracle_puts
3:
j 3b
.section .rodata
pass_msg:
.asciz "PASS\n"
fail_msg:
.asciz "FAIL\n"
unexpected_trap_msg:
.asciz "UNEXPECTED_TRAP\n"
On OpenC910, ordinary lw prints PASS, while dcache.cva prints FAIL.
How to reproduce
Build OpenC910's native Verilator simulator
cd openc910/smart_run
make compile SIM=verilator THREADS=8
make buildVerilator
Compile and run the failing testcase
/opt/riscv/bin/riscv64-unknown-elf-gcc -c -march=rv64gc_zicsr_zifencei -mabi=lp64d -O2 openc910_min_crt0.S -o openc910_min_crt0.o
/opt/riscv/bin/riscv64-unknown-elf-gcc -c -march=rv64gc_zicsr_zifencei -mabi=lp64d -O2 -DACCESS_KIND=1 -DDELAY_NOPS=1 openc910_pmp_locked_dcache_op_param.S -o openc910_pmp_locked_dcache_op_param.o
/opt/riscv/bin/riscv64-unknown-elf-gcc -nostdlib -nostartfiles -march=rv64gc_zicsr_zifencei -mabi=lp64d -T openc910_min_linker.ld openc910_min_crt0.o openc910_pmp_locked_dcache_op_param.o -o openc910_pmp_locked_dcache_op_param.elf
/opt/riscv/bin/riscv64-unknown-elf-objcopy -O srec openc910_pmp_locked_dcache_op_param.elf openc910_pmp_locked_dcache_op_param_inst.hex -j .text* -j .rodata* -j .eh_frame*
/opt/riscv/bin/riscv64-unknown-elf-objcopy -O srec openc910_pmp_locked_dcache_op_param.elf openc910_pmp_locked_dcache_op_param_data.hex -j .data* -j .bss -j .sbss -j .COMMON
../tests/bin/Srec2vmem openc910_pmp_locked_dcache_op_param_inst.hex inst.pat
../tests/bin/Srec2vmem openc910_pmp_locked_dcache_op_param_data.hex data.pat
./obj_dir/Vtop
Observed output:
Meaning:
PASS = the PMP-denied operation raised an access-fault trap
FAIL = the PMP-denied cache operation returned successfully
ILLEGAL, SETUP_FAIL, UNEXPECTED_TRAP = diagnostic failures
Test Case: test.zip
Summary
OpenC910 custom addressed cache operations complete successfully on an address protected by PMP. Under the same PMP configuration, an ordinary load from the same address raises an access fault.
The minimal software-visible POC is a locked M-mode cache operation:
PMP0 = locked 4KB NAPOT denyon the target pagelwfrom the target trapsdcache.cvaon the same target returns successfullyExpected result:
Actual result on OpenC910:
Test Case
The testcase configures
pmpaddr0 = 0x181ffandpmpcfg0 = 0x98, which makes the page containing0x60080a locked NAPOT no-access region. It then runs either the ordinary load control or the addressed cache operation on the same target address:On OpenC910, ordinary
lwprintsPASS, whiledcache.cvaprintsFAIL.How to reproduce
Build OpenC910's native Verilator simulator
cd openc910/smart_run make compile SIM=verilator THREADS=8 make buildVerilatorCompile and run the failing testcase
Observed output:
FAILMeaning:
PASS= the PMP-denied operation raised an access-fault trapFAIL= the PMP-denied cache operation returned successfullyILLEGAL,SETUP_FAIL,UNEXPECTED_TRAP= diagnostic failuresTest Case: test.zip