Skip to content

Sv39-translated U-mode store to an inaccessible physical address retires without Store/AMO access fault #262

Description

@jf-cc727

Bug Description

A U-mode sw passes Sv39 page permission checks but translates to a physical-address hole. Spike takes a precise Store/AMO access fault (mcause=7) at the store. NutShell commits the store, remains in U-mode, and does not update mcause, mepc, or mtval.

The root-level leaf PTE maps virtual address 0x60000040 through a 1 GiB Sv39 superpage. Although the PTE's explicit PPN is zero, Sv39 copies the lower VPN fields into the physical PPN for a superpage, so the resulting physical address is 0x20000040, not 0x40.

In the supplied platform configuration that address is outside the RAM/flash/MMIO map and the reference model reports an access fault.

RISC-V Specification Requirement

The important point is that passing page permission checks is not enough. Sv39 first computes a physical address, and the actual physical memory access can still fail. In this test, the 1 GiB superpage rule makes 0x60000040 translate to physical address 0x20000040; because that physical address is outside the platform's accessible map, the store must raise a Store/AMO access fault instead of retiring.

The Supervisor Privileged Specification defines the Sv39 translation algorithm. For a superpage, the lower physical PPN components are copied from the virtual VPN components. After translation, the resulting physical access is still subject to the platform's PMA/PMP and access-error behavior.

Relevant translation rule:

  • pa.pgoff = va.pgoff;
  • for i > 0, pa.ppn[i-1:0] = va.vpn[i-1:0];
  • remaining physical PPN bits come from the leaf PTE.

Reference: https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#_virtual_address_translation_process

When a store cannot be completed because the resulting physical address fails the platform's access checks, the architectural exception is Store/AMO access fault (cause 7), and the store must not retire as a successful architectural memory operation.

Steps to Reproduce

  1. Run the supplied poc/program.elf.
  2. M-mode installs two root-level Sv39 leaf entries: executable U-mode code at 0x80000000 and writable U-mode test VA 0x60000040.
  3. M-mode clears MPP and executes mret into U-mode.
  4. U-mode executes sw 0xdead1234, 0(0x60000040).

Essential instruction:

li s0, 0x60000040
li t0, 0xdead1234
sw t0, 0(s0)

Expected Result

A precise Store/AMO access fault:

  • mcause = 7
  • mepc = address of sw (0x80000084 in this build)
  • mtval = 0x60000040
  • current privilege becomes M-mode because delegation is cleared
  • the store has no architectural side effect

Actual Result

NutShell shows the store as committed and remains in U-mode, while Spike has entered the M-mode handler:

DUT: [26] commit ... sw t0, 0(s0)
REF: mcause=7, mepc=0x80000084, mtval=0x60000040, privilege=3
DUT: mcause=0, mtval=0, privilege=0
Image

NS-3.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions