snapshot: stop the l1d dirty bit aliasing physical address bit 31 - #66
Merged
Merged
Conversation
mach-kernel
force-pushed
the
snapshot-restore-1
branch
2 times, most recently
from
July 30, 2026 14:00
15cc45a to
12bc6cd
Compare
mach-kernel
force-pushed
the
snapshot-restore-1
branch
2 times, most recently
from
July 30, 2026 14:11
e3f790c to
7a1cefc
Compare
The serialized L1D tag mixed two layouts from the R4400 manual: PTag at [31:8] from the TagLo register (Figure 4-18) with the dirty bit at 27 from the physical cache line (Figure 11-4). Bit 27 is PTag bit 19 in the register layout, so it aliased physical address bit 31 and every dirty line came back 2 GB from its own address, never matched again, and was never written back. Use Figure 11-4 throughout: PTag [23:0], CS [25:24], W [27]. Snapshots written before the dc_tag_format key are migrated.
mach-kernel
force-pushed
the
snapshot-restore-1
branch
from
July 30, 2026 14:17
7a1cefc to
d482c28
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The serialized L1D tag mixed two layouts from the manual:
PTagat[31:8]from the TagLo register, with the dirty bit at 27 from the physical cache line. Bit 27 isPTagbit 19 in the register layout, so it aliased physical address bit 31. Every dirty L1D line came back 2 GB from its own address,matches_physnever matched it again, and it was never written back.Changes
WandPTagmoves down out of its way:[27]W, write-back[25:24]CS[23:0]PTagW'andPare parity over fields this model does not compute, so they stay zero.save_cache_statewritesdc_tag_format; absent or0means the old layout andmigrate_l1d_tag_word_v0repacks it,1is current, anything else is an error rather than a silent misread.phys_bit31 | dirty, so migration resolves it in favour of dirty. Safe because no cacheable mapping exists at or above0x8000_0000: the highest range indevice_mapisHIMEM_ENDat0x3000_0000.SCHEMA_VERSION3 to 4. Without it a v3 reader takes a v4 tag as clean and drops the line without writing it back, which is this same bug running the other way. The bump makes it refuse the snapshot instead, perrules/snapshot/snapshot-manifest-format-snapshottoml-schema-version1.md.rules/snapshot/l1d-tag-must-match-the-cache-line-layout.mdrecords why a round-trip test cannot catch this.Coverage / needs eyes
l1d_tag_dirty_round_trips_addressandl1d_tag_v0_word_migratesboth fail with only the twoFromimpls reverted. The first reportsleft: 2147483648 right: 0, the 2 GB offset.0x8000_0000andcs1-3.cs = 2withdirtyset is the dominant real state, sincemark_l1d_dirtysetsdirtywithout touchingcs.cargo test --release --features lightning,rex-jit,chd: 358 passed, 11 ignored, over 3 runs.CSandWstay independent fields, so no state normalizes across a snapshot. An earlier revision of this PR folded dirty intoPStateand lost both Shared-with-dirty and CleanExclusive-with-dirty.l1d_tag_invalid_stays_invalidsurvives that mutation. It is a guard, not a regression test.L1ITagstill uses the TagLo register layout ([31:8]PTag,[7:6]PState). It has no dirty bit so nothing aliases, but the two tags in this file now follow different figures.