summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 19:28:39 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 19:28:39 -0400
commit6c3fd5df61ff2f5cb8833ead6c05eaff9fdc92bf (patch)
tree3b3680902cd2223cbe60aaec0a0799cfc7b26be6 /debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md
parenta5473c91b8869b017385582ea969783b33553ded (diff)
downloadopen-iov-6c3fd5df61ff2f5cb8833ead6c05eaff9fdc92bf.tar.gz
open-iov-6c3fd5df61ff2f5cb8833ead6c05eaff9fdc92bf.zip
risc-v-gsp-rm-debugger: land docs 45-53 + harness/sim tool set with tests
rm_capture (chunked decode), launch_audit, state_seed/state_decode, valprobe, rehost, contracts+run_contracts, host_traffic, gmmu_walk, msgq_attach, libos_port, log_decode, server_snapshot; doc index updates in the tool overview, operations pages and the repo README.
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md')
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md179
1 files changed, 179 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md b/debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md
new file mode 100644
index 0000000..c412f21
--- /dev/null
+++ b/debug/risc-v-gsp-rm-vm/docs/48-GMMU-WALK-AND-LAUNCH-AUDIT.md
@@ -0,0 +1,179 @@
+# 48 — GMMU walk & launch memory-contract audit (in development)
+
+> **Status: in development (2026-10-06, engine-path wave).** Documents the
+> functional page-table walker (`sim/gmmu_walk.py`) and the launch
+> memory-contract auditor (`harness/launch_audit.py`). Together they answer,
+> offline and deterministically, *where the engine would read/write each
+> address of a submission* — the class of question behind "the front-end never
+> wrote the QMD" and "the release never fired".
+>
+> Development-only tooling: never a shipped component, never in a guest,
+> never touching hardware. Fidelity is the address view (L1); no timing or
+> engine-behaviour claim.
+>
+> **See also:** `43-GMMU-PTE-DECODER.md` (entry decoding), `42`/`44`
+> (observe-only GMMU/FBIF windows and the oracle workflow), `46`/`47`
+> (surgical rehost and predicate probes), `06-ACCURACY.md` (fidelity levels).
+
+## 1. What the two tools are
+
+* **Walker** (`sim.gmmu_walk`): given a page-directory base PA and a sparse
+ physical-memory view of the table pages, it follows VER2 entries through all
+ five levels and reports the leaf mapping — PA, page size, aperture,
+ writable/read-only — or the exact fault (`table_missing`,
+ `invalid_aperture`, `pte_invalid`, `unsupported`, `va_out_of_range`).
+ Every level's raw entry and decode is kept in the report.
+* **Auditor** (`harness/launch_audit.py`): takes a submission's **memory
+ contract** — the labelled VAs a launch requires (ring, inline-QMD
+ destination, parameter/program pages, release slot, report semaphore, ctx
+ buffers) — walks each leg, and classifies the result against what the host
+ believes:
+
+| verdict | meaning |
+|---|---|
+| `ok` | the engine can reach the leg with the required access |
+| `pa_mismatch` | the walk resolves to a different PA than the host's bookkeeping (the engine writes the shadow while you check the guest page, or vice versa) |
+| `unmapped` | no mapping/valid leaf: the engine's access is dropped or faults |
+| `access_denied` | the leaf is read-only for a write leg |
+
+Schemas: `greeneye-gmmu-walk/1`, `greeneye-launch-audit-spec/1`,
+`greeneye-launch-audit/1`, `greeneye-launch-audit-check/1`.
+
+```bash
+python3 -m sim.gmmu_walk demo # captured channel-PDB vector
+python3 -m sim.gmmu_walk run --pdb-pa 0x12f16e000 \
+ --va 0x100000 --mem 0x12f16e000=<hex> … # ad-hoc walk
+python3 harness/launch_audit.py demo # captured contract + fork classes
+python3 harness/launch_audit.py run --spec audit.json
+python3 harness/launch_audit.py check --spec partial.json # pages to dump next
+python3 harness/launch_audit.py capture-hints # exact live dump list + skeleton
+```
+
+## 2. Evidence and validation
+
+* Geometry, field positions and encodings come from the same evidence base as
+ the PTE decoder (`docs/43`); the walker composes the decoder rather than
+ re-implementing it.
+* The 4K and 2M paths are **validated against a live captured channel PDB**:
+ `sim.gmmu_walk demo` walks five VAs and must reproduce the DMA addresses the
+ capture logged (5/5, deterministic). The capture lives as numeric entries in
+ the module (`channel_pdb_fixture`).
+* The 64K dual path is **modelled** from the format definitions and reported
+ with `evidence: "modeled"` until a capture validates it. Video-memory leaf
+ addresses are reported with `pa_complete: false` (the decoder does not claim
+ the high bits there).
+* Unsupported encodings fail closed; an incomplete table view reports
+ `unmapped`, never "unreachable".
+
+## 3. Using it on the live launch wall
+
+`harness/launch_audit.py capture-hints` prints the capture recipe plus the
+exact page list and a copy-paste `greeneye-launch-audit-spec/1` skeleton for
+the current wall. In short: the channel's PDB base PA, a raw PA→bytes dump of
+the table pages reachable from it for the contract VAs, the submitted stream's
+pointers (GPFIFO ring, `SET_INLINE_QMD_ADDRESS_A/B` destination, QMD
+parameter/program/release-slot addresses, report semaphore), and the host's
+shadow bookkeeping for the same VAs. Put them in one spec and run the audit.
+
+### 3.1 `check` — iterate the capture with an empty or partial dump
+
+`check` runs the same walks but reports, per contract leg, the FIRST table
+page the `memory[]` view is missing — the page to dump next — with the
+level/index path that reached it, and a consolidated `needed_pages[]` list
+(sorted, de-duplicated, each entry naming the legs that need it). A leg whose
+walk faults on entries that are present (invalid aperture/PTE, unsupported
+encoding) is `fault` and needs no more pages; `complete` means every table
+page the walk needed is in the spec (not that any mapping is correct).
+
+Start with only `pdb_pa` + `contract` (empty `memory`) and let the tool drive
+one dump level per iteration; then run the verdict audit on the completed
+spec:
+
+```bash
+python3 harness/launch_audit.py check --spec m7-launch.json # -> needed_pages
+python3 harness/launch_audit.py check --spec m7-launch.json --out ./out
+python3 harness/launch_audit.py run --spec m7-launch.json
+```
+
+### 3.2 Current live wall dump list (m7 evidence, 2026-10-06)
+
+The m7 launch silence needs these raw pages (`capture-hints` prints the same
+list with the spec skeleton):
+
+* host-side chain (the validated 5/5 fixture): root `0x12f16e000`, pd2
+ `0x12f16f000`, pd1 `0x11065e000`, pd0 `0x110663000`, pt `0x15908d000`;
+* forward-window PT pages `0x1b8706000` (pdeIndex 4128) and `0x1197a6000`
+ (pdeIndex 4131); the geometry rule `pdeIndex = (pd1_idx << 8) | pd0_idx`
+ places the forward windows at pd1 index 16, and their pd1/pd0-level chain
+ entries are server-written (in no host log) — dump them too if they fall
+ outside the host pages above;
+* the 16 guest-scratch-PT page DMAs (`vaBase=0x200000`, capacity 512) — the
+ Tier-2 shadow legs resolve through them;
+* the `rmcall_gr_shadow` chunk DMAs — the engine-write shadow pages for the
+ high-VA legs.
+
+Contract VAs: QMD destination `0x204608000` (write), release slot
+`0x204027f7c` (write), low-window ring/push-buffer legs `0x100000..0x104000`,
+and the high-VA param/program legs, which are NOT directly mapped — they
+resolve through the shadow aliases (`0x210000`/`0x220000`/`0x260000`) whose
+PTEs come from the guest scratch pool.
+
+Reading the result:
+
+* `pa_mismatch` on the inline-QMD destination or the release slot means the
+ engine operates on a different PA than the one the post-mortem checks — fix
+ the bookkeeping/observation point, not the engine path.
+* `unmapped` means the engine's access is dropped at translation; the fault
+ names the exact missing level/table — `check` names the page to dump.
+* all-`ok` with a silent launch means the address path is complete: the
+ silence is downstream (front-end/engine/context), and the next suspect is
+ the context program itself (see docs/46/47 for the commit-gate probes).
+
+### 3.3 Demo scenarios and expected verdicts (pinned by tests)
+
+`demo` audits the fork classes and prints every verdict:
+
+| scenario | mapping (VA → PA) | host bookkeeping | expected verdict |
+|---|---|---|---|
+| captured channel contract | 5 low-window legs (validated fixture) | matches capture | all `ok` |
+| `qmd-dest-shadow-trusted` | 0x204608000 → shadow 0x15e8fa000 | shadow PA | `ok` |
+| `qmd-dest-host-checks-guest` | 0x204608000 → shadow | guest page 0x204608000 | `pa_mismatch` |
+| `qmd-dest-unmapped` | 0x204608000 → unmapped | n/a | `unmapped` |
+| `engine-write-shadow-host-checks-guest` | alias 0x210000 → shadow PA | guest PA | `pa_mismatch` |
+| `engine-write-shadow-bookkeeping-aligned` | alias 0x210000 → shadow PA | shadow PA | `ok` |
+
+The last two are the next wall class after dispatch clears: CUDA output
+buffers at high VAs, where Tier-1 is refused (0x1f) and the leg resolves
+through the guest scratch PT pool to a shadow page. The shadow/guest PAs in
+the demo are synthetic (documented in the `run_demo` docstring), not m7
+captures.
+
+## 4. Reuse across firmware/driver version upgrades
+
+Both tools are data-driven and fail closed; nothing about them encodes a
+specific firmware version except the entry-encoding family:
+
+1. On a new version, re-run `python3 -m sim.gmmu_walk demo` and the test
+ module. If the encoding family changed, the walker refuses with
+ `unsupported` rather than guessing.
+2. Extend the evidence base (decoder field tables/encoders) and the LEVELS
+ geometry in one place (`sim/gmmu_pte.py` / `sim/gmmu_walk.py`), add one
+ captured golden vector per new format, and pin it in tests.
+3. Keep `firmware`/`gmmu` fields in audit specs so reports are self-describing
+ across versions; the audit refuses an unknown `gmmu` kind.
+4. Re-capture the contract data from the new version (the capture recipe is
+ version-independent) and re-run; compare the two audit reports for
+ behaviour drift.
+
+## 5. Tests
+
+`tests/test_gmmu_walk.py` (15) and `tests/test_launch_audit.py` (20):
+captured golden vector, synthetic round-trips, 2M/64K paths, all fault
+classes, read-only leaves, mismatch/unmapped/access-denied verdicts,
+check-mode page needs (empty memory, partial memory, complete+fault legs,
+needed-pages dedup/ordering, CLI exit codes/artifact), engine-write shadow
+demo verdicts, determinism, spec errors and CLI exit codes.
+
+```bash
+python3 -m unittest tests.test_gmmu_walk tests.test_launch_audit -v
+```