From c3a295efd1b1132bbaa5d422cd05b3fa8e89a8bf Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 21 Sep 2026 13:06:51 -0400 Subject: kernel: Fix GSP emulation shadow binding, eventfd wiring, RPC livelocks + docs suite + repo reorg CRITICAL FIXES (guest driver bring-up): - gsp_emulation.c: emulation engine bound to the WRONG BAR0 - it polled the host physical BAR0 (bars[0].vaddr ioremap) for the doorbell and read RPCs from a local dma_alloc_wc buffer, while the guest writes land in the vzalloc'd bar0_shadow. The RPC path could never work; PBA writes even corrupted the host GPU's physical BAR0+0x3000. gsp_emu_init now binds exclusively to bar0_shadow (doorbell/mailbox/PBA aliases; shared_mem_dma==0 marks the alias so cleanup never dma_free's it). - main.c SET_IRQS: DATA_EVENTFD eventfds were DISCARDED ('TODO' + kfree) - the guest never received MSI-X completions. Full wiring now: eventfd_ctx_fdget per vector, fd -1 clears, dev_close releases refs. gsp_emu_inject_completion_interrupt looks up vgpu->irqs[0].trigger LIVE (init-time copy was permanently NULL since QEMU wires after gsp_emu_init). - gsp_rpc_client.c: BAR_TRAP/MIGRATE in emulation mode called gsp_rpc_submit_raw which rings the SAME doorbell the thread polls - self-triggered RPC livelock + multi-second stalls. Now fail fast with -ENOTSUPP + pr_warn_ratelimited (guest BAR access is direct MMIO). MORE FIXES: - main.c: nv_vgpu_config_write returned SIZE_MAX (while(count--) wrap) and was dead code while the VFIO write handler did unfiltered byte copies (guest could rewrite vendor ID/BARs). Return fixed; VFIO write handler now routes through the per-register filter. - kernel/Makefile: M=$(PWD) used the env var which is stale when invoked via the top-level make (pointed at repo root -> kbuild silently built NOTHING; explains every 'stale .ko' incident). Now M=$(CURDIR). - Warnings sweep: header prototypes for mdev/type functions, format casts in gsp_comm.c DRY-RUN logs, unused variable. ROBUSTNESS (harness/tooling): - vgpu_vm.py: run had no timeout (start could block forever); guest_shell recv could block forever on a wedged guest. Both now bounded; guest_shell pre-flights guest-ping and reports wedge diagnostics. - stack_manager.sh: qemu/qemu-debug now launch via the vgpu_vm.py harness (workflow rule: never raw QEMU). REPO REORGANIZATION: - driver/ (legacy guest-side gsp-vgpu.ko) moved to legacy-driver-guest/ (reference only, not built; README explains). 3 legacy un-buildable test files moved to legacy-driver-guest/kernel-tests/. Top-level Makefile cleaned of the dead DRIVER_DIR reference. DOCUMENTATION SUITE (new): - docs/GSP_EMULATION_ARCHITECTURE.md - emulator deep-dive: shadow BAR0 model, doorbell protocol, dispatch table, MSI-X path, lifecycle, memory- model caveats - docs/DEBUGGING.md - QEMU GDB stub workflow, serial console, QMP NMI, failure taxonomy, full bring-up validation checklist, EPT-livelock case study, version-matrix discipline - docs/ONBOARDING.md - repo tour, coding standards (incl. virt_to_phys / dma_addr_t / get-put rules), first build & test - docs/VERSION_UPGRADE.md - end-to-end new-driver-version procedure (firmware fetch, Ghidra analysis, configs, signatures, validation) - docs/PERFORMANCE.md - bare-metal A/B methodology + targets - README.md doc index; STATE.md refreshed; DEVELOPMENT_WORKFLOW.md corrected (load order: open-iov-vfio BEFORE nvidia; stock-driver blacklist note) --- docs/DEVELOPMENT_WORKFLOW.md | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'docs/DEVELOPMENT_WORKFLOW.md') diff --git a/docs/DEVELOPMENT_WORKFLOW.md b/docs/DEVELOPMENT_WORKFLOW.md index 2263af6..9019ac1 100644 --- a/docs/DEVELOPMENT_WORKFLOW.md +++ b/docs/DEVELOPMENT_WORKFLOW.md @@ -17,7 +17,7 @@ $OPEN_IOV_ROOT/ # Main monorepo (git + LFS) | Directory | Purpose | |-----------|---------| | `kernel/` | Host VFIO mdev driver (`open-iov-vfio.ko`) | -| `driver/` | Guest vGPU driver (`gsp-vgpu.ko`) - **to be removed** | +| `legacy-driver-guest/` | Historical guest-side driver (reference only, **not built**) | | `userspace/lib/` | `libiov.so` / `libvgpu.so` + `rpc_emulator.c` | | `userspace/examples/` | `example_vgpu` test app | | `firmware/57X-GSP/570.144/` | GSP firmware binary + 132 decompiled C files | @@ -212,8 +212,7 @@ oiv-clean | Artifact | Location | Size | |----------|----------|------| | `nvidia.ko` | `nvidia-open-gpu-kernel-modules/kernel-open/` | 35MB | -| `open-iov-vfio.ko` | `kernel/` | 2.8MB | -| `gsp-vgpu.ko` | `driver/` | 1.8MB | +| `open-iov-vfio.ko` | `kernel/` | ~3.8MB | | `libiov.so` / `libvgpu.so` | `userspace/lib/` | 76KB | | `example_vgpu` | `userspace/examples/` | 27KB | @@ -222,32 +221,44 @@ oiv-clean ## 4. Kernel Module Loading ### Prerequisites -- **REBOOT REQUIRED** if kernel cmdline has `module_blacklist=nvidia,...` -- Check: `cat /proc/cmdline | grep module_blacklist` -- GRUB must be updated: `/etc/default/grub` → `update-grub` → `update-initramfs -u` → reboot +- The **stock Ubuntu nvidia driver must not be loaded** when you want our + OpenRM nvidia.ko: both are named `nvidia`. The stock driver auto-loads on + desktop boots (udev) and is held open by the GUI. + `/etc/modprobe.d/blacklist-nvidia-open-iov.conf` (installed on this + machine) prevents that auto-load after reboot; `insmod` is unaffected. +- `stack_manager.sh load-nvidia` detects a foreign loaded nvidia + (compares `/sys/module/nvidia/version` with our build) and refuses with + guidance instead of silently skipping. ### Load Order (Critical) ```bash -# 1. NVIDIA OpenRM host driver (exports vGPU VFIO symbols) -sudo insmod $OPEN_IOV_ROOT/nvidia-open-gpu-kernel-modules/kernel-open/nvidia.ko +# 1. VFIO/mdev prerequisites +sudo modprobe vfio vfio_iommu_type1 vfio_pci mdev -# 2. Open-IOV VFIO mdev driver (depends on nvidia.ko symbols) +# 2. Open-IOV VFIO mdev driver FIRST - it is fully standalone (zero nvidia +# imports) and EXPORTS the nvidia_vgpu_vfio_* interface + registers the +# mdev parent on the physical GPU. sudo insmod $OPEN_IOV_ROOT/kernel/open-iov-vfio.ko -# 3. Guest vGPU driver (standalone, works without above) -sudo insmod $OPEN_IOV_ROOT/driver/gsp-vgpu.ko firmware_name=gsp-570.144.fwimage.bin +# 3. NVIDIA OpenRM host driver - imports our nvidia_vgpu_vfio_* symbols +# (must be built with KBUILD_EXTRA_SYMBOLS=kernel/Module.symvers) +sudo insmod $OPEN_IOV_ROOT/nvidia-open-gpu-kernel-modules/kernel-open/nvidia.ko + +# 4. GSP firmware for the host GPU +sudo cp firmware/57X-GSP/570.144/gsp-570.144.fwimage.bin /lib/firmware/ ``` ### Using Helper Script ```bash -oiv-load # Runs all three in order +./scripts/stack_manager.sh load-stack # prereqs → open-iov-vfio → nvidia → firmware ``` ### Verify Load ```bash -lsmod | grep -E "nvidia|open_iov|gsp_vgpu" +lsmod | grep -E "nvidia|open_iov" dmesg -T | grep -i -e nvidia -e gsp -e vgpu -e open-iov -ls -la /dev/gsp-vgpu /dev/nvidia* +ls /sys/class/mdev_bus/0000:01:00.0/mdev_supported_types/ +cat /sys/class/mdev_bus/0000:01:00.0/mdev_supported_types/nvidia-nvidia-vgpu-turing/available_instances ``` ### Unload -- cgit v1.2.3