Skip to content

[BUG] Incorrect address translation for G-stage NAPOT. #3569

Description

@YangKefan-rk

Code of Conduct

  • I have searched the existing bug issues.
  • I am a human engaging in an interpersonal interaction. During this interaction, my words are my own and are not generated. If relevant, I provide links to my sources.

CVA6 commit affected

81245a4

Bug Description

Bug Description

With RVH=1 and SvnapotEn=1, a G-stage 64 KiB NAPOT mapping
translates a load to the wrong physical subpage.

In cva6_tlb.sv, the NAPOT handling replaces the low four PPN bits
for lu_content_o, but omits the corresponding replacement for
lu_g_content_o. The G-stage output retains the encoded value
PPN[3:0] instead of using GPA[15:12].

The Svnapot specification explicitly states:

If the hypervisor extension is also implemented, Svnapot is also
supported in G-stage translation.

Specification:
https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#svnapot

Steps to reproduce

Environment: CVA6 ariane_testharness under Verilator 5.036 and Spike
execute the same bare-metal RISC-V ELF, comparing register writeback traces.

Configuration: cv64a6_imafdch_sv39 with RVH=1, RVC=0,
SvnapotEn=1, and UseSharedTlb=0.

A possible way to reproduce this issue would be to write a small
bare-metal assembly test that sets up a G-stage NAPOT mapping and
loads from a selected guest physical address. The same ELF runs on
CVA6 and Spike, and the value loaded into a0 is compared.
The test performs the following steps:

  1. Set vsatp to Bare and configure hgatp for Sv39x4, using a
    16 KiB-aligned root page table.
  2. Map the guest range starting at 0x40000000 to the 64 KiB-aligned
    physical range at 0x80010000. Populate all 16 lowest-level entries
    with identical NAPOT PTEs: N=1, PPN=0x80018,
    V/R/W/X/U/A/D=1, and other bits zero.
  3. Place distinct values at physical addresses 0x80013120 and
    0x80018120, then execute HFENCE.GVMA.
  4. Set MPRV=1, MPV=1, and MPP=S. Execute ld a0, 0(s0) with
    s0=0x40003120, and compare the result against Spike.

Expected behavior

The low four PPN bits must be replaced with GPA[15:12]=3.

Result Expected / Spike CVA6
Physical address 0x80013120 0x80018120
Loaded value 0x1111222233334444 0x5555666677778888

Observed behavior

CVA6 reads from the wrong physical subpage, producing a different
load result from Spike.

Activity

  1. added
    Type:BugFor bugs in the RTL, Documentation, Verification environment or Tool and Build system
    on Sep 16, 2026
  2. added
    Component:RTLFor issues in the RTL (e.g. for files in the rtl directory)
    Status:NewNewly created issue, nobody has looked at it yet.
    notCV32A65XIt is not an CV32A65X issue
    on Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Component:RTLFor issues in the RTL (e.g. for files in the rtl directory)PARAM:MMUMMU relatedStatus:NewNewly created issue, nobody has looked at it yet.Type:BugFor bugs in the RTL, Documentation, Verification environment or Tool and Build systemnotCV32A65XIt is not an CV32A65X issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions