Repository navigation
openvmm: name every CPUID difference in CPU-surface errors - #1014
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the documentation update recording the OpenVMM pin and CPU-diagnostic commits.
No open issues 🎉
What changed in this PR
This PR promotes an OpenVMM revision that reports every CPUID difference in CPU-surface errors, addressing #568. The reviewed documentation maps those changes into NVX’s upstream roadmap.
Changes:
- Updates the documented NVX pin to
235da5cb8, position 362. - Records the three CPU-diagnostic commits and their relationship to the existing time ABI work.
- Updates the commit counts, branch diagram, and merge history.
| File | Description |
|---|---|
doc/openvmm-upstream-roadmap.md |
Documents the new pin, positions 360–362, and their upstream context. |
Review effort: Balanced
b468ec7 to
ca43130
Compare
ca43130 to
e0f8b6e
Compare
Pin microsoft/openvmm#4804 at e4c741e1860de1e2149b3dd5d41863468705b02c, four commits on c32c57d12, the previous pin, which is the head of feature/microvm/dev. CPU-profile verification is to report every violation together, naming the leaf, subleaf, register, and bit, as section 2.2.1.3 of the architecture guide states. OpenVMM's E_CPU_SURFACE errors instead named at most 16 differences and dropped the rest, though they counted them all: both the restore's comparison of the recomputed effective CPUID with the snapshot's record and the comparison of VP 0's CPUID with the effective CPUID before any VP runs. The VM worker also ran its CPU checks in turn and stopped at the first that failed. The first commit names, for each entry that both the recomputed effective CPUID and the snapshot's record hold, every register in which they differ, with its value and mask on each side, on one line, rather than all four results and masks of each side as pretty-printed arrays of 24 lines. The second names every difference. The lists stay bounded: the effective CPUID of each pinned profile has between 64 and 94 entries, and a snapshot's record at most 1024, which the manifest decoder enforces. The third names the non-zero CPUID entries outside the profile's tables that VP 0 reads on a pass-through backend together with the results that VP 0 does not observe, rather than only once those match, as the support check names such entries after what a backend lacks. A report whose only violations are such entries still fails with E_CPU_UNLISTED. The fourth runs every CPU check of a partition, even after one fails: the restore's comparison with the snapshot's record, the check of VP 0's CPUID, and the check that the backend supports the profile. It reports their failures together, leading with the first failure, and so with the code that OpenVMM reported before. A failure alone is reported as before. The line with which OpenVMM exits on these errors keeps its code, from which nvx-rs attributes a clone's failure to an incompatible host. The error's detail follows that line in OpenVMM's log. For the largest pinned profile, whose effective CPUID has 94 entries, an error in which every register of every entry differs in both comparisons and the backend supports nothing takes 61,717 bytes, within the 64 KiB at the end of the log that nvx-rs searches for the line. 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 four commits that the previous commit pins as positions 362-365 of the microVM chain, and move the NVX pin to e4c741e18. Positions 362-365 make the E_CPU_SURFACE errors of the microVM's CPU checks name every CPUID difference rather than the first 16, each entry of a snapshot's effective CPUID record on one line with the registers in which it differs, and name the non-zero CPUID entries outside the profile's tables that VP 0 reads together with the results that VP 0 does not observe. The VM worker then runs every CPU check of a partition, even after one fails, and reports their failures together. They change only the CPU checks of the VM worker's time ABI, which the time ABI work at positions 159-269 added, and the snapshot guide's description of them; say so in the table's remarks. The pin is now 208 commits past the mapped tip. Positions 360 and 361 are no longer only a proposal: microsoft/openvmm#4807 merged them, so position 361, c32c57d12, is the head of feature/microvm/dev. Say so in the scope, and name microsoft/openvmm#4804 as the proposal of positions 362-365. Refs #568 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e0f8b6e to
f5f4c67
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
Integration depends on validation of the unmerged OpenVMM head, completion of queued exact-head CI run 40958505253, and confirmation of the required fast-forward into feature/microvm/dev.
No open issues 🎉
Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The OpenVMM gitlink pins an open PR with roughly 500 lines outside this diff, requiring maintainer confirmation of upstream source review and the prerequisite branch fast-forward and merge order.
No open issues 🎉
Review effort: Max
Fixes #568. Pins microsoft/openvmm#4804 at
e4c741e1860de1e2149b3dd5d41863468705b02c, which makes the CPU checks of a microVM report every violation together, as section 2.2.1.3 of the architecture guide states. TheE_CPU_SURFACEerrors name every CPUID difference rather than the first 16, and the VM worker runs every CPU check of a partition and reports their failures in one error rather than stopping at the first. This pull request also maps the pin in the OpenVMM roadmap. The architecture guide does not change: OpenVMM now reports what it states, so no bound needs recording.Based on
devat8bee339dd. microsoft/openvmm#4804 is four commits directly onc32c57d12, the head offeature/microvm/devand the revision thatdevpins since #1016 merged, and the pin is that pull request's head commit itself, so this branch's two commits are its whole diff.Change
545684c80openvmmopenvmmc32c57d12→e4c741e18: the four commits of microsoft/openvmm#4804f5f4c67bfdocdoc/openvmm-upstream-roadmap.mdfeature/microvm/devNo other NVX change is needed. OpenVMM's control-session protocol vectors and built-in CPU profiles are unchanged at the pin. The line with which OpenVMM exits on these errors, such as
fatal error: [E_CPU_SURFACE] failed to launch vm worker, keeps the code of the first check that fails, andnvx-rsattributes a clone's failure to an incompatible host from that code. The error's detail follows that line in OpenVMM's log. For the largest pinned profile, Turin, an error in which every register of all 94 entries differs in both comparisons and the backend supports nothing takes 61,717 bytes. That is within the 64 KiB at the end of the log thatnvx-rssearches for the line; only a snapshot record that no OpenVMM writes, with most of the 1024 entries that the manifest decoder admits, could take more.OpenVMM changes
69ddc715b). When the effective CPUID that a restore recomputes differs from the snapshot's record, the error names, for each entry that both hold, every register in which they differ, with its value and mask on each side, on one line. It printed all four results and masks of each side with{:#x?}, which pretty-prints each array over six lines: 24 lines per entry, without saying which register differs.c55db5d9e). BothE_CPU_SURFACEerrors, the restore's comparison with the snapshot's record and the comparison of VP 0's CPUID with the effective CPUID before any VP runs, name every difference rather than the first 16 (MAX_REPORTED_CPUID_DIFFERENCES), and keep counting them. The lists stay bounded: the effective CPUID of each pinned profile has between 64 entries (Skylake-SP) and 94 (Turin), and a snapshot's record at most 1024, which the manifest decoder enforces.e1fa0f028). The worker checked VP 0's non-zero CPUID entries outside the profile's tables on a pass-through backend (E_CPU_UNLISTED) only once VP 0 observed every result, so a report that failed both named only the results. AnE_CPU_SURFACEfailure now names every result that VP 0 does not observe, then every such entry, as the backend support check names those entries after what a backend lacks, and a report whose only violations are such entries still fails withE_CPU_UNLISTED. No failure changes its code.e4c741e18). The worker ran its CPU checks in turn and stopped at the first that failed, so a restore whose record differed did not say whether VP 0 also read other values or the backend also lacked a feature of the profile. It now runs the comparison with the snapshot's record, the check of VP 0's CPUID, and the check that the backend supports the profile even after one fails. It reports their failures in one error that leads with the first, and so with the code that it had. A failure alone is reported as before.The issue's tasks map onto this as follows:
Validation
OpenVMM, on Windows: for
openvmm_core,cargo clippy --all-targets -- -D warnings,cargo doc --no-deps, andcargo nextest run --profile agentate4c741e18(121 tests passed), withcpu_profile's 119, andcargo xtask fmt, all clean. Before [DO NOT REVIEW] microVM: name every CPUID difference in CPU-surface errors openvmm#4804 was rebased ontoc32c57d12, its first three commits passed 118, 120, and 120 tests onbd2b27a2e;git range-diffshows the four commits unchanged by the rebase. The new tests fail with the limit restored, the test of the entries outside the profile fails if the error leaves them out, and the test of the combined checks fails if they stop at the first failure.End to end on the Azure test VMs
nvx-kvm-test,nvx-mshv-test, andnvx-whp-test, at this branch's head, with the guest artifacts of releasev0.1.0-dev.299d0b4d9851, whose OpenVMM,bd2b27a2e, served as the baseline:Several failures. On Linux/KVM, a snapshot captured with the pin on the host profile
intel.host.v1(--cpu-profile host) had SSE4A (CPUID0x80000001ECX bit 6), which Intel CPUs lack, set in its manifest's profile document, and the document's digest updated. It fails to restore on each binary with the same exit line,fatal error: [E_CPU_SURFACE] failed to launch vm worker, and the pin names both failures:[DO NOT REVIEW] microVM: name every CPUID difference in CPU-surface errors openvmm#4804's third commit as first pushed,
235da5cb8, names the first failure alone, and the baseline names it over 24 lines. MSHV and WHP refuse such a profile when they create the partition, before these checks run ([E_PROFILE_UNSUPPORTED] the hypervisor's processor features cannot present CPU profile intel.host.v1: they lack sse4a_support), with the pin as before.Every difference. A snapshot captured with the pin, whose manifest's effective CPUID record then had bit 0 of EAX flipped in every entry, fails to restore with
E_CPU_SURFACEon both binaries, with the same exit line. The baseline names 16 of the entries that it counts, over 321 lines. The pin names every one, on one line, and no other failure, as the other checks, which now run too, pass:intel.emeraldrapids.v1intel.emeraldrapids.v1intel.icelake-sp.v1On the same VMs,
python3 scripts/nvx.py test-microvm(andpython scripts\nvx.py test-microvmon Windows) with the scenariossmp-snapshot(1, 2, 4, and 8 vCPUs),snapshot-core, andtime-abi-conformance(8 vCPUs), whose cold boots and restores pass every CPU check, passed at the pin on Linux/KVM, Linux/MSHV, and Windows/WHP, as they did at93cf08c4d, the pin before the rebase. A--x-time-abi-verifycold boot on each logstime ABI CPU checks passedwith the checks' timings, as before.NVX at
f5f4c67bf:python scripts\nvx.py verify(consistent); theopenvmm_vectorsandopenvmm_cpu_profilescomparisons with--ignored(3 and 1 passed), against the pinned revision;python scripts\check_markdown_links.py; andgit diff --check.Every commit is signed, both these and [DO NOT REVIEW] microVM: name every CPUID difference in CPU-surface errors openvmm#4804's.
CI: before the rebase, [DO NOT REVIEW] microVM: name every CPUID difference in CPU-surface errors openvmm#4804's checks all passed at
93cf08c4d, and this pull request's atca431309a. Ate0f8b6ecc, ondevat0eb0a27f2,NVX CLI / Linuxfailed inscripts/test_nvx_rs_mutants.py(MUTANTS_RESULT: unbound variable), as on other pull requests of thatdev: ci: fix nvx-rs mutants summarize miscounting shards #952 changed the mutants workflow's merge step without its tests, which scripts: test the mutants merge against the shards' indexed outcomes #1023 fixed, so this branch now sits ondevwith scripts: test the mutants merge against the shards' indexed outcomes #1023. At headf5f4c67bf, every check passed. The first attempt of run 40962952624 failed one runtime adapter scenario ofNVX microVM tests / Linux / KVM / Guests and sandboxes,vm_clone'sa_clone_refuses_a_scratch_image_whose_upper_an_earlier_clone_used, whose second clone accepted a used scratch image. That is the intermittent failure that runtime-adapter: a_clone_refuses_a_scratch_image_whose_upper_an_earlier_clone_used fails intermittently #1020 tracks, whichdev's own push run 40949525134 also hit, at OpenVMMc32c57d12, and the rerun of the failed jobs passed. The pin changes no step of a CPU check that passes, so a clone's guest sees the same machine. Onnvx-kvm-test, with that run's own guest artifacts and guest agent,vm_clone's 34 scenarios failed intermittently with both pins: in 6 of 14 runs withe4c741e18, 4 of them in that scenario, and in 2 of 11 runs withc32c57d12, in two other scenarios. [DO NOT REVIEW] microVM: name every CPUID difference in CPU-surface errors openvmm#4804's checks all passed ate4c741e18too: the first attempt of its run 40958505253 failed the twoverify openhcl binary sizejobs, which compare with thefeature/microvm/devCI run ofc32c57d12, then still running, and their rerun passed.Merge microsoft/openvmm#4804 into
feature/microvm/dev, by fast-forwarding that branch toe4c741e18, before merging this pull request.