<feed xmlns='http://www.w3.org/2005/Atom'>
<title>open-iov.git/kernel/gsp_emulation.c, branch archive/pre-squash</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=archive%2Fpre-squash</id>
<link rel='self' href='https://git.vgpu.io/open-iov.git/atom?h=archive%2Fpre-squash'/>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/'/>
<updated>2026-09-23T03:41:13+00:00</updated>
<entry>
<title>kernel: widen PCFG mirror watch to link-cap aliases (debug helper)</title>
<updated>2026-09-23T03:41:13+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-23T03:41:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=1ed5d98cbb2273e75674d050fb48e3c3422a3877'/>
<id>urn:sha1:1ed5d98cbb2273e75674d050fb48e3c3422a3877</id>
<content type='text'>
Logs changes to NV_PMC_BOOT_1 (0x4), the low PCFG alias, the BAR0 PCFG
block (0x880000/0x880080/0x880084/0x880088/0x88008c) and the VF-window
aliases. Observed during a CUDA run: the guest never writes any of them,
so the link-cap values we pre-set (0x103 / 0x01030000) are not clobbered.
Reads are not observable through the mmap'd BAR0.
</content>
</entry>
<entry>
<title>kernel: FB/BUS info-list controls + PCIe link caps for the UVM path</title>
<updated>2026-09-23T03:32:44+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-23T03:32:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=14283fe73fb5e432a7af45de94961655714910f6'/>
<id>urn:sha1:14283fe73fb5e432a7af45de94961655714910f6</id>
<content type='text'>
CUDA (cuInit) now reaches UVM's device create: libcuda opens nvidia-uvm,
UVM calls nvGpuOpsDeviceCreate/gpuGetGpuInfo, and the driver fails at
getPCIELinkRateMBps -&gt; calculatePCIELinkRateMBps ("Unknown PCIe speed",
NV_ERR_INVALID_STATE) -&gt; nv_open_device aborts -&gt; cuInit returns
CUDA_ERROR_NOT_INITIALIZED (3).

Implemented along the way:
- FB_GET_INFO_V2 (0x20801303): echo the requested FB info indices and
  answer TU104 values (256MB RAM/heap/BAR1, GDDR6, 8 LTCs, 4MB L2, ...).
  Fixes the kern_mem_sys_ctrl.c:911 asserts and gives CUDA/UVM real
  memory sizes.
- BUS_GET_INFO_V2 (0x20801823): echo indices; PCIe Gen3 x16 link caps /
  GEN info / link status, SYSMEM_CONNECTION_TYPE=PCIE. UVM's
  gpuGetSysmemLinkInfo reads SYSMEM_CONNECTION_TYPE and the nominal link
  bandwidth from here.
- PCIe Link Capabilities in the emulated config space (0x8C/0x92) and in
  the BAR0 PCFG mirror (gpuReadBusConfigReg -&gt; NV_PCFG+0x84 = BAR0+
  0x88084): MAX_SPEED=3 (8GT/s Gen3), MAX_WIDTH=0x10 (x16); link status
  mirror at 0x88088. Also mirrored under the VF-window/low aliases.
- Temporary change-watch on PCFG[0x88084] to see if the guest overwrites
  it (it does not - stays 0x103).

