Repository navigation
nvx-rs: read OpenVMM's fatal error before a chain of any length, and name repeated CPUID record entries - #1039
Merged
Pedro Henrique Penna (ppenna) merged 3 commits intoOct 30, 2026
Conversation
A clone whose VMM exits before its restore-ready event reads, from the VMM's log, the line with which OpenVMM reported the error that ended it, and attributes the failure to an incompatible host when the line's time ABI code, such as E_CPU_SURFACE, says so. OpenVMM writes that line first, then the error's chain. read_fatal looked for the line in the last 64 KiB of the log alone, which held it while OpenVMM's CPU checks named at most 16 differences. Since microsoft/openvmm#4804, which #1014 pinned, they name every difference that they find, together, in one cause of the chain: about 7.5 KB on the Azure test hosts, and 61,717 bytes for the Turin profile when every register of every entry differs in both comparisons and the backend supports none of the profile, but more for a pass-through backend whose VP 0 reads non-zero values at entries outside the profile's tables, each of which the error names, or for a snapshot record of up to the 1024 entries that the decoder admits. A chain longer than 64 KiB pushed the line out of the tail, so the failure kept its lost status, whose outcome is unknown, rather than the incompatible host, and lost OpenVMM's line from its message. read_fatal now reads the log back from its end, 64 KiB at a time, until it finds the last line that starts with "fatal error: ", then reads that line and the chain that follows it, so that the line keeps its attribution after a chain of any length. A log without the line is read whole, a block at a time. Tests check that the line is read before a chain several blocks long, whether or not a line precedes it, with a cause that names a forward that OpenVMM cannot bind after a long one, and wherever a block starts around the line: after the newline before it, at its start, or within its prefix; and that a long log that only quotes the line holds none. Follow-up to #568. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pin microsoft/openvmm#4818 at bcfc47cff6606afadffef97551e538962895b598, two commits on e4c741e18, the previous pin, which is the head of feature/microvm/dev. When the effective CPUID that a restore recomputes differs from the snapshot's record, OpenVMM's E_CPU_SURFACE error names every entry that differs. It kept only the last listing of an entry that the record lists more than once, and named a record out of order only when nothing else differed, so a record that no OpenVMM writes, but that the decoder admits, could hide differences: a changed listing followed by the entry's own was reported as the same entries in another order. The first commit tests the error's every register, value, and mask, and the order of the entries that only one side has. The second compares every listing of an entry and names each that differs, each entry listed more than once, and a record out of order, whatever else differs. The error keeps its code, and names the differences of a record that OpenVMM writes as before. The protocol vectors and built-in CPU profiles that nvx-rs copies are unchanged. Refs #568 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Record the two commits that the previous commit pins as positions 366 and 367 of the microVM chain, and move the NVX pin to bcfc47cff. Positions 366 and 367 make the restore's comparison of the effective CPUID with a snapshot's record name every difference of a record that the decoder admits although no OpenVMM writes it: each entry that the record lists more than once, each of its listings that differs, and a record out of order, together with the entries that differ. They also test each register, value, and mask that the error names. They change only the first CPU check of the VM worker's time ABI, its tests, and the snapshot guide's description of it; say so in the table's remarks. The pin is now 210 commits past the mapped tip. Positions 362-365 are no longer only a proposal: microsoft/openvmm#4804 merged them, so position 365, e4c741e18, is the head of feature/microvm/dev. Say so in the scope, and name microsoft/openvmm#4818 as the proposal of positions 366 and 367. Refs #568 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
A missing negative test for boundary-aligned quoted fatal text leaves false fatal diagnoses caused by incorrect line-start handling unguarded.
1 open issue
What changed in this PR
Preserves NVX clone-failure attribution when OpenVMM emits long CPU-check error chains, following #1014, and incorporates improved CPUID-record diagnostics.
Changes:
- Search logs backward in 64 KiB blocks instead of limiting fatal-line detection to the final block.
- Add tests for long error chains, forwarding causes, and fatal-prefix block boundaries.
- Update the OpenVMM roadmap for pin
bcfc47cffand repeated or unordered CPUID-record diagnostics.
| File | Description |
|---|---|
nvx-rs/src/host/template/clone/records.rs |
Adds backward fatal-line searching and regression tests. |
doc/openvmm-upstream-roadmap.md |
Records the new pin, commit positions, and CPUID diagnostic changes. |
Review effort: Max
| format!("{filler}warning: fatal error: quoted\n{filler}"), | ||
| ) | ||
| .unwrap(); | ||
| assert_eq!(read_fatal(&path), None); |
Pedro Henrique Penna (ppenna)
deleted the
agents/cpu-surface-review-followups
branch
October 30, 2026 05:27
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.

Follows up #1014 and microsoft/openvmm#4804 from their review, for #568. Two independent reviews of #1014 found that OpenVMM's uncapped CPU-check errors can push the line that leads OpenVMM's fatal error out of the 64 KiB at the end of a VMM's log in which
nvx-rslooked for it, which then lost a clone's attribution to an incompatible host, and that a snapshot record that lists an entry more than once, or out of order, still hid differences. This pull request makesnvx-rsread that line before a chain of any length, pins microsoft/openvmm#4818 atbcfc47cff6606afadffef97551e538962895b598, which names those differences and tests each register, value, and mask that the error names, and maps the pin in the OpenVMM roadmap.Based on
devatd34d8ab73. microsoft/openvmm#4818 is two commits directly one4c741e18, the head offeature/microvm/devsince microsoft/openvmm#4804 merged and the revision thatdevpins since #1014 merged, and the pin is that pull request's head commit itself.Change
6856d4769nvx-rsnvx-rs/src/host/template/clone/records.rsread_fatalreads the VMM's log back from its end, 64 KiB at a time, until it finds the last line that starts withfatal error:, then reads that line and the error's chain after it30ff24201openvmmopenvmme4c741e18→bcfc47cff: the two commits of microsoft/openvmm#48180853bdc75docdoc/openvmm-upstream-roadmap.mdfeature/microvm/devThe protocol vectors and built-in CPU profiles that
nvx-rscopies are unchanged at the pin, and no error code changes.The fatal line before a chain of any length
A clone whose VMM exits before its restore-ready event reads, from the VMM's log, the line with which OpenVMM reported the error that ended it, such as
fatal error: [E_CPU_SURFACE] failed to launch vm worker. The failure's message keeps the line, and its time ABI code attributes the failure to an incompatible host,Evidence::IncompatibleHost, whose outcome isHost. OpenVMM writes the line first, then the error's chain (fatal_error_messageinopenvmm_entry).read_fatallooked for the line among the last 64 KiB of the log (FATAL_TAIL_BYTES), which held it while the CPU checks named at most 16 differences. Since #1014, they name every difference that they find, together, in one cause of the chain:0x100leaves per range and 64 subleaves per leaf, rather than the profile. By the reviews' count, 32 such entries take that Turin error past 64 KiB, and 416 took a combined error to 107,893 bytes.Past 64 KiB, the tail began inside the chain, so
read_fatalfound no line,diagnosedkeptEvidence::LostStatus, whose outcome isUnknown, and the failure's message lostOpenVMM reported: ....read_fatalnow finds the line withlast_line_start, which reads the log back from its end, a block ofFATAL_BLOCK_BYTES(64 KiB) at a time, and checks every line start in a block, last first: after each newline, and at the log's start. A block's read goes on past its end by the prefix's length, so a line that starts at the block's end, after a newline that ends the block, or whose prefix straddles the next block, is found too. It then reads from the line to the log's end: the line, cut to 1024 characters as before, and the chain, in which a cause that names a forward that OpenVMM cannot bind still follows the line. The search holds a block at a time, and the read the chain, which OpenVMM held whole to write it. A log without the line is read whole, a block at a time. The log holds OpenVMM's output of one launch alone; the guest's console has its own log.The tests read the line before a chain three blocks long, with and without a line before it; with a cause that names a forward after a long one; and wherever a block starts around the line, at each offset from the newline before it to past its prefix. They read none from a long log that only quotes the line. With the 64 KiB tail in place of
last_line_start, the first of them fails:read_fatalreturns none.OpenVMM changes
e51ab72d3). Tests only. They check the whole error for a change of the value, and of the mask, of each register alone; for several registers of one entry, named in order on one line; and for an entry that differs among entries that the snapshot lacks, followed by entries that only the snapshot has, named and counted in that order. They pass before and after the next commit.bcfc47cff).recorded_cpuid_differenceskept only the last listing of an entry that a snapshot's record lists more than once, and named a record out of order only when nothing else differed, thoughdecode_effective_cpuidadmits both: a changed listing followed by the entry's own read as "the snapshot lists the same entries in another order", and a record out of order with a changed entry named the changed entry alone. It now compares every listing with the partition's entry and names each that differs, then each entry that the record lists more than once, and, whatever else differs, a record not in order of leaf and subleaf. The error keepsE_CPU_SURFACE, and names the differences of a record that OpenVMM writes as before. With the previous function, the commit's test fails on the review's first case.Validation
nvx-rs, on Windows:cargo fmt --all --check;cargo clippy --locked -- -D warningswith--all-targets --all-features,--lib, and--lib --no-default-features;cargo doc --locked --no-deps --all-featureswith-D warnings;cargo +1.89 check --locked --all-targets --all-features; andcargo test --locked --all-features, all clean.cargo clippy --all-targets -p openvmm_core -- -D warnings,cargo doc --no-deps -p openvmm_core,cargo nextest run --profile agent -p openvmm_core(122 and 123 tests passed), andcargo xtask fmt --fix, all clean.0853bdc75:python scripts\nvx.py verify(consistent); theopenvmm_vectorsandopenvmm_cpu_profilescomparisons with--ignored(3 and 1 passed) against the pin;python scripts\check_markdown_links.py; andgit diff --check.Merge microsoft/openvmm#4818 into
feature/microvm/dev, by fast-forwarding that branch tobcfc47cff, before merging this pull request.