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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions