Skip to content

hptw: tag the DTLB entry with the access's own VA on a chained walk (#1885) - #1887

Open
davidharrishmc wants to merge 1 commit into
openhwfoundation:mainfrom
davidharrishmc:dh/hptw-seladr-fix
Open

davidharrishmc wants to merge 1 commit into
openhwfoundation:mainfrom
davidharrishmc:dh/hptw-seladr-fix

Conversation

@davidharrishmc

Copy link
Copy Markdown
Contributor

Fixes #1885 with one line, as an alternative to the full revert in #1886.

What was wrong

The DTLB entry is tagged with the MMU's VAdr input, which is the LSU address muxed by
SelHPTWAdr, so SelHPTWAdr has to drop during DTLBWriteM. #1875 qualified that term with
(DTLBWalkPending & ~ITLBWalkPending), which is false when a DTLB walk and an ITLB walk are both
pending — the chained walk #1871 introduced. On such a walk the mux stays on the walker and the
entry is tagged with the walker's PTE address.

MEMPIPE_PROBE, same ELF and cycle, before and after (Im=1 is the pending ITLB walk, HPTW=10 is
LEAF, DW=1 the DTLB write):

before  [68300] Adr=00000300800013b0 PA=00000000000008 | DTLBw=1 Im=1 SelAdr=1 PTE=00db DW=1
after   [68300] Adr=00000300800013b0 PA=000300800013b0 | DTLBw=1 Im=1 SelAdr=0 PTE=00db DW=1

The mis-tagged entry carries PTE 0xdb (V, R, X, U=1, A, D) over the trap handler's data
region, so the next S-mode access that hits it with SUM=0 fails ImproperPrivilege and takes a
spurious page fault. Full analysis in #1885.

Verification

On top of ff84ec108, Verilator 5.036 plus Questa + ImperasDV where noted:

main this PR
#1885 reproducers (3 tests, rv64gc) watchdog livelock pass, 0 IDV mismatches
#1766 ELF (rv32gc) pass pass, 0 IDV mismatches
arch64vm_sv39, sv48, sv48_a, sv48_b pass pass
ACT Sv, act4 HEAD and 22c01e88b1, rv32gc 30 + rv64gc 97 94/97 on one combination pass, all four
regression-wally 6 failed configs same 6, identical list

(Those 6 are pre-existing in a fresh worktree: three configs where testbench.sv:797 dereferences
core.priv.priv unconditionally, two suites whose vectors this machine never built, and
wally64priv/WALLY-trap-01, which fails the same way on main.)

Caveat

This does not address the other half of #1875 — the removal of MemAccessInFlightM /
MemAccessDoneM. The same trace shows a performed M-stage access being flushed and replayed
([68520] D$ ADDRESS_SETUP, then [68530] HPTWFlushW), which is what those guards existed for.
Harmless for a cached load, not for an uncached/IO access or an AMO (R4 in the #1871 notes). I have
no failing case for it, so it is an open risk, not a second bug — if you would rather be
conservative, take #1886 instead and re-land #1875 without the SelHPTWAdr hunk.

🤖 Generated with Claude Code

The DTLB entry is tagged with the MMU's VAdr input, which is the LSU address
muxed by SelHPTWAdr, so SelHPTWAdr has to drop during DTLBWriteM.  openhwfoundation#1875
qualified that term with (DTLBWalkPending & ~ITLBWalkPending), which is false
when a DTLB walk and an ITLB walk are both pending: on such a chained walk the
mux stays on the walker and the entry is tagged with the walker's PTE address.

The bogus entry carries the leaf PTE of the data page (U=1 in the Sv tests) and
covers the trap handler's data region, so the next S-mode access that hits it
with SUM=0 fails ImproperPrivilege and takes a spurious page fault (openhwfoundation#1885).

Restores the openhwfoundation#1871 expression and leaves the rest of openhwfoundation#1875 in place.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spurious load page fault in the trap handler after a wrong-path ITLB walk fault (regression from #1875)

1 participant