Code of Conduct
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:
- Set
vsatp to Bare and configure hgatp for Sv39x4, using a
16 KiB-aligned root page table.
- 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.
- Place distinct values at physical addresses
0x80013120 and
0x80018120, then execute HFENCE.GVMA.
- 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.
Code of Conduct
CVA6 commit affected
81245a4
Bug Description
Bug Description
With
RVH=1andSvnapotEn=1, a G-stage 64 KiB NAPOT mappingtranslates a load to the wrong physical subpage.
In
cva6_tlb.sv, the NAPOT handling replaces the low four PPN bitsfor
lu_content_o, but omits the corresponding replacement forlu_g_content_o. The G-stage output retains the encoded valuePPN[3:0]instead of usingGPA[15:12].The Svnapot specification explicitly states:
Specification:
https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#svnapot
Steps to reproduce
Environment: CVA6
ariane_testharnessunder Verilator 5.036 and Spikeexecute the same bare-metal RISC-V ELF, comparing register writeback traces.
Configuration:
cv64a6_imafdch_sv39withRVH=1,RVC=0,SvnapotEn=1, andUseSharedTlb=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
a0is compared.The test performs the following steps:
vsatpto Bare and configurehgatpfor Sv39x4, using a16 KiB-aligned root page table.
0x40000000to the 64 KiB-alignedphysical range at
0x80010000. Populate all 16 lowest-level entrieswith identical NAPOT PTEs:
N=1,PPN=0x80018,V/R/W/X/U/A/D=1, and other bits zero.0x80013120and0x80018120, then executeHFENCE.GVMA.MPRV=1,MPV=1, andMPP=S. Executeld a0, 0(s0)withs0=0x40003120, and compare the result against Spike.Expected behavior
The low four PPN bits must be replaced with
GPA[15:12]=3.0x800131200x800181200x11112222333344440x5555666677778888Observed behavior
CVA6 reads from the wrong physical subpage, producing a different
load result from Spike.