<feed xmlns='http://www.w3.org/2005/Atom'>
<title>open-iov.git/kernel/gsp_rm_emulation.c, branch master</title>
<subtitle>Open-IOV vGPU-IO: host-side GSP emulation for unmodified NVIDIA guest drivers
</subtitle>
<id>https://git.vgpu.io/open-iov.git/atom?h=master</id>
<link rel='self' href='https://git.vgpu.io/open-iov.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/'/>
<updated>2026-10-11T21:50:53+00:00</updated>
<entry>
<title>Revert "vgsp-sema: scope channel deletion to the owning RM client (ISSUE-0002)"</title>
<updated>2026-10-11T21:50:53+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-11T21:50:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=b06a23c3a8ed36de9db3b880fe6df55d63ad4586'/>
<id>urn:sha1:b06a23c3a8ed36de9db3b880fe6df55d63ad4586</id>
<content type='text'>
This reverts commit 5fa773c2cd4e166d2c31a40aff9fb63e7534fec3.
</content>
</entry>
<entry>
<title>vgsp-sema: scope channel deletion to the owning RM client (ISSUE-0002)</title>
<updated>2026-10-11T20:43:33+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-11T20:43:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=5fa773c2cd4e166d2c31a40aff9fb63e7534fec3'/>
<id>urn:sha1:5fa773c2cd4e166d2c31a40aff9fb63e7534fec3</id>
<content type='text'>
Handles are per-client, but the FREE path unregistered any channel whose
numeric handle matched the freed object, with no client check. r77 root
cause of the third-client pma scrub hang: the boot session's CeUtils
scrubber channel (h=0x2, gpfifo=0x120064000, entries=4096) was
unregistered when an unrelated class-0x2080 object with handle 0x2 in
client 0xc1d00011 was freed. The guest kept using the live channel for
the scrub; the service no longer pumped it, its pushes were never
decoded and the channel-buffer finish payload (pbGpuVA+0x6c004) was
never written, so scrubCheckAndWaitForSize polled forever (sysrq stack:
ceutilsUpdateProgress -&gt; channelReadChannelMemdesc).

