# Practical Challenges and Adversarial Interoperability > How we intend to implement compute/CUDA support *fast and correctly*, and the > discipline that keeps the whole stack unmodified — ours included. ## 1. The central engineering bet > Emulate the interface. Pass through the work. Never patch anyone. Everything below follows from taking that seriously. It forces hard choices (no "just add a flag to the guest driver"), and it pays for itself by making the project portable, maintainable and legally clean. ## 2. Fast and correct: the tension ### 2.1 What "correct" means here Correctness is not "no crash". It is: * the guest observes the same **values** (capabilities, handles, table contents) it would on real hardware — a control whose reply fields the driver consumes is only "implemented" once its reply is coherent, not just `SUCCESS`-shaped (the reply-fidelity ladder: status-only → coherent zeroed params → coherent values for consumed fields → exact values; see [`../../userspace/cuda/docs/04-virtualization-and-emulation.md` §6](../../userspace/cuda/docs/04-virtualization-and-emulation.md)), * the guest observes the same **ordering** (completions happen after the work they signal; faults arrive before replays), * the guest observes the same **failure semantics** (errors are surfaced, not swallowed), * and the work produces the same **results** (a CUDA kernel's output matches native execution). ### 2.2 What "fast" means here Two budgets matter, and they are different: * **Initialization latency** — how long from VM start to CUDA ready. Dominated by RPC round-trips and guest driver's own work. Target: within 2× of physical device initialization in the same guest. * **Steady-state throughput/latency** — kernel launch overhead, copy bandwidth, and completion latency. Target: published, stable, and within an agreed factor of native for each supported operation class. We will publish the methodology and the numbers together; a performance claim without a methodology is not accepted in this project. ### 2.3 The fast paths * **Pure state operations** (semaphores, membar, fences, some memops) are satisfied in the emulation directly — they are microseconds in hardware and would otherwise cost a round trip to the physical GPU and back. * **Management operations** (object creation, capability queries, mappings) are answered from cached/derived state where the hardware has no side effects the guest can observe. * **Real work** (grid launches, copies) is meant to be forwarded to the physical GPU (see §3). CE-class copies and their semaphore releases are now forwarded to the physical copy engine (default off) with a host-side fault relay, and memsets/copies/releases the host decoder understands still run in software as a fail-closed correctness bridge. No CUDA kernel is forwarded yet: GR kernel execution is blocked on GR engine-context validity. ## 3. Forwarding: the options and the chosen mechanism ``` (A) Proxy through the host driver guest push → translate → host driver's RM → real channel → GPU Not implementable with an unmodified distribution driver: no callable RM entry point from kernel context (see 03-architecture/08). (B) Own the GPU; own scheduling (no GSP) guest push → translate → our own channels/runlists/page tables → GPU Reproduces the scheduler and MMU ownership; large, capability-limiting. (C) Hybrid Only meaningful once (A) and (B) both exist. (D) Own the GPU; use its real GSP firmware as the server ← chosen guest push → translate → real GSP-RM session → real channel → GPU The module is the host-side resource-manager client; the firmware schedules. ``` The full analysis — which interfaces exist, why the proxy is unavailable, and the ownership model — is in [`../03-architecture/08-physical-gpu-integration.md`](../03-architecture/08-physical-gpu-integration.md). The work path stays abstracted behind one interface so the backend can be swapped. Software execution of decoded state/memory operations remains a correctness bridge for bring-up, not the data plane. ## 4. Hard problems we must solve, and our stance on each | Problem | Stance | |---|---| | **Page tables on both sides** | We populate server-owned ranges using the layout the client hands us and the entry encodings from AMAP/HAL references; a validator compares our tables against what the guest expects before enabling a channel. | | **Memory coherence** | Guest sysmem is coherent by construction (same physical pages); VRAM objects must be migrated to real VRAM or DMA-mapped. Phase 2 picks per-object policy with correctness first. | | **Scheduling between tenants** | One real GPU, N guest channels — schedule explicitly (time-slice/partition), measure fairness, audit isolation. Never let the guest's own scheduler influence another tenant. | | **Fault handling** | Reproduce faults under forwarding, implement replay/cancel on the guest's terms, and make fault latency measurable. | | **State explosion** | Drivers create enormous state. We do not model all of it — we model what the guest *observes*, and forward what it *uses*. Anything unobserved stays unmodeled. | | **Version drift** | Version-keyed handlers with a configuration-driven profile per (driver, firmware) family; new versions added by measurement, never by guessing. | | **Security of the debug tooling** | Debug parameters are development-grade; the productized build keeps only read-only diagnostics and gates destructive ones behind explicit opt-in. | ## 5. Adversarial interoperability ### 5.1 The rule **No modification is permitted in any component we do not own**: guest driver, host driver, GPU firmware, hypervisor, device model, guest OS. Why so absolute: every permitted exception becomes a maintenance liability that scales with the number of versions in the field. A patch to the guest driver means maintaining forks for every guest OS and driver version. A patch to the hypervisor means every hypervisor project must carry it. A firmware change is impossible in practice. In this repository, patch files exist only as build glue for the *optional* OpenRM submodule build (`legacy-patches/nvidia/`, applied by `install.sh`). The runtime and the guest stack are never patched, and the deployment path uses the distribution driver — so nothing patched is required to run the stack. ### 5.2 How compliance is verified * **Contract tests** (goal): CI builds run against *stock* drivers obtained from distribution repositories (or vendor runfiles), and against *unmodified* hypervisor packages. Today CI is push/PR-triggered only — builds, kernel/unit/KUnit/mock tests, static analysis and docs checks; there is no scheduled guest suite or stock-driver contract test yet, so the guest ladder is still run by hand (see the operations docs). * **No-patch checks**: our build must not depend on any patch file for third-party components. Where patches exist in the tree for convenience (e.g. build glue for the optional OpenRM submodule), they are development scaffolding only: the contract tests must pass without them, and the deployment path uses the unpatched distribution driver; anything that fails this is a bug. * **Behavioral equivalence**: where we answer from emulation, we validate the values against traces from real hardware (or from our decompiled study notes) — not against our own previous answers. ### 5.3 What we *can* change * Our own module, userspace library, tools, scripts and docs. * Configuration: device profiles, version profiles, capability tables. * Tests and harnesses. ### 5.4 Where the line gets tested * **Firmware signatures**: the driver verifies firmware. We satisfy the handshake by *emulating the interface*, not by patching the image or the driver. * **PCI IDs and VBIOS**: the guest driver decides how to treat the device from what it reads. We present a coherent device; we never rely on the driver skipping checks. * **Licensing checks**: our device is our device; we do not impersonate a licensed product. Interoperability is the goal, not circumvention of a vendor's own licensing for their own products. ## 6. Why this approach is durable Because our artifacts are: * **Interface definitions** (protocol tables, structures) — survive versions. * **Measured contracts** (what the guest observes) — survive reimplementation. * **Configuration** (profiles per version/hardware) — survive hardware. * **Tests** (contract ladders) — catch drift immediately. A new driver version or GPU is therefore *data + verification*, not a rewrite — the difference between a hobby project and infrastructure. ## 7. The "thrilling" part (for developers) If you are reading this to decide whether to work on it: this project is one of the few places where you can: * reverse engineer a 28 MB RISC-V firmware and turn it into maintainable C, * design a memory model that makes two different address-space owners agree, * build a virtualization path for the most commercially important accelerator on Earth, under a permissive license, * and have your work outlive the hardware generation you started on. Start with [`../07-developers/onboarding-and-standards.md`](../07-developers/onboarding-and-standards.md).