handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes
Source changes (dormant parity infra, retained from iterate 2.AI/2.AO): - xenia-kernel/exports.rs: nt_create_event manual_reset polarity + related event wiring - xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps (.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as regenerable local artifacts — see memory + HANDOFF for the running findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
110
audit-runs/review-a-step1c-crowbar-v3/fix.diff
Normal file
110
audit-runs/review-a-step1c-crowbar-v3/fix.diff
Normal file
@@ -0,0 +1,110 @@
|
||||
+
|
||||
+/// Crowbar v3 Step 2 — optionally install full ctx bytes at `ctx_ptr`
|
||||
+/// from a binary file specified by `XENIA_CROWBAR_CTX_BIN`. Bytes are
|
||||
+/// written verbatim (no byte-swap) via `write_u8` because the file is
|
||||
+/// expected to be a raw guest-endian (big-endian) capture of the ctx
|
||||
+/// layout from canary's runtime memory. Logs the first 16 u32 slots
|
||||
+/// after install for verification. If the env var is unset, this is a
|
||||
+/// no-op so v2 behaviour is preserved exactly.
|
||||
+///
|
||||
+/// Captured via canary's `audit_68_host_mem_read_probe` cvar — see
|
||||
+/// `xenia-rs/audit-runs/review-a-step1c-crowbar-v3/canary-probe-run1.log`.
|
||||
+///
|
||||
+/// **Option γ (per v3 brief)**: install verbatim, including canary-VA
|
||||
+/// pointer fields like `[ctx+44]=0xBCE25640`. These VAs may be unmapped
|
||||
+/// in ours's address space — if a worker dereferences one and faults,
|
||||
+/// that confirms the case-(C) recursion is required (v4 work).
|
||||
+fn crowbar_maybe_install_ctx_from_file(mem: &GuestMemory, ctx_ptr: u32) {
|
||||
+ let path = match std::env::var("XENIA_CROWBAR_CTX_BIN") {
|
||||
+ Ok(p) if !p.is_empty() => p,
|
||||
+ _ => {
|
||||
+ tracing::warn!(
|
||||
+ "CROWBAR: XENIA_CROWBAR_CTX_BIN not set — skipping ctx install \
|
||||
+ (v2 behaviour; only +0/+4/+8/+12 are populated; \
|
||||
+ workers will likely fault on [ctx+44] dispatch)"
|
||||
+ );
|
||||
+ return;
|
||||
+ }
|
||||
+ };
|
||||
+ let bytes = match std::fs::read(&path) {
|
||||
+ Ok(b) => b,
|
||||
+ Err(e) => {
|
||||
+ tracing::error!(
|
||||
+ "CROWBAR: failed to read ctx bin {:?}: {} — skipping install",
|
||||
+ path,
|
||||
+ e,
|
||||
+ );
|
||||
+ return;
|
||||
+ }
|
||||
+ };
|
||||
+ let n = bytes.len().min(256);
|
||||
+ for (i, b) in bytes.iter().take(n).enumerate() {
|
||||
+ mem.write_u8(ctx_ptr + i as u32, *b);
|
||||
+ }
|
||||
+ tracing::warn!(
|
||||
+ "CROWBAR: installed {} bytes at ctx_ptr={:#010x} from {:?}",
|
||||
+ n,
|
||||
+ ctx_ptr,
|
||||
+ path,
|
||||
+ );
|
||||
+ // Verify: log the first 16 u32 slots after install.
|
||||
+ for slot in 0..16u32 {
|
||||
+ let off = slot * 4;
|
||||
+ let v = mem.read_u32(ctx_ptr + off);
|
||||
+ tracing::warn!(
|
||||
+ "CROWBAR: post-ctx-install ctx[+{:>3}] (={:#010x}) = {:#010x}",
|
||||
+ off,
|
||||
+ ctx_ptr + off,
|
||||
+ v,
|
||||
+ );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/// Crowbar entry point — allocate the worker ctx, install the vtable
|
||||
+/// + self-pointer doubly-linked-list head pattern that AUDIT-068 S3
|
||||
+/// captured, spawn all 4 workers suspended, then resume each one.
|
||||
+/// Returns the number of workers successfully resumed (0..=4).
|
||||
+///
|
||||
+/// **Reading-error #37 discipline**: the value written at `ctx+0` is the
|
||||
+/// vtable BASE `0x8200A1E8`, NOT the slot-N address `0x8200A208` cited
|
||||
+/// in older audits. Per AUDIT-068 S3 measurement.
|
||||
+pub fn crowbar_force_spawn_workers(state: &mut KernelState, mem: &GuestMemory) -> u32 {
|
||||
+ // 0. Crowbar v2 Step 0 diagnostic — dump 256 bytes at the vtable base
|
||||
+ // BEFORE doing anything else. Distinguishes case (A) vtable .rdata
|
||||
+ // is missing/zero in ours vs case (B) .rdata present but vtable[35]
|
||||
+ // is not statically populated (= runtime install needed). Per
|
||||
+ // Reading-error #37: 0x8200A1E8 is vtable BASE; slot N is at base+4*N.
|
||||
+ // For workers we care about slots 35/36/37/38 (offsets 140/144/148/152).
|
||||
+ // Bump dump to 512 bytes (128 slots) so we see vtable[64] which is read
|
||||
+ // by the slot-35 callee `sub_82506B08` at +256.
|
||||
+ crowbar_dump_vtable_region(mem, CROWBAR_VTABLE_BASE, 512);
|
||||
+
|
||||
+ // 1. Allocate ctx struct (one heap page is plenty; the real struct is
|
||||
--
|
||||
+
|
||||
+ // 2c. Crowbar v3 Step 2 — full ctx-bytes install.
|
||||
+ // If the cvar `XENIA_CROWBAR_CTX_BIN=<path>` is set AND the file
|
||||
+ // exists, read up to 256 bytes from it and write them at ctx_ptr.
|
||||
+ // The file should be a raw guest-endian (big-endian) capture of the
|
||||
+ // ctx layout — see canary's `audit_68_host_mem_read_probe` cvar.
|
||||
+ // The v2 init at +0/+4/+8/+12 above is intentionally retained as a
|
||||
+ // fallback when the env var is unset; the file install overwrites
|
||||
+ // those four slots verbatim (the bytes match the v2 pattern).
|
||||
+ //
|
||||
+ // **Option γ (per v3 brief)**: canary-VA pointer fields like
|
||||
+ // `[ctx+44]=0xBCE25640` are written as-is even if unmapped in
|
||||
+ // ours — diagnostic intent is to OBSERVE the fault PC, not avoid
|
||||
+ // it.
|
||||
+ crowbar_maybe_install_ctx_from_file(mem, ctx_ptr);
|
||||
+
|
||||
+ // 3. Spawn the 4 workers suspended (matching canary jitter sample).
|
||||
+ let mut handles: [u32; 4] = [0; 4];
|
||||
+ let mut spawned = 0u32;
|
||||
+ for (i, entry) in CROWBAR_WORKER_ENTRIES.iter().enumerate() {
|
||||
+ if let Some(h) = crowbar_spawn_one_worker(state, mem, *entry, ctx_ptr) {
|
||||
+ handles[i] = h;
|
||||
+ spawned += 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // 4. Resume each spawned worker directly through the scheduler.
|
||||
Reference in New Issue
Block a user