Channel registration now records h_client (the RM alloc header's client)
and deletion matches (h_object, h_client); a missing client on either
side keeps the handle-only behaviour. Re-registration keeps the
counter/release slots only for the same (handle, client) pair. Live
proof from the hung VM: sema_probe translates the finish-payload VA
0x12006c004 to pa=0x10f962004 aperture=ram - the word the guest polls is
reachable; the channel was simply invisible to the pump.
</content>
</entry>
<entry>
<title>vgsp-sema: bound emulated-vidmem shadow accesses by the shadow size, not the BAR1 aperture (ISSUE-0002)</title>
<updated>2026-10-11T19:43:30+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-11T19:43:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=1743c19465f4c024010d37e1fd96e9192cdc4525'/>
<id>urn:sha1:1743c19465f4c024010d37e1fd96e9192cdc4525</id>
<content type='text'>
The pma scrub in a second/third CUDA session memsets a legitimate vidmem
offset at 262M (inside the 512M turing shadow) and the copy path rejected it
with -EINVAL because every FB bounds check compared against
vgpu-&gt;bars[1].size, the physical BAR1 aperture exposed to the guest (256M on
TU104). The op was held and retried forever (opdef), the GR scrub waited in
scrubCheckAndWaitForSize and the client froze.

All bounds checks that guard a dereference of the emulated vidmem shadow at
vgpu-&gt;bars[1].vaddr now use nv_vgpu_fb_emul_size() via svc_fb_shadow_size():
the copy/fill paths, svc_read_ap/svc_write_ap, svc_ap_ok, the page-directory
discovery scans, svc_lookup's vidmem VA translation, the GRCE inline write,
svc_fwd_operand_hpa and the debug scans. The 2 MB leaf path of svc_gmmu_walk
now validates through svc_ap_ok like every other leaf path so an
out-of-shadow translation falls through to the shadow fallback instead of
reaching the copy path. The RM page-directory debug peek is bounded the same
way.

Evidence: r75b live log: sema-bigcopy dst_va=0x76aa08e02200 -&gt; pa=0x10602200
ap=0 prov=3; sema-bigop rc=-22 repeated; guest sysrq stack
scrubCheckAndWaitForSize -&gt; pmaAllocatePages.
</content>
</entry>
<entry>
<title>vgsp-rm: PROMOTE_CTX reply must keep bInitialize set (ISSUE-0001)</title>
<updated>2026-10-08T15:07:42+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-08T15:07:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=54bc80ae33addabc73a5bc1b0881423a63bc9862'/>
<id>urn:sha1:54bc80ae33addabc73a5bc1b0881423a63bc9862</id>
<content type='text'>
kgrobjPromoteContext_IMPL marks each ctx buffer initialized when the
REPLY's promoteEntry[i].bInitialize is set:

    if (!params.promoteEntry[i].bInitialize) continue;
    kgrctxMarkCtxBufferInitialized(...);

The flag is the server's initialized-ACK, so the correct emulation reply is
a verbatim echo (the physical backend owns residency; the control answers
SUCCESS). 7ce387f3 cleared the flag believing the check inverted - that
skipped the mark and left the RM re-promoting the same buffers forever.
Restore echo semantics with the source-cited comment.
</content>
</entry>
<entry>
<title>vgsp-rm: PROMOTE_CTX reply acknowledges ctx-buffer initialization</title>
<updated>2026-10-08T14:03:19+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-08T14:03:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=7ce387f3e3e5aac043b6d46a4451269c2b5c5233'/>
<id>urn:sha1:7ce387f3e3e5aac043b6d46a4451269c2b5c5233</id>
<content type='text'>
kgrobjPromoteContext_IMPL marks a context buffer initialized only when the
REPLY's promoteEntry[i].bInitialize is clear; echoing the request back kept
the flag set so the RM re-promoted the same contexts indefinitely. Clear
the flag on the echoed reply (per-entry, 5 entries observed per call).

Note: this aligns the reply with the caller contract but did NOT by itself
unblock the observed cudaMalloc stall (client still reaches DEVICE then
spins; zero GR ring content in VRAM) - kept because the old behavior was
wrong and the flag gates kgrctxMarkCtxBufferInitialized.
</content>
</entry>
<entry>
<title>vgsp-rm: harden the boot-time queue link against the 4 s GspStatusQueueInit window</title>
<updated>2026-10-08T13:38:39+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-08T13:38:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=7127c04d038074a3753a3c38dc11fa1fddf81b16'/>
<id>urn:sha1:7127c04d038074a3753a3c38dc11fa1fddf81b16</id>
<content type='text'>
The guest's first RmInitAdapter intermittently fails: GspStatusQueueInit
gives the status-queue link only 4 s (message_queue_cpu.c: timeoutUs =
4000000) and the first boot attempt can burn it, after which the RM tears
down, leaks the device and retries; the surviving retry leaves the GR/ctx
state degraded, which is the persistent cudaMalloc stall class.

Changes:
- gsp_rm_emu_poll: parse-retry cadence 250 ms -&gt; 50 ms (the 250 ms tick
  consumed a fifth of the guest's budget per attempt).
- gsp_rm_emu_reset: clear last_parse_retry so a new boot gets a fresh
  retry budget; take stat_lock while clearing queue cursors so a sema
  event post cannot race the reset.
- gsp_rm_emu_on_booter_done: on GSP_INIT_DONE send failure re-arm the
  retry path (parsed/active were already set, so the poll loop would
  never retry).
- gsp_rm_parse_queue_chain: free the previous ptes before re-alloc so
  retries and post-reset re-parses do not leak.
- gsp_rm_post_channel_event: never post events across a queue reset
  (parsed gate).

guest_kprobes.sh: add rpcs/rpcp transport probes (the direct RPC-wait
symbol is notrace in 570.144) and ccset entry/return probes for
rmapiControlCacheSet so a stall names the control whose reply breaks the
guest's control-cache bookkeeping.
</content>
</entry>
<entry>
<title>vgsp: per-mdev emulated VRAM size (1.0 multiple mediate sizes)</title>
<updated>2026-10-05T16:25:05+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-05T16:25:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=708a3802824358c1770d5ad0b3c2e24fae114eb8'/>
<id>urn:sha1:708a3802824358c1770d5ad0b3c2e24fae114eb8</id>
<content type='text'>
- nv_vgpu_type_info/ioctl gain vram_mb; nv_vgpu_device gains fb_emul_size
  bound from the mdev type at create (default 512 MiB).
- New nvidia-vgpu-turing-1g type (1024 MiB); turing max_instances 1 -&gt; 2;
  show_description reports the per-type framebuffer and max_instance.
- Thread fb_emul_size through GSCI fb_length/region/frtsOffset, WPR2,
  NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE, the vidmem allocator bound and the BAR1
  shadow; bar_info callback uses the per-device size.
- UNTESTED at commit time: builds clean; validation blocked by the Xid 140
  incident (reboot pending). See Handoff-vGPU-IO.md ADDENDUM 48.
</content>
</entry>
<entry>
<title>vgsp: end-to-end CUDA acceptance in the guest</title>
<updated>2026-10-04T20:19:31+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-04T20:19:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=aa3520f252182aaf64ea0b8856a3ac5e4466ce0e'/>
<id>urn:sha1:aa3520f252182aaf64ea0b8856a3ac5e4466ce0e</id>
<content type='text'>
The no-claim emulation path now runs a stock CUDA program end to end:
device properties, cudaMalloc, a GPU-authored string kernel read back
byte-for-byte, two 4 MB host-to-device copies, a 1 M-element vectorAdd
executed on the physical GPU through the host bridge, and the
device-to-host copy-back verified element by element. Three consecutive
supervised cycles report MAIL + VADD bad=0 checksum=392344090.500000 +
STATUS OK with identical input/output hashes.

Two data-path correctness fixes make the transfers sound:

- Once-only op execution per GPFIFO entry. The pump replays recently
  consumed ring entries when translation batches are injected so missed
  releases can land; re-executing a CE copy is not idempotent because
  its source is a client staging buffer that may have been refilled.
  Slots now record their raw entry words and a replayed entry matching
  that identity suppresses operations while still processing releases.

- Per-page translation of virtual operands. svc_copy resolved only the
  first page of a VA range and walked the PA linearly; client staging
  ranges are frequently split (observed 195 + 61 pages), so the tail of
  alternating chunks was read from unrelated memory. Multi-page copies
  now re-resolve each 4 KB page through the trusted resolver.

Also carries the earlier uncommitted emulation fixes that got the client
to the launch (QMD address-window gate, counter registration
persistence, 512 MiB emulated FB, bridge slot hygiene) and bounded
diagnostics (sema-bigop, sema-bigcopy, bridge-in/out hashes, daemon
INCHECK/OUTCHECK/dumps).
</content>
</entry>
<entry>
<title>kernel: capture the guest's PROMOTE_CTX entries; add promote mode 19 (guest-faithful 9-entry set)</title>
<updated>2026-10-02T19:45:55+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T19:45:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=680c0ad248dd54f5778808f19fbb6c2f9835ebab'/>
<id>urn:sha1:680c0ad248dd54f5778808f19fbb6c2f9835ebab</id>
<content type='text'>
- gsp_rm_emulation: dump every guest GPU_PROMOTE_CTX (0x2080012b) params and
  entries so the real client's promote shape is observable (captured on the
  emulation path: MAIN 2 MB PA+VA, PATCH, BUNDLE_CB/PAGEPOOL/ATTRIBUTE_CB/
  RTV_CB_GLOBAL VA-only, FECS, PRIV, UNRESTRICTED)
- gsp_phys_booter: promote mode 19 replays that exact 9-entry shape on the V5
  channel with host buffers (MAIN 2 MB + PDB map, small buffers, booking-only
  VAs); clamp 0..19
- docs/eng-ops: mode-19 result recorded - the server never replied (fn76 -110)
  and the release fail-safe held WPR2/GPU until an approved reboot; mode 19 is
  known-wedging
</content>
</entry>
<entry>
<title>kernel: GR context-promote bisection modes 4-17 and server-managed-ctxbuf registry variant; complete vgsp rename; docs/tooling refresh</title>
<updated>2026-10-02T19:13:06+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T19:13:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=c9bf1cf098c8ea4daeb3e6c9b274a9025c03045d'/>
<id>urn:sha1:c9bf1cf098c8ea4daeb3e6c9b274a9025c03045d</id>
<content type='text'>
- gsp_phys_booter: GR promote bisection modes 4-17 (two-phase zero-field VA,
  batched entries, hVirtMemory, bare VA, KMD SKIP_CTXBUFFER_ALLOC channel,
  old-interface GPU_INITIALIZE_CTX, FBMEM context buffer, UVM-faithful PA-only,
  PATCH/PM auxiliary promotes, server-managed no-promote path); PATCH/PM
  geometry queries and buffers; pre-boot SET_REGISTRY profile selection
- gsp_phys_gpu: gsp_phys_rmcall_gr_promote clamp 0..17 and gsp_phys_srv_ctxbuf
  parameter; registry image variant with RMSetClientRMAllocatedCtxBuffer=0
- vgsp rename across kernel, scripts, tools and docs (module vgsp.ko,
  /sys/kernel/debug/vgsp/, vgsp-&lt;subsystem&gt;: log prefixes)
- risc-v-gsp-rm-debugger user-facing rename and docs/CI refresh; guest-diag
  tool updates; README/SBOM/install/Makefile sync

Live status: CE ladder and P6 guest-copy forwarding green; GR engine context
commit still open (all promote shapes accepted or cleanly refused; the channel
stays CTXNOTVALID) - see Handoff-vGPU-IO.md Addendum 21 (local).
</content>
</entry>
</feed>
