| Commit message (Collapse) | Author | Age |
| |
|
|
|
| |
The per-area coordination file was local scratch (gitignored); future
parallel work is announced through the project handoff instead.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Two more retry loops surfaced once the guest driver got past the CE binding:
- BAR0 region reads returned -EINVAL ("would be handled by mmap"), so a
QEMU-trapped read of BAR0+0x88084 failed and the driver polled it forever.
Serve reads from the BAR0 shadow/trap handler (and mirror BAR1 reads from
the emulated vidmem backing).
- Config-space writes above offset 0xFF were refused with -EINVAL, so the
driver's write to extended config 0x704 (PCIe device control area) never
took effect and it retried. Accept and store extended-space writes; keep
the legacy identity registers fixed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Status now matches the live state: guest driver probe and nvidia-smi work;
cuInit/device queries work; cuCtxCreate returns 999 because the emulated
engine list is missing the async copy engine (COPY14). The userspace
libcuda segfault is recorded as solved, with its mechanism (an RM
allocation reply must echo request parameters; zeroing them corrupted the
caller's saved frame pointer).
* Correct the emulation claims: only a subset of RM controls are
special-cased; the rest return a success reply with zeroed parameters whose
consumed fields are still being corrected; allocation replies are coherent
but no server-side object model exists.
* Add the eight-point emulation checklist and reply-fidelity ladder as
explicit gates, documented in userspace/cuda and linked from the
architecture, implementation and operations docs.
* Fix operational errors: build/test commands, module load order, mdev type
names, LFS references, debugfs claims, in-repo firmware claims, CI claims,
portability matrix (guest status, config layout, userspace driver facts).
* Mark historical material: one superseded banner per legacy document with a
pointer to its replacement; STATE.md marked as a 2026-09-21 snapshot.
* Wiki: fix the index, add status banners and in-place factual corrections
(msgq transport vs legacy mailbox, BAR definitions, error statuses,
migration, glossary), and note the archived 2023 imports.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add the analysis of the NVIDIA CUDA userspace driver used by Open-IOV VMs:
* docs/01-08: architecture (layers, object model, threads, sync, memory,
channels, launch), build and execution model, the driver/kernel/GPU
interface contract, virtualization approaches, the 570.144 decompilation
map with the corrected libcuda crash path and the current engine-topology
blocker, tooling, and a version-upgrade playbook.
* tools/: version-agnostic toolchain - stdlib ELF/interface toolkit
(exports, unwind-table function map, wrapper resolution, version delta,
crash address decode), callgraph walker, corpus annotator, and Ghidra
analysis/decompilation/name-map scripts with resumable parallel drivers.
* 570.144/annotations/: our name map (exports + resolved wrappers + verified
internals) and subsystem index, tracked so naming work accumulates.
* READ-ME-FIRST.md: reading guide with the fast lookup recipes.
The full decompiled corpus and annotated corpus stay untracked (vendor-
derived, gitignored under the version run/ tree).
|
| |
|
|
|
|
|
|
|
|
| |
The mdev's region write handler returned success without touching the BAR0
shadow or the trap table, so register writes that arrive through the VFIO
region path (QEMU-trapped accesses) never took effect. A fresh guest then
polled a register that never changed and spun forever in cuInit (QEMU log:
vfio_region_write(mdev:region0+0x88704) failed: Resource temporarily
unavailable). Route those writes to the BAR0 shadow/trap handler and mirror
BAR1 writes into the emulated vidmem backing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- GSP_RM_ALLOC: echo the request payload back with status forced to NV_OK.
The kernel driver copies the reply params over the caller's params buffer
using the class-expected size, so a zeroed reply smashed libcuda's stack
(SIGSEGV at the engine-registration continuation); echoing makes the
copy-back idempotent.
- CE_GET_PHYSICAL_CAPS / CE_GET_ALL(_PHYSICAL)_CAPS: report sysmem, P2P and
BL copy caps and mark the GR-synchronous CE (GRCE, COPY0). Without a GRCE
the client's context walk ends with an empty secondary-engine record and
the engine RM alloc is issued with class 0 (rejected -> cuCtxCreate fails).
- TU104 engine table: CE0 shares the GR PBDMA ids (the driver's GR/GRCE
runqueue validation requires it), plus an entry for the async copy engine
(COPY14) advertised in the GSP static info engine caps.
- tools/guest-diag/ioctl_trace: decode the RM status fields of alloc,
control and free so the first failing driver call is visible in traces.
gitignore: keep the CUDA analysis scratch tree (incl. WORKING-HERE.md) local.
|
| |
|
|
|
|
| |
Move supporting detail to the adjacent local analysis notes (gitignored;
referenced by name from the public analysis) and ignore those notes tree-wide.
No behaviour or code changes.
|
| |
|
|
|
|
|
|
|
|
|
| |
The host libcuda (570.211.01) has the identical engine-registration helper
instruction sequence (byte-pattern matched, host vaddr 0x454470 vs guest
0x453ef0). scripts/host_gdb_descriptor.sh runs cdt on the host under gdb and
prints the per-engine 6-dword registration record and the dispatch hook
target. Host registers a copy engine {3, 0xd, 4, 0xc5b5, 0x3e6, 3} and
cuCtxCreate succeeds; the guest registers GR {1, 1, 0, 0xc5c0, 0, 0} and
crashes - so the divergence is in the engine records the driver builds from
the emulated GSP static info engine table.
|
| |
|
|
|
|
|
|
| |
Records that libcuda builds an async copy-engine list from per-engine records
(engine kind, runlist, class) received with the device information, which is
derived from the GSP static info engine table this project emulates, and that
the crashing per-engine helper operates on those records. The adjacent local analysis notes (userspace/cuda/570.144/LOCAL-ANALYSIS.md) carry supporting
detail.
|
| |
|
|
|
|
|
|
|
| |
Documents the exact crash: cuInit/device enumeration now succeed; cuCtxCreate
faults in an engine-check/report path at libcuda+0x453f90 with rbp=0.
Register trace shows rbp valid at the helper and at the dispatch hook's
leave, but 0 immediately after the hook returns; the hook and the dispatch
table entries are all valid libcuda code. Adds the ioctl sequence observed
before the crash and lists what is still unanalysed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Analysis tooling for debugging CUDA execution in Open-IOV guests:
- userspace/cuda/570.144/: fetch a library from a running guest (nc),
objdump helpers, crash ip -> file vaddr + symbol mapping, and Ghidra
headless import/analysis/decompile scripts (project kept so single
functions decompile in seconds). The purpose is debugging correctness
and performance of CUDA in Open-IOV VMs (not a reimplementation);
extracted binaries and decompiled output are gitignored.
- tools/guest-diag/ioctl_trace.c: ptrace tracker for the NVIDIA driver
ioctls of a child (libcuda issues raw syscalls, so LD_PRELOAD sees
nothing). Decodes RM_ALLOC (class) and RM_CONTROL (cmd) arguments;
this is how the cuCtxCreate crash sequence was captured.
- tools/test/cuda_drv_test.c: unbuffered + per-call markers so a crash
identifies the CUDA call it happened in.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The progress service now decodes push buffers as method streams and performs
the work the driver pushes, not just the tracking semaphore:
- C5B5 method decoder: SET_REMAP_CONST_A/B + COMPONENTS + OFFSET_OUT +
LINE_LENGTH_IN + LAUNCH_DMA = memset (into vidmem or guest RAM);
OFFSET_IN + OFFSET_OUT + LAUNCH_DMA = copy; SET_SEMAPHORE_A/B/PAYLOAD +
LAUNCH_DMA = release. Contiguous method runs (count 2/4) are applied in
full - OFFSET_IN/OUT arrive as one run.
- Pushes span page boundaries, so pages are decoded as method streams
without a start marker. Collected operations execute only when the
push's release is reached and still pending (payload ahead of the
semaphore), so recycled buffers replaying old pushes are skipped and
their stale memsets cannot overwrite newer state.
- VA->PA map is first-wins: stale copies of freed allocations and
unrelated adjacent u64 pairs produced bogus entries that hijacked a
good mapping and sent semaphore writes to the wrong page.
- dump_guest module parameter (hex dump of guest PA, kthread via
completion; kthread_stop before the thread runs loses the work).
With this the guest no longer stalls in uvm_tracker_wait and no longer
oopses in the UVM path; the failure moved to a userspace segfault inside
libcuda (NULL-0x38) after the driver's page allocations.
Also add tools/cuda-ab: run one deterministic CUDA workload on the host
(bare metal oracle) and in the guest, then compare the stable result
lines. The binary links the CUDA runtime statically so the guest only
needs the driver's libcuda.so.
|
| |
|
|
|
|
|
|
|
| |
Relax the in-order rule to forward progress (payload > current), with the
jump bounded and counted: UVM tolerates forward jumps up to 2M
(2 * UVM_CHANNEL_NUM_GPFIFO_ENTRIES_MAX), and push buffers are recycled so
intermediate pushes can be missed. Add miss/stale/jump counters to the
rebuild log and a sema_probe module parameter to dump the service's map
entry and live slot values for a GPU VA (diagnostics for tracker stalls).
|
| |
|
|
|
|
|
|
|
| |
- patches/ -> legacy-patches/ (gitignored)
- legacy-driver-guest/ (old guest vGPU driver, gitignored)
- docs/old/ (superseded architecture write-up, gitignored)
- docs that only reference the legacy components stay tracked; their path
references now point at legacy-patches/
- install.sh PATCH_DIR updated
|
|
|
Open-IOV virtualizes NVIDIA GPUs so that unmodified guest drivers run with
real GPU functionality - CUDA first, 3D and video to follow - on unmodified
hosts, without a proprietary vGPU license and without patching any driver,
firmware or hypervisor.
Core principle: emulate the interface, pass through the work.
kernel/ open-iov-vfio.ko - host VFIO mdev driver: virtual GPU device
(PCI config space, BAR shadows, MSI-X), GSP boot emulation,
GSP-RM message-queue/RPC emulation, memory model (GPU-VA to
guest-PA discovery) and the semaphore-completion service that
advances guest UVM progress.
userspace/ libiov.so management API and examples.
tools/ guest diagnostics, firmware analysis wrappers, RM probes.
scripts/ stack manager, VM harness, build/load/test automation.
config/ hardware/version profiles (the portability surface).
docs/ documentation tree - start at docs/README.md.
wiki/ long-form firmware and protocol deep dives.
Status: initialization works end to end for a stock 570.144 Linux guest on
Turing (TU104): driver probe, nvidia-smi, the full GSP-RM control battery,
object creation and the early CUDA/UVM start-up path. GPU work forwarding -
the step that makes CUDA kernels execute on real hardware - is the active
work item; see docs/04-implementation/01-known-knowns-and-unknowns.md.
License: BSD-3-Clause for the project; GPL-2.0 for kernel modules that link
GPL-only kernel interfaces. See LICENSE and docs/09-reference/legal-and-licensing.md.
|