Verified: guest nvidia-smi -L still works and reports PCIe Generation
Max/Current = 3. cuInit still fails; the remaining question is which
address the driver's kbifGetGpuLinkCapabilities read sees as zero (the
PCFG shadow holds 0x103). Guest-side kprobe tracing of that function
panicked the VM (free_swap_cache page fault on a corrupted pointer) -
possible guest memory corruption to investigate separately.
</content>
</entry>
<entry>
<title>kernel: guest probe completes - nvidia-smi enumerates the emulated TU104</title>
<updated>2026-09-23T02:40:26+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-23T02:40:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=f6d450a8be075fdc19a874826e7649ae0149b099'/>
<id>urn:sha1:f6d450a8be075fdc19a874826e7649ae0149b099</id>
<content type='text'>
Root cause of the golden-image NV_ERR_NO_MEMORY: STATIC_KGR_GET_CONTEXT_
BUFFERS_INFO (0x20800a32) fell through to the generic zeroed reply, so
kgraphicsInitializeDeferredStaticData() stored a 0-byte main ctx buffer
size and kgrctxAllocMainCtxBuffer() did a 0-page allocation
(mem_desc.c:1353). Serve the TU104 per-engine ctx buffer table (26 engine
IDs x 8 GR engines; NV_U32_MAX = unsupported, which the client skips).

Second blocker after that: L2 cache-op and TLB-invalidate completion
registers. Turing reaches them through the virtual-register window
(GPU_VREG_* = BAR0 + sriovState.virtualRegPhysOffset + offset, 0xB80000
for a non-SRIOV virtual GPU): NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE
(0xB830B0, TRIGGER bit31) and the L2 invalidate/dirty-flush set
(0x70000-0x70014 and 0xB80F00/0xB80F04). The driver soft-locked spinning
in osDevReadReg032 on 0xB830B4 (kgmmuCheckPendingInvalidates_TU102) and
timed out in kmemsysDoCacheOp_GM107; auto-clear all of them (both the
plain and windowed aliases).

Third: re-probe failed with GspStatusQueueInit msgqRxLink timeout because
gsp_rm_emu_reset() was not called before a fresh boot, leaving rm-&gt;parsed
set so the new libos args were never parsed. Reset GSP-RM state on the
fresh FWSEC kick.

Verified: guest nvidia-smi and nvidia-smi -L both exit 0 (full
unload/reload cycle), GPU enumerated as "NVIDIA GeForce RTX 2080 SUPER"
with 256MB, no NO_MEMORY / timeouts / soft lockups in the guest.

Also add tools/rmq/grctx_oracle.c documenting that the host RM does not
expose the ctx-buffer table to userspace (the real values are probed from
the ctxsw ucode by GSP-RM), so the emulation serves synthesized sizes.
</content>
</entry>
<entry>
<title>BAR2 verify test fix: remove PRAMIN sync + contiguous ALLOC + vidmem VA allocator</title>
<updated>2026-09-23T01:55:54+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-23T01:55:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=fcd603db457c0fb035df882abc55397bc854a1cd'/>
<id>urn:sha1:fcd603db457c0fb035df882abc55397bc854a1cd</id>
<content type='text'>
Fixes the BAR2 verify test (kbusVerifyBar2_GM107):
1. Removed PRAMIN window sync from emulated BAR1 - the sync was overwriting
   test data written by the driver through the vBar2 aperture. The shadow
   BAR0 is already consistent (guest writes/reads hit the same shadow location).
2. Added contiguous page allocation for golden image (alloc_pages with order
   for large allocations, falling back to individual pages).
3. Added vidmem VA allocator - ALLOC now returns GPU VAs within the emulated
   GPU's vidmem range (0x100000 - fb_size) instead of default 4GB, so the
   memmgr accepts them.

Verified: driver probes past RmInitNvDevice bus init, reaches golden image
channel allocation (progress from fn-10 FREE timeout).
</content>
</entry>
<entry>
<title>PRAMIN window translation + queue state preservation on Booter-unload</title>
<updated>2026-09-22T14:59:59+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-22T14:59:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=a7bda851fc7938555eaaf69b062f49efb9d90ece'/>
<id>urn:sha1:a7bda851fc7938555eaaf69b062f49efb9d90ece</id>
<content type='text'>
Fixes the BAR2 verify test failure (kbusVerifyBar2_GM107):
- GSP emulation thread now watches NV_PBUS_BAR0_WINDOW (BAR0+0x1700) for
  base/target changes and syncs the PRAMIN window (BAR0+0x700000) from the
  emulated BAR1 (vidmem) at (base &lt;&lt; 16). This makes PRAMIN reads return
  correct vidmem content for the BAR2 verify test.

