#1261 probes: exception entry, spurious ack, timer re-arm, console-free sample - #1284
Merged
Merged
Conversation
…ee sample All inert unless `forensics on`; each is pinned by the extended live-forensics gate so deleting a call site fails the gate instead of silently zeroing the reading a dying boot is read for. - `entry` at exc_dispatch entry, BEFORE any GIC state is consumed — cadence vs the post-ack `irq` probe separates "not delivered" from "delivered but acked spurious". - `spur` on the spurious-ack early return in irq_dispatch — a spurious storm was previously indistinguishable from silence. Reported in the gate census, not required (a healthy boot acks zero). - `rearm` in timer.arm, arg = the programmed comparator delta — a steady rearm cadence with no `entry` says the comparator fires but the exception is never taken; a rearm gap says the source stopped. - `shot` from the shell idle loop, self-draining, one per 4 s of wall-clock time: proves the guest is still executing with no console traffic to ride on. Clock choice is measured, not assumed. Two candidates were tried and rejected with live evidence: `scheduler.tick_count` (per-quantum, not per-second: 6,212 samples in one gate boot) and `timer.irq_ticks` (shared by both cores' PPIs and reset by re-init paths: went 1 -> 0 during early boot and advanced ~2/s, flooding at ~47 samples/s — the gate census `shot: 6624` caught it before merge). The shipped clock is `timer.cntpct() / timer.freq`: monotonic-by-contract, exact seconds, host-test-deterministic (freq is a parameter). The counter itself is NOT monotonic for the first ~0.9 s under VZ on this host (observed twice: a ~0.1 s backward step at t≈0.89 s), so the elapsed computation saturates instead of underflowing, and any trace that sorts `t=` across the first second of a boot is misordered — a finding for #1261, recorded where the guard is. Measured on the nudge dying-boot scratch tree: samples on a 4.0 s cadence to the end of a 120 s boot, spurious acks zero, beat deltas 1.000-1.002 s, `entry` cadence matching the 1 Hz timer — the PPIs are delivered AND recorded to the end. Full finding on issue #1261. Gate: live-forensics PASS 1/1 — census entry 245 / irq 238 / rearm 238 / rotate 121 / shot 32 on a 120 s boot, shot args 4->8->...->124 exact. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
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.
What this is
The probe set #1261 needed to make a dying boot name its own last instant, plus the one defect the extended gate caught in the sampler before merge. Every probe is inert unless
forensics on; the extendedlive-forensicsspec pins every probe call site so deleting one fails the gate instead of silently zeroing the reading.Closes #1261 — the card's deliverable was a settled delivered-vs-recorded verdict with the mechanism bounded in writing, which this supplies (below). The follow-on work (which guest action makes VZ abort, and can the abort be made observable) is filed as #1287.
The probes
entryexc_dispatchentry, before any GIC state is consumedirq: "not delivered" vs "delivered but acked spurious"spurirq_dispatchrearmtimer.arm, before the comparator writeentry⇒ comparator fires but exception never taken; rearm gap ⇒ the source stoppedshotThe verdict (measured, twice, on the nudge dying-boot scratch tree)
The PPIs are delivered AND recorded to the last second. The death is not guest-side.
entrycadence matches the 1 Hz timer to the end; samples on a 4.0 s cadence through the final second; spurious acks zero for the whole run;rearmargs all exactly24000000(a 1 s comparator at 24 MHz).VZErrorDomain code=1 — Internal Virtualization error. The virtual machine stopped unexpectedly.VZ aborts the VM rather than the guest faulting — which is why no[EXC]block and no tombstone ever appeared.shotsample is what makes the "still alive" claim sound: 4.000 s exact spacing across the whole run needs neither a delivered interrupt nor a console line to be printed.t=across the first second is misordered; the sampler saturates elapsed time instead of underflowing, and the comment at the guard records this.The gate-caught defect (why this PR exists beyond doc comments)
The first sampler clock was
timer.irq_ticks. The extended gate's census came backshot: 6624on a ~30 s boot — the exact flood signature the wrong-clock bug produced in the scratch tree. Reading the run withVIRELAI_KEEP_RUN=1:irq_ticksis a shared counter (both cores' 1 Hz PPIs) and is reset by re-init paths (it went1 → 0during early boot), and the== 0bypass fired on every sample until the first timer IRQ. The shipped clock istimer.cntpct() / timer.freq— monotonic by contract, exact seconds, and deterministic in host tests because the frequency is a parameter. Post-fix census on a 120 s boot:entry 245 / irq 238 / rearm 238 / rotate 121 / shot 32, shot args4 → 8 → … → 124exact, dense per-core sequences intact.Verification (all observed this session)
live-forensics(class B, extended spec)just verify-portable(incl. transcript gate, fmt, unit tests)zig build(guest image)Not re-run here: the other class-B VZ shards (need VZ; CI runs them).