From 1c99bfbeffff04529f6f669601fdf835a73778da Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 2 Oct 2026 11:44:31 -0400 Subject: rename (cosmetic): green-eye -> risc-v-gsp-rm-debugger in user-facing names, docs, CLI, launcher and CI workflow; internal greeneye package/module identifiers unchanged (includes in-flight greeneye module edits present in the tree) --- .../02-debugging-and-maintenance-workflows.md | 20 +- docs/05-operations/03-risc-v-gsp-rm-vm.md | 24 +- docs/05-operations/04-green-eye-user-guide.md | 439 --------------------- .../04-risc-v-gsp-rm-debugger-user-guide.md | 439 +++++++++++++++++++++ 4 files changed, 461 insertions(+), 461 deletions(-) delete mode 100644 docs/05-operations/04-green-eye-user-guide.md create mode 100644 docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md (limited to 'docs/05-operations') diff --git a/docs/05-operations/02-debugging-and-maintenance-workflows.md b/docs/05-operations/02-debugging-and-maintenance-workflows.md index cfc452d..975b3dc 100644 --- a/docs/05-operations/02-debugging-and-maintenance-workflows.md +++ b/docs/05-operations/02-debugging-and-maintenance-workflows.md @@ -192,13 +192,13 @@ Watch the serial log afterwards for backtraces. A truly hard-wedged vCPU (spinning on a faulting MMIO instruction) may print nothing — use the gdbstub instead. -### 3.9 Firmware runtime analysis — green-eye (experimental) +### 3.9 Firmware runtime analysis — risc-v-gsp-rm-debugger (experimental) > **# TOOL IN DEVELOPMENT - NOT READY YET!** For firmware-side questions (what does the GSP/uproc server do at runtime, what does it read/write, how do its state machines evolve), the experimental -green-eye tooling runs uproc/GSP firmware in a `qemu-system-riscv64` VM with +risc-v-gsp-rm-debugger tooling runs uproc/GSP firmware in a `qemu-system-riscv64` VM with hooks, watchpoints, memory dumps and session recording, without a physical GPU, WPR2 risk or a reboot. See [`03-risc-v-gsp-rm-vm.md`](03-risc-v-gsp-rm-vm.md) for purpose, status and @@ -322,13 +322,13 @@ version × each hardware family, run the step-5 bring-up sequence. When adding a version, extend the matrix rather than replacing the old column — regressions across versions are the cheapest bugs to catch. -### 4.1.1 Green-eye-assisted upgrade/porting workflow (experimental) +### 4.1.1 Risc-V GSP-RM debugger-assisted upgrade/porting workflow (experimental) - +the new RUNBOOK and risc-v-gsp-rm-debugger user guide; additive only. --> -For firmware-side questions the experimental green-eye tooling (see +For firmware-side questions the experimental risc-v-gsp-rm-debugger tooling (see [`03-risc-v-gsp-rm-vm.md`](03-risc-v-gsp-rm-vm.md)) turns steps 3–5 above into a repeatable pipeline that produces attachable evidence before any emulation change. It never replaces the physical backend when silicon truth is required, @@ -336,11 +336,11 @@ and it never touches a guest, a kernel module or the installed driver. | Rung | Command (from `debug/risc-v-gsp-rm-vm/`) | Output | |---|---|---| -| Probe | `./greeneye.sh probe --symbols symbols-.json --record` | first-divergence report; first-touch map | -| Symbols | `./greeneye.sh symbols export --index --bias 0 -o symbols-.json` | runtime-address symbol DB with provenance | +| Probe | `./risc-v-gsp-rm-debugger.sh probe --symbols symbols-.json --record` | first-divergence report; first-touch map | +| Symbols | `./risc-v-gsp-rm-debugger.sh symbols export --index --bias 0 -o symbols-.json` | runtime-address symbol DB with provenance | | Version diff | `python3 harness/version_diff.py --old --new --out dumps/vdiff-` | shape/symbol/corpus/probe/behavior diff plus the M1–M6 skeleton | | Portability matrix | `python3 harness/portability_matrix.py --target --target --out dumps/matrix-` | per-target sessions and per-pair `compare` reports | -| Decide | `./greeneye.sh compare dumps/ dumps/ --symbols` | symbol-attributed deltas; a product change only after physical confirmation | +| Decide | `./risc-v-gsp-rm-debugger.sh compare dumps/ dumps/ --symbols` | symbol-attributed deltas; a product change only after physical confirmation | Decision discipline: verify the pairing first; behaviour that moved without a code change is usually a state/ordering fix; changed code on a live path is @@ -348,7 +348,7 @@ prioritised; a symbol never hit in either run is a coverage gap, not dead code. The full incident procedures (symptoms, evidence, response order, rollback) are in the [Open-IOV Defensive Operations Runbook](../RUNBOOK.md) S1 and its OODA ordering; the quickstart and tool chooser are in the -[green-eye user guide](04-green-eye-user-guide.md). +[risc-v-gsp-rm-debugger user guide](04-risc-v-gsp-rm-debugger-user-guide.md). ### 4.2 New guest driver version diff --git a/docs/05-operations/03-risc-v-gsp-rm-vm.md b/docs/05-operations/03-risc-v-gsp-rm-vm.md index c21124b..773006d 100644 --- a/docs/05-operations/03-risc-v-gsp-rm-vm.md +++ b/docs/05-operations/03-risc-v-gsp-rm-vm.md @@ -1,4 +1,4 @@ -# GSP in a RISC-V VM — green-eye (experimental) +# GSP in a RISC-V VM — risc-v-gsp-rm-debugger (experimental) > **# TOOL IN DEVELOPMENT - NOT READY YET!** > This is experimental developer tooling. It is not part of the shipped @@ -10,7 +10,7 @@ ## 1. What it is -**green-eye** runs GSP/uproc firmware in a `qemu-system-riscv64` VM and makes +**risc-v-gsp-rm-debugger** runs GSP/uproc firmware in a `qemu-system-riscv64` VM and makes its runtime behaviour inspectable with Frida-like primitives: * breakpoints and enter/leave hooks (RV64 ABI aware), @@ -48,7 +48,7 @@ accuracy, portability playbooks, roadmap) is under * **Not a timing model.** Do not infer latency or concurrency behaviour from it; its in-scope conclusions are execution flow and memory side effects. * **Not a replacement for Ghidra or the guest diagnostics.** Ghidra answers - *what is the code*; green-eye answers *what did it do*. The guest driver + *what is the code*; risc-v-gsp-rm-debugger answers *what did it do*. The guest driver remains the oracle for guest-side behaviour. ## 3. Where it fits @@ -58,10 +58,10 @@ accuracy, portability playbooks, roadmap) is under | Static | Ghidra corpus (`userspace/cuda`, `tools/ghidra`) | what is the code? | | Guest driver | `tools/guest-diag/`, ptrace tracer | what did the driver request? | | Physical backend | supervised physical cycles, module logs | what did real silicon/the real GSP-RM do? | -| **Firmware runtime (this)** | **green-eye** | **what does the firmware server do, repeatably and safely?** | +| **Firmware runtime (this)** | **risc-v-gsp-rm-debugger** | **what does the firmware server do, repeatably and safely?** | The intended measurement loop is: capture the real backend's RPC behaviour, -run the same stimulus in green-eye, and compare the recorded sessions +run the same stimulus in risc-v-gsp-rm-debugger, and compare the recorded sessions (`greeneye compare`) with the accuracy metrics defined in the tool's `docs/06-ACCURACY.md`. Portability runs (new GSP, new device, GB10-class architecture) are described in `docs/07-PORTABILITY-PLAYBOOKS.md`. @@ -72,13 +72,13 @@ From the repository root: ```bash cd debug/risc-v-gsp-rm-vm -./greeneye.sh info # environment check (QEMU, toolchain) +./risc-v-gsp-rm-debugger.sh info # environment check (QEMU, toolchain) make demo sdk # build the demo uproc and the injection SDK -./greeneye.sh demo # canned instrumentation pass; records a session -./greeneye.sh analyze dumps/ -./greeneye.sh probe # real GSP image: report the first divergence -./greeneye.sh inject # load and invoke an injected service -./greeneye.sh ghidra # serve the session to GhidraScripts +./risc-v-gsp-rm-debugger.sh demo # canned instrumentation pass; records a session +./risc-v-gsp-rm-debugger.sh analyze dumps/ +./risc-v-gsp-rm-debugger.sh probe # real GSP image: report the first divergence +./risc-v-gsp-rm-debugger.sh inject # load and invoke an injected service +./risc-v-gsp-rm-debugger.sh ghidra # serve the session to GhidraScripts ``` Requirements: `qemu-system-riscv64` (Ubuntu `qemu-system-misc`), Python 3.10+ @@ -96,7 +96,7 @@ real-firmware first-fault probe, and the TCG full-memory trace plugin. Not implemented: device model (R1), custom simulator (R2), MCP plugin (R3) — all roadmap. The long-term program (adversarial navigation, adjacent microcontrollers, custom simulator, Verilog soft-core, agentic platform) is -documented in `debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md`. +documented in `debug/risc-v-gsp-rm-vm/RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`. ## 6. When the development flag can be removed diff --git a/docs/05-operations/04-green-eye-user-guide.md b/docs/05-operations/04-green-eye-user-guide.md deleted file mode 100644 index a9bf1dc..0000000 --- a/docs/05-operations/04-green-eye-user-guide.md +++ /dev/null @@ -1,439 +0,0 @@ -# green-eye User Guide (experimental) - -> **# TOOL IN DEVELOPMENT - NOT READY YET!** -> green-eye is the development environment for running GSP/uproc firmware -> off-hardware, observing it, injecting into it and comparing runs as evidence. -> It is never shipped, never a driver dependency and never present in a guest; -> interfaces and file formats may change without notice. For incident response -> procedures see the [Open-IOV Defensive Operations Runbook](../RUNBOOK.md). - -This guide is the single front door for a new user: what green-eye is, how to -get a first recorded run in ten minutes, which tool to use for which task, how -to treat sessions as evidence, and what to do when something is wrong. The -authoritative details live in the tool's own documentation set -([documentation map](#10-documentation-map)). - -## 1. What green-eye is - -green-eye runs GSP/uproc firmware in a controllable machine, instruments it -with Frida-like primitives, records a durable session, changes the machine's -inputs (including injected code), and compares runs so that emulation changes -in `open-iov-vfio` land with evidence instead of anecdotes. - -| It is | It is not | -|---|---| -| A firmware runtime microscope (execution + memory: L0/L1) | A timing, interrupt or device model (L2/L3 absent) | -| A scriptable `Session` API with two backends (QEMU-RSP and native) | A GDB wrapper; there is no GDB dependency | -| A recorded-evidence system with a versioned session format | A product component, a guest agent or a shipped dependency | -| A static/dynamic join for Ghidra | A decompiler or a CUDA-corpus replacement | -| An automation layer (harnesses, MCP, CI) | A fuzzing service against hardware; simulator/re-hosted code only | - -Ghidra answers *what is the code*; green-eye answers *what did it do*. Guest -diagnostics answer *what did the driver request*; a supervised physical cycle -answers *what does silicon do*. green-eye makes the middle question repeatable -and safe. - -## 2. Ten-minute quickstart - -Requirements: Linux, Python 3.10+ (stdlib only), `qemu-system-riscv64` -(Ubuntu `qemu-system-misc`), `clang` and `lld`. No GPU, no driver and no -kernel module are touched. - -```bash -cd open-iov/debug/risc-v-gsp-rm-vm - -./greeneye.sh info # environment check: QEMU, toolchain, paths -make demo && make sdk # build the bundled RV64 uproc demo and injection SDK - -./greeneye.sh demo # canned run: boot, hooks, watchpoints, session -./greeneye.sh analyze dumps/ - -./greeneye.sh probe # real GSP image: report the first divergence -./greeneye.sh inject # load and invoke a position-independent service -``` - -What "good" looks like: - -1. `info` reports QEMU and the demo paths; -2. `demo` prints hook/branch lines and a session directory under `dumps/`; -3. `analyze` renders hook/watch/breakpoint events and a coherent summary; -4. `probe` reports a bounded first divergence (for the TU104 570.144 image, a - load-access fault at firmware vaddr `0x4009014` reading - `0x2000000000000A00`) — that is expected data, not a boot; -5. `inject` returns matching values on the direct and firmware-dispatched - paths. - -Next steps: [choose a tool](#5-choosing-the-right-tool) for your task and read -[Common recipes](#7-common-recipes). - -## 3. Mental model - -### 3.1 Two backends, one session API - -```text -CLI / REPL / Python ─┐ -MCP (stdio) ────────┼─► GreenEyeAPI ─► Session ─┬─► QEMU-RSP backend (qemu-system-riscv64) -Ghidra bridge ──────┤ hooks, watchpoints, └─► native backend (sim/machine.py) -harness/ + rmharness┘ memory, symbols, recorder ──► session directory -``` - -* **QEMU-RSP** is the default: full RV64 execution, gdbstub transport without - GDB, TCG trace plugin optional. -* **native** (`--backend native`) is the in-process interpreter: deterministic - virtual time (instruction counts), fast startup, an exec/access trace, and - lenient MMIO for first-touch exploration. -* Both satisfy the same `Session` primitives (registers/memory, breakpoints, - watchpoints, step/continue, snapshots), so scripts, probes, plugins, - recordings and comparisons survive a backend change. - -### 3.2 The primitives - -| Primitive | Use it for | -|---|---| -| `breakpoint` / `hook` | did this function run? with what arguments and return value? | -| `watch` (`w`/`r`/`a`) | when did this field change, from which store PC? | -| `run` / `run_until` | bounded observation; stop at a chosen address | -| `call` | Frida-like remote call to unit-test a function in isolation | -| `step` / `note` | single-step with dispatch; annotate the event stream | -| `Memory.read/write/hexdump/search/snapshot/diff` | inspect and diff memory regions | -| `SymbolDB` | resolve file/program/runtime addresses across sources | -| `Recorder` | write the durable session (events, snapshots, blobs) | -| injection SDK | load, register and invoke your own PIC RV64 service | - -Instructions between stops are invisible unless a trace is on: the TCG plugin -(`-plugin qemu/greeneye-trace.so`) on QEMU, or `--trace` on the native backend. - -### 3.3 Fidelity levels (what a result can mean) - -| Level | Property | green-eye today | -|---|---|---| -| **L0** | instruction semantics | high (QEMU TCG, same ISA family) | -| **L1** | memory behaviour | high for RAM-resident code, conditional on mapping | -| **L2** | time/concurrency | **not modelled** (do not claim) | -| **L3** | device environment (falcon, WPR2, CSB, PMU, timers, DMA, IRQ) | **absent** (device model is roadmap) | - -A simulator observation is evidence about the firmware, not about silicon; -anything that would change the product is reproduced on a physical/vfio-mdev -reference first. Never quote a green-eye session for timing, interrupt or -security claims. - -### 3.4 A session is the unit of work - -Every run records a `greeneye-session/1` directory: - -```text -dumps/-/ - session.json format, name, counts, snapshot inventory, meta - events.jsonl append-only event stream (hooks, watches, memory, notes) - snapshots/*.bin.z zlib-compressed region captures with sha256 - blobs/* QEMU logs, trace.jsonl, host-oracle stdout - summary.md rendered analysis -``` - -Partial sessions stay readable; the format evolves additively. A copied -`events.jsonl` without its `session.json`, snapshots and metadata is not -evidence. - -## 4. Tool inventory - -Run everything from `open-iov/debug/risc-v-gsp-rm-vm/` unless stated. - -### 4.1 CLI (`./greeneye.sh`) - -| Command | One-line purpose | -|---|---| -| `info` | environment/tooling check (QEMU, paths, capabilities) | -| `demo` | canned boot + hooks + watchpoints + recording on the bundled uproc | -| `run ` | run a Python instrumentation session against the demo/ELF | -| `attach` / `launch` | interactive REPL; keep a target alive and print its gdbstub port | -| `record` | boot and record with watches/snapshots (and `--trace` on native) | -| `probe ` | bounded run of a raw image; first-divergence report | -| `analyze ` | session to symbol-annotated Markdown report | -| `compare ` | symbolic A/B delta of two recorded sessions | -| `symbols export\|resolve` | build/inspect a runtime-address symbol DB | -| `inject` | load, register and invoke an SDK service (direct + mailbox) | -| `ghidra` | serve the live session to GhidraScripts over localhost | -| `plugins` | list discoverable plugins | - -### 4.2 Harnesses (`harness/`) - -| Tool | One-line purpose | -|---|---| -| `portability_matrix.py` | probe + fixed scenario + compare across targets, with an M1–M6 skeleton | -| `mutation_harness.py` | seeded one-input mutations with outcome classes and per-attempt sessions | -| `control_discovery.py` | sweep a call surface to find known/unknown/injected handler IDs | -| `reach.py` | is one symbol reachable, what triggers it, with what arguments and effects | -| `version_diff.py` | old vs new image: shape, symbols, corpus hints, probe, behavior | -| `ci_release.py` | version_diff → matrix → mutation smoke, hashed into one bundle | -| `port_driver_versions.py`, `port_new_device.py`, `package_sim.py` | porting/packaging scaffolds (dry-run default; pilot status and evaluation in [docs/28](../../debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md), [docs/29](../../debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md)) | -| `value_demos/run_all.py` | ten fixed scenarios s01–s10 with measured time-to-value | -| `common.py` | shared helpers (flat relocation, sessions, bounded log reads) | - -### 4.3 Native simulator, plugins, host oracle, bridges - -| Tool | One-line purpose | -|---|---| -| `sim/` (`--backend native`, `--trace`) | deterministic RV64IMAC interpreter with exec/access trace and lenient MMIO | -| `python3 -m greeneye.device_map harvest\|show\|merge\|demo` | first-touch MMIO map: authoring, inspection, merge | -| `qemu/greeneye_trace.c` (`make -C qemu`) | full TCG exec/access JSONL trace with `start=`/`end=` filters | -| `plugins/example_plugin.py` | plugin authoring reference | -| `plugins/mcp_server.py` | MCP server for agents (stdio or loopback; read-only by default) | -| `plugins/rmharness_plugin.py` | REPL commands for the host RM oracle | -| `rmharness/harness.sh` + `rmtool`/`rmtop`/`rmq` | read-only host oracle captures appended into a session | -| `ghidra/ExportForGreenEye.java`, `MarkGreenEyeHits.java`, `GreenEyeControl.java` | symbol export, hit annotation and decompiler-driven execution | -| `sdk/` + `greeneye inject` | position-independent service ABI v1 | - -## 5. Choosing the right tool - -| Task | Tool | Notes | -|---|---|---| -| "Does this run?" / first divergence of a raw image | `./greeneye.sh probe` | no device model: expected early fault is data | -| "What does this firmware do on this stimulus?" | `record` / `run` + `analyze` | fixed stimulus, bounded budgets, hooks/watchpoints | -| "Which command IDs exist / what is undiscovered?" | `harness/control_discovery.py` | fresh session per probe; deterministic seed | -| "Is this function reachable, and how?" | `harness/reach.py` | `auto|stimulus|trigger|run|call`; emits a replayable probe spec | -| "What changed between two firmware versions?" | `harness/version_diff.py`, `./greeneye.sh compare` | static inventory + dynamic profile | -| "Does the new firmware move behaviour or code?" | `harness/version_diff.py` + docs/14 decision table | code vs behaviour classification | -| "Prove an error path / fail-closed rule" | `harness/mutation_harness.py` | simulator only; seeded and replayable | -| "Prototype an RM service before product code" | `sdk/` + `./greeneye.sh inject` | PIC blob; direct and mailbox paths | -| "Join Ghidra static addresses to runtime hits" | `./greeneye.sh ghidra` + Java bridges | localhost only; no auth | -| "What does a control reply look like on real RM?" | `rmharness/harness.sh … rmtool` | read-only host oracle; safe beside a CUDA job | -| "Explore MMIO the firmware touches first" | `probe` → `python3 -m greeneye.device_map` | versioned JSON; feeds the device model | -| "Triage a release end to end" | `harness/ci_release.py` | always `--dry-run` first | -| "Let an agent monitor a run" | `plugins/mcp_server.py` | read/observe by default; writes gated | - -Decision rule: static reading is a hypothesis; a recorded session is evidence; -at least an A/B pair is a conclusion. - -## 6. Sessions as evidence - -1. **Record with a fixed stimulus.** The same script, seed, budgets and image - hash make runs comparable; a self-comparison must be empty. -2. **Annotate as you go.** `s.note(...)` inside the session explains what was - asked and what was mutated; a chat log is not evidence. -3. **Attach the provenance.** Firmware SHA-256, version string, pairing notes, - symbol DB source/hash/bias, and the exact command or script. -4. **Keep the directory together.** `session.json` + `events.jsonl` + - `snapshots/` + blobs are one artifact; publish a SHA-256 list when moving - it. -5. **State the fidelity.** L0/L1 exercised; L2/L3 not claimed; reference - capture named (hardware, vfio-mdev, host oracle or none). -6. **Report deltas honestly.** `compare` marks non-semantic fields (time, host - paths, backend identity) as such; every remaining delta is explained or - listed as open. An empty unexplained-delta list is a claim that must be - earned. -7. **Bundle for triage.** A release bundle is - `bundle-manifest.json` + `release-report.json` + version-diff + portability - matrix + mutation smoke; see - [docs/21](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) §4.3. - -The M1–M6 metric contract (inventory, reply, ordering, state, error-path and -memory-side-effect agreement) is defined in -[docs/06-ACCURACY](../../debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md) §5 and is -authoritative for every claim. - -## 7. Common recipes - -### 7.1 First record and analyze - -```bash -cd debug/risc-v-gsp-rm-vm -make demo -./greeneye.sh demo # prints the session directory -./greeneye.sh analyze dumps/ # symbol-annotated report -``` - -### 7.2 Probe a new firmware image - -```bash -./greeneye.sh symbols export --index --bias 0 -o symbols-.json -./greeneye.sh probe .fwimage.bin> --symbols symbols-.json --record -python3 harness/version_diff.py --old --new --out dumps/vdiff- \ - --old-symbols symbols-.json --new-symbols symbols-.json -``` - -### 7.3 Discover controls and prove reachability - -```bash -python3 harness/control_discovery.py --out dumps/discovery --max-id 32 \ - --patterns zero --seed 5 -python3 harness/reach.py --target rpc_ping --method call --args 0x41 \ - --out dumps/reach-ping -``` - -### 7.4 Mutate an input surface (simulator only) - -```bash -python3 harness/mutation_harness.py --out dumps/mutation-7 \ - --iterations 64 --seed 7 --timeout 0.25 --settle 0.2 -``` - -### 7.5 Portability pipeline across targets - -```bash -python3 harness/portability_matrix.py \ - --target --target \ - --out dumps/matrix-candidate --probe-instructions 200 --scenario-duration 0.2 -``` - -### 7.6 Inject and debug a service - -```bash -make -C sdk -make -C sdk relocs -./greeneye.sh inject --service sdk/build/injected_demo.elf --cmd 1 --arg0 0x41 --arg1 0x42 -``` - -The direct call is the unit test; the mailbox call is the integration test. -Both are recorded. - -### 7.7 Drive execution from Ghidra - -```bash -# terminal 1 -./greeneye.sh ghidra --kernel --bridge-port 7000 -# terminal 2 (Ghidra headless) -$GHIDRA/support/analyzeHeadless -process -noanalysis \ - -scriptPath open-iov/debug/risc-v-gsp-rm-vm/ghidra \ - -postScript GreenEyeControl.java 7000 0x
-``` - -### 7.8 Host oracle capture (read-only) - -```bash -./rmharness/harness.sh --session dumps/real- --name before \ - -- rmtool engine list --format=json -./rmharness/harness.sh --session dumps/real- -- rmtop --once -``` - -### 7.9 Release rehearsal - -```bash -python3 harness/ci_release.py --old --new --out dumps/release- \ - --old-label --new-label --dry-run -``` - -`--dry-run` prints the plan and creates nothing; the RM 610 gate refuses 610 -labels (exit 3) until a human approves in writing. - -### 7.10 Let an agent monitor - -```bash -python3 plugins/mcp_server.py --stdio --backend native --record -# read/observe by default; --allow-write and --allow-inject are explicit opt-ins -``` - -### 7.11 First-touch device map - -```bash -./greeneye.sh probe --record -python3 -m greeneye.device_map harvest dumps/ --out dumps/-device-map.json -python3 -m greeneye.device_map show dumps/-device-map.json -``` - -## 8. Troubleshooting - -| Symptom | Likely cause | Fix | -|---|---|---| -| `qemu-system-riscv64 not found` | QEMU absent or not on `PATH` | install `qemu-system-misc` or point `GREENEYE_QEMU` at the binary | -| QEMU starts but the script cannot attach | wrong port / target exited | use the port `launch`/`demo` printed; re-run `launch` and `attach --port ` | -| `Address already in use` on a bridge/trace port | stale bridge or another session | choose another `--bridge-port`; check `pgrep -fa greeneye` and `pgrep -fa qemu-system-riscv64` | -| QEMU survives Ctrl-C of a script | `launch` keeps the target alive by design | close the session or stop the reported PID; do not kill an unrelated QEMU | -| Session analyzer shows no hits/events | recording off, or the stimulus never ran | use the CLI (records by default); check hooks/watchpoints with a known symbol (`rpc_sum`) | -| `NameError: __file__` in `run` scripts | script invoked outside `greeneye.sh run` | run through `./greeneye.sh run`, keep scripts inside the tool tree | -| Empty TCG trace blob | plugin window missed or target never resumed | `make -C qemu`; widen `start=`/`end=`, set `exec=on`, resume the target | -| MCP writes refused / no tools | server read-only by default; stdout polluted | pass `--allow-write`/`--allow-inject` deliberately; keep stdout protocol-only | -| `greeneye error:` on a valid path | wrong relative path or `--db` file | `./greeneye.sh info` shows resolved paths; bad symbol DBs fail with a clear error | -| Harness findings not reproducible | seed/budget changed | pin `--seed` and budgets; compare `findings.jsonl` byte-for-byte | -| Everything "unreachable" | wrong surface/timeouts | run `--surface demo` on the built demo first; raise `--settle`/`--timeout` | -| `Unknown symbol` in the optional OpenRM build | module-tag drift | re-pin build glue; see the [RUNBOOK](../RUNBOOK.md) S2 | - -Marker status: every tool document carries the -**# TOOL IN DEVELOPMENT - NOT READY YET!** banner. The marker is removed only -when the acceptance list in -[docs/00-OVERVIEW](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md) passes on a -clean checkout, the usage recipes verify end-to-end, a second person can run -the quickstart unaided, and the session format and CLI are declared stable. - -## 9. Safety - -* **Simulator only.** The tools launch their own QEMU or native machine - against the bundled demo or an explicitly allowed re-hosted ELF. They never - attach to hardware, a guest, a kernel module, an mdev or an existing - gdbstub. -* **No guest, no hardware, no product.** Nothing runs in a guest; injected - services are prototypes, not shipped code; product changes go through - `open-iov-vfio` with physical confirmation. -* **Read by default; writes gated.** MCP `write_mem`/`call_function` need - `--allow-write`, injection needs `--allow-inject`, and every write is - recorded in the session. -* **Bounded everywhere.** Runs have durations/stop caps; reads and snapshots - have size caps; harness subprocesses have timeouts; a wedged target is left - stopped and restarted clean rather than poked. -* **Local only.** Ghidra and MCP transports are localhost/stdio; the bridge is - unauthenticated by design, so never expose it on a network interface. -* **No confidentiality claims.** The simulator is a study environment, never a - security or confidentiality boundary; never use injection to defeat a - hardware security boundary. -* **Fuzzing is gated.** Mutation runs only against the simulator or re-hosted - code, behind explicit harnesses, with recorded evidence. -* **RM 610 is a hard human gate.** No acquisition, analysis, emulation edit, - physical work or support claim before written approval; the gate is enforced - by the CLIs. - -## 10. Documentation map - -Tool documentation (`debug/risc-v-gsp-rm-vm/docs/`): [00 overview](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md), -[01 design](../../debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md), -[02 usage](../../debug/risc-v-gsp-rm-vm/docs/02-USAGE.md), -[03 scripting](../../debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md), -[04 plugins](../../debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md), -[05 Ghidra bridge](../../debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md), -[06 accuracy](../../debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md), -[07 portability playbooks](../../debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md), -[08 roadmap](../../debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md), -[09 firmware notes](../../debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md), -[10 related work](../../debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md), -[11 RM service guide](../../debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md), -[12 injection SDK](../../debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md), -[13 Ghidra control](../../debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md), -[14 adversarial interop](../../debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md), -[15 agentic GSP IDE](../../debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md), -[16 custom simulator](../../debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md), -[17 RM harness](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md), -[18 harness automation](../../debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md), -[19 control discovery](../../debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md), -[20 MCP server](../../debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md), -[21 CI/release pipeline](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md), -[22 porting CUDA and devices](../../debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md), -[23 RM 610 readiness](../../debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md), -[24 device map](../../debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md), -[25 value validation](../../debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md), -[26 architecture](../../debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md), -[27 tool audit](../../debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md), -[28 porting automation](../../debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md), -[29 packaging and trialing](../../debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md), and the -[long-term roadmap](../../debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md). - -Project documentation: - -* [Open-IOV Defensive Operations Runbook](../RUNBOOK.md) — incident scenarios - S1–S10, evidence bundles, escalation tree; -* [GSP in a RISC-V VM](03-risc-v-gsp-rm-vm.md) — project-level purpose, status - and limits; -* [Debugging and maintenance workflows](02-debugging-and-maintenance-workflows.md) - — captures, failure taxonomy and the upgrade runbook; -* [Hardware and software matrix](../06-portability/hardware-software-matrix.md) - — support ladder and the portability pipeline; -* [Adversarial interoperability](../04-implementation/02-practical-challenges-and-adversarial-interop.md) - — the no-patch rule; -* [Engineering operations](../eng-ops.md) — tool admission, workflows and - retirement (the cross-cutting engineering-operations document); -* CUDA playbook: - [`userspace/cuda/docs/07-version-upgrade-playbook.md`](../../userspace/cuda/docs/07-version-upgrade-playbook.md) - and [`userspace/cuda/READ-ME-FIRST.md`](../../userspace/cuda/READ-ME-FIRST.md); -* [Documentation front door](../README.md) — the full reading order. - - diff --git a/docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md b/docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md new file mode 100644 index 0000000..f12230a --- /dev/null +++ b/docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md @@ -0,0 +1,439 @@ +# risc-v-gsp-rm-debugger User Guide (experimental) + +> **# TOOL IN DEVELOPMENT - NOT READY YET!** +> risc-v-gsp-rm-debugger is the development environment for running GSP/uproc firmware +> off-hardware, observing it, injecting into it and comparing runs as evidence. +> It is never shipped, never a driver dependency and never present in a guest; +> interfaces and file formats may change without notice. For incident response +> procedures see the [Open-IOV Defensive Operations Runbook](../RUNBOOK.md). + +This guide is the single front door for a new user: what risc-v-gsp-rm-debugger is, how to +get a first recorded run in ten minutes, which tool to use for which task, how +to treat sessions as evidence, and what to do when something is wrong. The +authoritative details live in the tool's own documentation set +([documentation map](#10-documentation-map)). + +## 1. What risc-v-gsp-rm-debugger is + +risc-v-gsp-rm-debugger runs GSP/uproc firmware in a controllable machine, instruments it +with Frida-like primitives, records a durable session, changes the machine's +inputs (including injected code), and compares runs so that emulation changes +in `open-iov-vfio` land with evidence instead of anecdotes. + +| It is | It is not | +|---|---| +| A firmware runtime microscope (execution + memory: L0/L1) | A timing, interrupt or device model (L2/L3 absent) | +| A scriptable `Session` API with two backends (QEMU-RSP and native) | A GDB wrapper; there is no GDB dependency | +| A recorded-evidence system with a versioned session format | A product component, a guest agent or a shipped dependency | +| A static/dynamic join for Ghidra | A decompiler or a CUDA-corpus replacement | +| An automation layer (harnesses, MCP, CI) | A fuzzing service against hardware; simulator/re-hosted code only | + +Ghidra answers *what is the code*; risc-v-gsp-rm-debugger answers *what did it do*. Guest +diagnostics answer *what did the driver request*; a supervised physical cycle +answers *what does silicon do*. risc-v-gsp-rm-debugger makes the middle question repeatable +and safe. + +## 2. Ten-minute quickstart + +Requirements: Linux, Python 3.10+ (stdlib only), `qemu-system-riscv64` +(Ubuntu `qemu-system-misc`), `clang` and `lld`. No GPU, no driver and no +kernel module are touched. + +```bash +cd open-iov/debug/risc-v-gsp-rm-vm + +./risc-v-gsp-rm-debugger.sh info # environment check: QEMU, toolchain, paths +make demo && make sdk # build the bundled RV64 uproc demo and injection SDK + +./risc-v-gsp-rm-debugger.sh demo # canned run: boot, hooks, watchpoints, session +./risc-v-gsp-rm-debugger.sh analyze dumps/ + +./risc-v-gsp-rm-debugger.sh probe # real GSP image: report the first divergence +./risc-v-gsp-rm-debugger.sh inject # load and invoke a position-independent service +``` + +What "good" looks like: + +1. `info` reports QEMU and the demo paths; +2. `demo` prints hook/branch lines and a session directory under `dumps/`; +3. `analyze` renders hook/watch/breakpoint events and a coherent summary; +4. `probe` reports a bounded first divergence (for the TU104 570.144 image, a + load-access fault at firmware vaddr `0x4009014` reading + `0x2000000000000A00`) — that is expected data, not a boot; +5. `inject` returns matching values on the direct and firmware-dispatched + paths. + +Next steps: [choose a tool](#5-choosing-the-right-tool) for your task and read +[Common recipes](#7-common-recipes). + +## 3. Mental model + +### 3.1 Two backends, one session API + +```text +CLI / REPL / Python ─┐ +MCP (stdio) ────────┼─► GreenEyeAPI ─► Session ─┬─► QEMU-RSP backend (qemu-system-riscv64) +Ghidra bridge ──────┤ hooks, watchpoints, └─► native backend (sim/machine.py) +harness/ + rmharness┘ memory, symbols, recorder ──► session directory +``` + +* **QEMU-RSP** is the default: full RV64 execution, gdbstub transport without + GDB, TCG trace plugin optional. +* **native** (`--backend native`) is the in-process interpreter: deterministic + virtual time (instruction counts), fast startup, an exec/access trace, and + lenient MMIO for first-touch exploration. +* Both satisfy the same `Session` primitives (registers/memory, breakpoints, + watchpoints, step/continue, snapshots), so scripts, probes, plugins, + recordings and comparisons survive a backend change. + +### 3.2 The primitives + +| Primitive | Use it for | +|---|---| +| `breakpoint` / `hook` | did this function run? with what arguments and return value? | +| `watch` (`w`/`r`/`a`) | when did this field change, from which store PC? | +| `run` / `run_until` | bounded observation; stop at a chosen address | +| `call` | Frida-like remote call to unit-test a function in isolation | +| `step` / `note` | single-step with dispatch; annotate the event stream | +| `Memory.read/write/hexdump/search/snapshot/diff` | inspect and diff memory regions | +| `SymbolDB` | resolve file/program/runtime addresses across sources | +| `Recorder` | write the durable session (events, snapshots, blobs) | +| injection SDK | load, register and invoke your own PIC RV64 service | + +Instructions between stops are invisible unless a trace is on: the TCG plugin +(`-plugin qemu/greeneye-trace.so`) on QEMU, or `--trace` on the native backend. + +### 3.3 Fidelity levels (what a result can mean) + +| Level | Property | risc-v-gsp-rm-debugger today | +|---|---|---| +| **L0** | instruction semantics | high (QEMU TCG, same ISA family) | +| **L1** | memory behaviour | high for RAM-resident code, conditional on mapping | +| **L2** | time/concurrency | **not modelled** (do not claim) | +| **L3** | device environment (falcon, WPR2, CSB, PMU, timers, DMA, IRQ) | **absent** (device model is roadmap) | + +A simulator observation is evidence about the firmware, not about silicon; +anything that would change the product is reproduced on a physical/vfio-mdev +reference first. Never quote a risc-v-gsp-rm-debugger session for timing, interrupt or +security claims. + +### 3.4 A session is the unit of work + +Every run records a `greeneye-session/1` directory: + +```text +dumps/-/ + session.json format, name, counts, snapshot inventory, meta + events.jsonl append-only event stream (hooks, watches, memory, notes) + snapshots/*.bin.z zlib-compressed region captures with sha256 + blobs/* QEMU logs, trace.jsonl, host-oracle stdout + summary.md rendered analysis +``` + +Partial sessions stay readable; the format evolves additively. A copied +`events.jsonl` without its `session.json`, snapshots and metadata is not +evidence. + +## 4. Tool inventory + +Run everything from `open-iov/debug/risc-v-gsp-rm-vm/` unless stated. + +### 4.1 CLI (`./risc-v-gsp-rm-debugger.sh`) + +| Command | One-line purpose | +|---|---| +| `info` | environment/tooling check (QEMU, paths, capabilities) | +| `demo` | canned boot + hooks + watchpoints + recording on the bundled uproc | +| `run ` | run a Python instrumentation session against the demo/ELF | +| `attach` / `launch` | interactive REPL; keep a target alive and print its gdbstub port | +| `record` | boot and record with watches/snapshots (and `--trace` on native) | +| `probe ` | bounded run of a raw image; first-divergence report | +| `analyze ` | session to symbol-annotated Markdown report | +| `compare ` | symbolic A/B delta of two recorded sessions | +| `symbols export\|resolve` | build/inspect a runtime-address symbol DB | +| `inject` | load, register and invoke an SDK service (direct + mailbox) | +| `ghidra` | serve the live session to GhidraScripts over localhost | +| `plugins` | list discoverable plugins | + +### 4.2 Harnesses (`harness/`) + +| Tool | One-line purpose | +|---|---| +| `portability_matrix.py` | probe + fixed scenario + compare across targets, with an M1–M6 skeleton | +| `mutation_harness.py` | seeded one-input mutations with outcome classes and per-attempt sessions | +| `control_discovery.py` | sweep a call surface to find known/unknown/injected handler IDs | +| `reach.py` | is one symbol reachable, what triggers it, with what arguments and effects | +| `version_diff.py` | old vs new image: shape, symbols, corpus hints, probe, behavior | +| `ci_release.py` | version_diff → matrix → mutation smoke, hashed into one bundle | +| `port_driver_versions.py`, `port_new_device.py`, `package_sim.py` | porting/packaging scaffolds (dry-run default; pilot status and evaluation in [docs/28](../../debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md), [docs/29](../../debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md)) | +| `value_demos/run_all.py` | ten fixed scenarios s01–s10 with measured time-to-value | +| `common.py` | shared helpers (flat relocation, sessions, bounded log reads) | + +### 4.3 Native simulator, plugins, host oracle, bridges + +| Tool | One-line purpose | +|---|---| +| `sim/` (`--backend native`, `--trace`) | deterministic RV64IMAC interpreter with exec/access trace and lenient MMIO | +| `python3 -m greeneye.device_map harvest\|show\|merge\|demo` | first-touch MMIO map: authoring, inspection, merge | +| `qemu/greeneye_trace.c` (`make -C qemu`) | full TCG exec/access JSONL trace with `start=`/`end=` filters | +| `plugins/example_plugin.py` | plugin authoring reference | +| `plugins/mcp_server.py` | MCP server for agents (stdio or loopback; read-only by default) | +| `plugins/rmharness_plugin.py` | REPL commands for the host RM oracle | +| `rmharness/harness.sh` + `rmtool`/`rmtop`/`rmq` | read-only host oracle captures appended into a session | +| `ghidra/ExportForGreenEye.java`, `MarkGreenEyeHits.java`, `GreenEyeControl.java` | symbol export, hit annotation and decompiler-driven execution | +| `sdk/` + `greeneye inject` | position-independent service ABI v1 | + +## 5. Choosing the right tool + +| Task | Tool | Notes | +|---|---|---| +| "Does this run?" / first divergence of a raw image | `./risc-v-gsp-rm-debugger.sh probe` | no device model: expected early fault is data | +| "What does this firmware do on this stimulus?" | `record` / `run` + `analyze` | fixed stimulus, bounded budgets, hooks/watchpoints | +| "Which command IDs exist / what is undiscovered?" | `harness/control_discovery.py` | fresh session per probe; deterministic seed | +| "Is this function reachable, and how?" | `harness/reach.py` | `auto|stimulus|trigger|run|call`; emits a replayable probe spec | +| "What changed between two firmware versions?" | `harness/version_diff.py`, `./risc-v-gsp-rm-debugger.sh compare` | static inventory + dynamic profile | +| "Does the new firmware move behaviour or code?" | `harness/version_diff.py` + docs/14 decision table | code vs behaviour classification | +| "Prove an error path / fail-closed rule" | `harness/mutation_harness.py` | simulator only; seeded and replayable | +| "Prototype an RM service before product code" | `sdk/` + `./risc-v-gsp-rm-debugger.sh inject` | PIC blob; direct and mailbox paths | +| "Join Ghidra static addresses to runtime hits" | `./risc-v-gsp-rm-debugger.sh ghidra` + Java bridges | localhost only; no auth | +| "What does a control reply look like on real RM?" | `rmharness/harness.sh … rmtool` | read-only host oracle; safe beside a CUDA job | +| "Explore MMIO the firmware touches first" | `probe` → `python3 -m greeneye.device_map` | versioned JSON; feeds the device model | +| "Triage a release end to end" | `harness/ci_release.py` | always `--dry-run` first | +| "Let an agent monitor a run" | `plugins/mcp_server.py` | read/observe by default; writes gated | + +Decision rule: static reading is a hypothesis; a recorded session is evidence; +at least an A/B pair is a conclusion. + +## 6. Sessions as evidence + +1. **Record with a fixed stimulus.** The same script, seed, budgets and image + hash make runs comparable; a self-comparison must be empty. +2. **Annotate as you go.** `s.note(...)` inside the session explains what was + asked and what was mutated; a chat log is not evidence. +3. **Attach the provenance.** Firmware SHA-256, version string, pairing notes, + symbol DB source/hash/bias, and the exact command or script. +4. **Keep the directory together.** `session.json` + `events.jsonl` + + `snapshots/` + blobs are one artifact; publish a SHA-256 list when moving + it. +5. **State the fidelity.** L0/L1 exercised; L2/L3 not claimed; reference + capture named (hardware, vfio-mdev, host oracle or none). +6. **Report deltas honestly.** `compare` marks non-semantic fields (time, host + paths, backend identity) as such; every remaining delta is explained or + listed as open. An empty unexplained-delta list is a claim that must be + earned. +7. **Bundle for triage.** A release bundle is + `bundle-manifest.json` + `release-report.json` + version-diff + portability + matrix + mutation smoke; see + [docs/21](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) §4.3. + +The M1–M6 metric contract (inventory, reply, ordering, state, error-path and +memory-side-effect agreement) is defined in +[docs/06-ACCURACY](../../debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md) §5 and is +authoritative for every claim. + +## 7. Common recipes + +### 7.1 First record and analyze + +```bash +cd debug/risc-v-gsp-rm-vm +make demo +./risc-v-gsp-rm-debugger.sh demo # prints the session directory +./risc-v-gsp-rm-debugger.sh analyze dumps/ # symbol-annotated report +``` + +### 7.2 Probe a new firmware image + +```bash +./risc-v-gsp-rm-debugger.sh symbols export --index --bias 0 -o symbols-.json +./risc-v-gsp-rm-debugger.sh probe .fwimage.bin> --symbols symbols-.json --record +python3 harness/version_diff.py --old --new --out dumps/vdiff- \ + --old-symbols symbols-.json --new-symbols symbols-.json +``` + +### 7.3 Discover controls and prove reachability + +```bash +python3 harness/control_discovery.py --out dumps/discovery --max-id 32 \ + --patterns zero --seed 5 +python3 harness/reach.py --target rpc_ping --method call --args 0x41 \ + --out dumps/reach-ping +``` + +### 7.4 Mutate an input surface (simulator only) + +```bash +python3 harness/mutation_harness.py --out dumps/mutation-7 \ + --iterations 64 --seed 7 --timeout 0.25 --settle 0.2 +``` + +### 7.5 Portability pipeline across targets + +```bash +python3 harness/portability_matrix.py \ + --target --target \ + --out dumps/matrix-candidate --probe-instructions 200 --scenario-duration 0.2 +``` + +### 7.6 Inject and debug a service + +```bash +make -C sdk +make -C sdk relocs +./risc-v-gsp-rm-debugger.sh inject --service sdk/build/injected_demo.elf --cmd 1 --arg0 0x41 --arg1 0x42 +``` + +The direct call is the unit test; the mailbox call is the integration test. +Both are recorded. + +### 7.7 Drive execution from Ghidra + +```bash +# terminal 1 +./risc-v-gsp-rm-debugger.sh ghidra --kernel --bridge-port 7000 +# terminal 2 (Ghidra headless) +$GHIDRA/support/analyzeHeadless -process -noanalysis \ + -scriptPath open-iov/debug/risc-v-gsp-rm-vm/ghidra \ + -postScript GreenEyeControl.java 7000 0x
+``` + +### 7.8 Host oracle capture (read-only) + +```bash +./rmharness/harness.sh --session dumps/real- --name before \ + -- rmtool engine list --format=json +./rmharness/harness.sh --session dumps/real- -- rmtop --once +``` + +### 7.9 Release rehearsal + +```bash +python3 harness/ci_release.py --old --new --out dumps/release- \ + --old-label --new-label --dry-run +``` + +`--dry-run` prints the plan and creates nothing; the RM 610 gate refuses 610 +labels (exit 3) until a human approves in writing. + +### 7.10 Let an agent monitor + +```bash +python3 plugins/mcp_server.py --stdio --backend native --record +# read/observe by default; --allow-write and --allow-inject are explicit opt-ins +``` + +### 7.11 First-touch device map + +```bash +./risc-v-gsp-rm-debugger.sh probe --record +python3 -m greeneye.device_map harvest dumps/ --out dumps/-device-map.json +python3 -m greeneye.device_map show dumps/-device-map.json +``` + +## 8. Troubleshooting + +| Symptom | Likely cause | Fix | +|---|---|---| +| `qemu-system-riscv64 not found` | QEMU absent or not on `PATH` | install `qemu-system-misc` or point `GREENEYE_QEMU` at the binary | +| QEMU starts but the script cannot attach | wrong port / target exited | use the port `launch`/`demo` printed; re-run `launch` and `attach --port ` | +| `Address already in use` on a bridge/trace port | stale bridge or another session | choose another `--bridge-port`; check `pgrep -fa greeneye` and `pgrep -fa qemu-system-riscv64` | +| QEMU survives Ctrl-C of a script | `launch` keeps the target alive by design | close the session or stop the reported PID; do not kill an unrelated QEMU | +| Session analyzer shows no hits/events | recording off, or the stimulus never ran | use the CLI (records by default); check hooks/watchpoints with a known symbol (`rpc_sum`) | +| `NameError: __file__` in `run` scripts | script invoked outside `risc-v-gsp-rm-debugger.sh run` | run through `./risc-v-gsp-rm-debugger.sh run`, keep scripts inside the tool tree | +| Empty TCG trace blob | plugin window missed or target never resumed | `make -C qemu`; widen `start=`/`end=`, set `exec=on`, resume the target | +| MCP writes refused / no tools | server read-only by default; stdout polluted | pass `--allow-write`/`--allow-inject` deliberately; keep stdout protocol-only | +| `greeneye error:` on a valid path | wrong relative path or `--db` file | `./risc-v-gsp-rm-debugger.sh info` shows resolved paths; bad symbol DBs fail with a clear error | +| Harness findings not reproducible | seed/budget changed | pin `--seed` and budgets; compare `findings.jsonl` byte-for-byte | +| Everything "unreachable" | wrong surface/timeouts | run `--surface demo` on the built demo first; raise `--settle`/`--timeout` | +| `Unknown symbol` in the optional OpenRM build | module-tag drift | re-pin build glue; see the [RUNBOOK](../RUNBOOK.md) S2 | + +Marker status: every tool document carries the +**# TOOL IN DEVELOPMENT - NOT READY YET!** banner. The marker is removed only +when the acceptance list in +[docs/00-OVERVIEW](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md) passes on a +clean checkout, the usage recipes verify end-to-end, a second person can run +the quickstart unaided, and the session format and CLI are declared stable. + +## 9. Safety + +* **Simulator only.** The tools launch their own QEMU or native machine + against the bundled demo or an explicitly allowed re-hosted ELF. They never + attach to hardware, a guest, a kernel module, an mdev or an existing + gdbstub. +* **No guest, no hardware, no product.** Nothing runs in a guest; injected + services are prototypes, not shipped code; product changes go through + `open-iov-vfio` with physical confirmation. +* **Read by default; writes gated.** MCP `write_mem`/`call_function` need + `--allow-write`, injection needs `--allow-inject`, and every write is + recorded in the session. +* **Bounded everywhere.** Runs have durations/stop caps; reads and snapshots + have size caps; harness subprocesses have timeouts; a wedged target is left + stopped and restarted clean rather than poked. +* **Local only.** Ghidra and MCP transports are localhost/stdio; the bridge is + unauthenticated by design, so never expose it on a network interface. +* **No confidentiality claims.** The simulator is a study environment, never a + security or confidentiality boundary; never use injection to defeat a + hardware security boundary. +* **Fuzzing is gated.** Mutation runs only against the simulator or re-hosted + code, behind explicit harnesses, with recorded evidence. +* **RM 610 is a hard human gate.** No acquisition, analysis, emulation edit, + physical work or support claim before written approval; the gate is enforced + by the CLIs. + +## 10. Documentation map + +Tool documentation (`debug/risc-v-gsp-rm-vm/docs/`): [00 overview](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md), +[01 design](../../debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md), +[02 usage](../../debug/risc-v-gsp-rm-vm/docs/02-USAGE.md), +[03 scripting](../../debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md), +[04 plugins](../../debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md), +[05 Ghidra bridge](../../debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md), +[06 accuracy](../../debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md), +[07 portability playbooks](../../debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md), +[08 roadmap](../../debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md), +[09 firmware notes](../../debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md), +[10 related work](../../debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md), +[11 RM service guide](../../debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md), +[12 injection SDK](../../debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md), +[13 Ghidra control](../../debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md), +[14 adversarial interop](../../debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md), +[15 agentic GSP IDE](../../debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md), +[16 custom simulator](../../debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md), +[17 RM harness](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md), +[18 harness automation](../../debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md), +[19 control discovery](../../debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md), +[20 MCP server](../../debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md), +[21 CI/release pipeline](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md), +[22 porting CUDA and devices](../../debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md), +[23 RM 610 readiness](../../debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md), +[24 device map](../../debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md), +[25 value validation](../../debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md), +[26 architecture](../../debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md), +[27 tool audit](../../debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md), +[28 porting automation](../../debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md), +[29 packaging and trialing](../../debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md), and the +[long-term roadmap](../../debug/risc-v-gsp-rm-vm/RISC-V-GSP-RM-DEBUGGER-ROADMAP.md). + +Project documentation: + +* [Open-IOV Defensive Operations Runbook](../RUNBOOK.md) — incident scenarios + S1–S10, evidence bundles, escalation tree; +* [GSP in a RISC-V VM](03-risc-v-gsp-rm-vm.md) — project-level purpose, status + and limits; +* [Debugging and maintenance workflows](02-debugging-and-maintenance-workflows.md) + — captures, failure taxonomy and the upgrade runbook; +* [Hardware and software matrix](../06-portability/hardware-software-matrix.md) + — support ladder and the portability pipeline; +* [Adversarial interoperability](../04-implementation/02-practical-challenges-and-adversarial-interop.md) + — the no-patch rule; +* [Engineering operations](../eng-ops.md) — tool admission, workflows and + retirement (the cross-cutting engineering-operations document); +* CUDA playbook: + [`userspace/cuda/docs/07-version-upgrade-playbook.md`](../../userspace/cuda/docs/07-version-upgrade-playbook.md) + and [`userspace/cuda/READ-ME-FIRST.md`](../../userspace/cuda/READ-ME-FIRST.md); +* [Documentation front door](../README.md) — the full reading order. + + -- cgit v1.2.3