Fixes the fn-10 FREE timeout during driver cleanup:
- gsp_emu_clear_boot_state no longer resets the GSP-RM queue state on
  Booter-unload kick. The driver sends cleanup FREEs AFTER the Booter-unload
  kick; resetting the queue here caused those frees to time out.
- Queue state is now only reset on: ENGINE reset (full GPU reset) or
  genuine queue death (insane writePtr). Both call gsp_rm_emu_reset
  explicitly.

Also fixes rmq tool ioctl encoding:
- Use _IOWR('F', nr, type) encoding for NVIDIA ioctls (was raw numbers)
- Open /dev/nvidiactl (not /dev/nvidia0) for RM_ALLOC
- Add NVOS64_PARAMETERS (48 bytes) for device/subdevice allocs

Verified: BAR2 verify test passes, INSTLOC regkey read, driver probes
past RmInitNvDevice bus init, reaches fn-10 FREE timeout during cleanup
(same as handoff's characterized blocker).
</content>
</entry>
<entry>
<title>kernel: floorsweeping masks + interrupt tree + WPR2 race + fn-10 handler</title>
<updated>2026-09-22T06:16:18+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-22T06:16:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=5eac589d9a7af8f8b321b00398575070b9a88513'/>
<id>urn:sha1:5eac589d9a7af8f8b321b00398575070b9a88513</id>
<content type='text'>
- STATIC_KGR_GET_FLOORSWEEPING_MASKS(0x20800a26): TU104 gpcMask=0x3f
  (6 GPCs), 4 TPC/GPC. numGpcs==0 killed krcWatchdogInit -&gt; RmInitAdapter
  bailed ('numGpcs &gt; 0' assert at kernel_graphics_object.c:191).
- CPU interrupt tree (osVerifyInterrupts): driver accesses VF window at
  virtualRegPhysOffset=NV_VIRTUAL_FUNCTION_FULL_PHYS_OFFSET(0xB80000)+off,
  NOT 0x1640 (was watching wrong offset). On LEAF_TRIGGER write, set
  LEAF/TOP pending bits + inject MSI-X so the sanity-test ISR runs -
  osVerifySystemEnvironment now passes.
- WPR2 race: clear boot state BEFORE CPUCTL=HALTED on Booter-unload kick
  so WPR2 is down when driver checks kgspIsWpr2Up ('WPR2 is still up').
- Dedicated GSP_RM_FREE(10) handler: echo NVOS00_PARAMETERS + status=NV_OK
  (proper free_v03_00 form). fn-10 timeout persists despite this -
  characterized as driver-side reply-matching issue, not content.
</content>
</entry>
<entry>
<title>kernel: CrashCat wayfinder suppression (prevent kgspHealthCheck loop)</title>
<updated>2026-09-22T03:38:30+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-22T03:38:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=9e776d0bd3a77217c700bf2fc538e32ac0d9173e'/>
<id>urn:sha1:9e776d0bd3a77217c700bf2fc538e32ac0d9173e</id>
<content type='text'>
kgspHealthCheck runs on every RPC drain; if the GSP falcon's DEBUGINFO
register (BAR0+0x110094) holds a valid CrashCat wayfinder-L0 signature
(0xdead), crashcatEngineGetNextCrashReport reads 'reports' from garbage
and loops forever in nv_open_q (which then can't poll RPCs -&gt; fn-10
timeouts). Force the wayfinder invalid - our emulated GSP has no
crashcat reports to offer.
</content>
</entry>
<entry>
<title>kernel: TLB invalidate auto-complete (MMU_INVALIDATE trigger) + fn-10 queue logging</title>
<updated>2026-09-22T01:08:06+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-22T01:08:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=55ffe494a749cf0ebf10b3146b8c59a4ab81aa5f'/>
<id>urn:sha1:55ffe494a749cf0ebf10b3146b8c59a4ab81aa5f</id>
<content type='text'>
- NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE (BAR0+0x30B0, TRIGGER=bit31):
  driver sets TRIGGER then spins in kgmmuCheckPendingInvalidates_TU102
  polling for it to clear. Our shadow held TRIGGER forever -&gt; nv_open_q
  hard-wedged in RmInitAdapter (TLB invalidate during dmaAllocMapping).
  Auto-clear the trigger bit in gsp_emu_poll_boot (instant completion).
- fn-10/47 handler logs hObjectOld + cmd_read/stat_write/drv_rp/stat_seq.
  Confirmed: drv_rp tracks stat_write 1:1 (driver drains cleanly, no
  lapping); frees complete; stat_seq increments per record.
- Health-check/crashcat loop (kgspHealthCheck -&gt; crashcatEngineGetNext
  CrashReport never returns NULL) is a SECONDARY symptom triggered by an
  RPC failure during RmInitAdapter - under investigation.
</content>
</entry>
<entry>
<title>kernel: Booter-Unload success + SM order table (unload/reload cycle works)</title>
<updated>2026-09-22T00:08:39+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-22T00:08:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=1e73a2e00c76e25e4ce2980e5d04a533b0c6158d'/>
<id>urn:sha1:1e73a2e00c76e25e4ce2980e5d04a533b0c6158d</id>
<content type='text'>
- gsp_emu_poll_boot generic SEC2 kick path: clear SEC2_MAILBOX0=0
  (success) - Booter Unload during GPU shutdown read a stale 0xff,
  failing the unload and killing the subsequent re-init ('Booter failed
  with non-zero error code: 0xff' -&gt; RmInitAdapter 0x40). A SEC2 kick
  after a completed boot is a GSP shutdown/reload: clear boot state.
  Driver unload/reload cycle (last close -&gt; RmShutdown, next open -&gt;
  RmInitAdapter) now works.
- STATIC_KGR_GET_GLOBAL_SM_ORDER(0x20800a22): TU104 topology 6 GPC x
  4 TPC x 2 SM = 48 SMs/24 TPCs on GR0. kgrStaticInit is init-critical
  (NV_CHECK_OK_OR_GOTO); zeros left numSm=0 and NVML spun on empty
  topology.
</content>
</entry>
<entry>
<title>kernel: Fix FIFO table fortify_panic + GSP boot-state reset on queue death + ISO fbRegion</title>
<updated>2026-09-21T23:04:05+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-09-21T23:04:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=6b686f70d8ff3e6340e8307c95847cd1eed4f2ae'/>
<id>urn:sha1:6b686f70d8ff3e6340e8307c95847cd1eed4f2ae</id>
<content type='text'>
- gsp_rm_handle_fifo_device_table: read baseIndex from the queue element
  buffer (req_data + hdr), not past the local 24-byte header struct -
  FORTIFY proved the old memcpy always overflows -&gt; fortify_panic killed
  gsp_emu_0 mid RmInitNvDevice (guest timed out on fn 76).
- gsp_emu_clear_boot_state: clear WPR2/RISCV/mailboxes/stage tracker and
  reset GSP-RM queue state. Turing guests produce no observable BAR0
  writes on unload, so the next probe's _kgspBootGspRm failed with
  'unexpected WPR2 already up'. Trigger on ENGINE reset and on detected
  queue death (insane writePtr jump / garbage element signature).
- GspStaticConfigInfo fbRegion[0].supportISO=1: memmgrCalcReservedFbSpace
  asserts some region supports ISO 'even with no display'; without it
  kdispStateInitLocked couldn't allocate clientChannelTable.
- .gitignore: scripts/git-push-vgpu.sh (local per-machine helper)
</content>
</entry>
</feed>
