Bug Description
During an Sv39 load translation, the root PTE is a valid non-leaf PTE whose PPN points to physical page 0. Accessing the next-level PTE therefore fails the platform's physical access checks.
Spike reports a Load access fault (mcause=5). NutShell reports a Load page fault (mcause=13). The original PTE content is not the reason for failure: the implicit memory access needed to fetch that PTE cannot be performed. These two conditions have different architectural causes.
RISC-V Specification Requirement
The distinction here is between failing to read a PTE and reading a bad PTE. If the page-table walker cannot access the memory containing the next PTE, the fault is an access fault for the original operation. It only becomes a page fault after the PTE has actually been read and its contents are found to be invalid or reserved.
The Supervisor Privileged Specification's virtual-address translation algorithm is explicit:
- Step 2 accesses the PTE at the computed physical address.
- If accessing that PTE violates a PMA or PMP check, the implementation raises an access-fault exception corresponding to the original access type.
- Only after a PTE is successfully read does an invalid/reserved PTE encoding cause a corresponding page-fault exception.
Reference: https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#_virtual_address_translation_process
For this original load, a failed implicit PTE read must therefore be cause 5, not cause 13.
Steps to Reproduce
- Run the supplied
poc/program.elf under difftest.
- The test writes a valid non-leaf root PTE with
PPN=0 for virtual address 0x40201010.
- It enables Sv39 and uses S-mode effective privilege for the data access.
- It executes
ld t2, 0(0x40201010).
Essential setup:
/* root_pt[ROOT_INDEX] = PTE_V, PPN = 0 */
li t1, 1
sd t1, (ROOT_INDEX * 8)(root_pt)
...
ld t2, 0(a0)
Expected Result
mcause = 5 (Load access fault)
mepc = load_site
mtval = 0x40201010
Actual Result
NutShell labels the fault as cause 13, while Spike reports cause 5:
DUT exception ... cause 000000000000000d ld t2, 0(a0)
REF mcause=0000000000000005 mepc=0000000080000070
REF mtval=0000000040201010
mcause different ... right=5, wrong=d
NS-5.zip
Bug Description
During an Sv39 load translation, the root PTE is a valid non-leaf PTE whose PPN points to physical page 0. Accessing the next-level PTE therefore fails the platform's physical access checks.
Spike reports a Load access fault (
mcause=5). NutShell reports a Load page fault (mcause=13). The original PTE content is not the reason for failure: the implicit memory access needed to fetch that PTE cannot be performed. These two conditions have different architectural causes.RISC-V Specification Requirement
The distinction here is between failing to read a PTE and reading a bad PTE. If the page-table walker cannot access the memory containing the next PTE, the fault is an access fault for the original operation. It only becomes a page fault after the PTE has actually been read and its contents are found to be invalid or reserved.
The Supervisor Privileged Specification's virtual-address translation algorithm is explicit:
Reference: https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#_virtual_address_translation_process
For this original load, a failed implicit PTE read must therefore be cause 5, not cause 13.
Steps to Reproduce
poc/program.elfunder difftest.PPN=0for virtual address0x40201010.ld t2, 0(0x40201010).Essential setup:
Expected Result
mcause = 5(Load access fault)mepc = load_sitemtval = 0x40201010Actual Result
NutShell labels the fault as cause 13, while Spike reports cause 5:
NS-5.zip