<feed xmlns='http://www.w3.org/2005/Atom'>
<title>open-iov.git/kernel/gsp_phys_gpu.c, branch dual</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=dual</id>
<link rel='self' href='https://git.vgpu.io/open-iov.git/atom?h=dual'/>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/'/>
<updated>2026-10-15T21:53:52+00:00</updated>
<entry>
<title>vgsp-dual: stage B+C minimal per-mdev separation (G1-G3, G5, G6, G7, G8a)</title>
<updated>2026-10-15T21:53:52+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-15T21:53:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=81c11ca09adf85bd314f7406a8e0d7d637726a80'/>
<id>urn:sha1:81c11ca09adf85bd314f7406a8e0d7d637726a80</id>
<content type='text'>
Goal 1.0: two mdevs + two QEMU guests running CUDA simultaneously.
Single-mdev behaviour is kept identical: the legacy guest-RAM record
still serves the first/only open mdev, the channel table degenerates to
the historical key, and the session flush fires at the same
last-channel-closed transition.

- G6: guest-RAM backing {file, path, ranges} per mdev (legacy record +
  up to 4 vgpu-bound records); debugfs gsp-phys-guest-ram accepts an
  mdev UUID as an extra first token and keeps the 4-token form; records
  released on mdev cleanup and physical release.
- G7: gsp_phys_gpa_to_hpa_vgpu(vgpu, gpa, *hpa); NULL keeps the
  historical first-open resolution. Forwarding operands pass the
  request's vgpu; the single-guest boot-ladder pin passes NULL.
- G1: the sema-service thread services every open mdev each pass.
- G2: channel table keyed by (vgpu, h_object); per-guest ranks;
  counter/scrub/opdef/pump snapshot+writeback matches per vgpu;
  scrubber records per guest.
- G3: per-guest session records drive the flush; the shared learned
  tables (staged G4) are only flushed when no guest has live channels.
- G5: hold/abort keyed by (vgpu, handle); dead-owner guards on the
  hold resolution paths; single-inflight serialization kept.
- G8a: guest-GPA pin refused while more than one mdev is open.

Build: make -j8 clean success (vgsp.ko). No module load. See
DUAL-REPORT.md for the per-item status and live-validation plan.
</content>
</entry>
<entry>
<title>vgsp-gr: m152 scratch-PT alias cache + extended pool; m153 outcome-verifying launch retry</title>
<updated>2026-10-15T14:20:13+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-15T14:20:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=48a8089ed3c4892c2577db2da815e6731b882045'/>
<id>urn:sha1:48a8089ed3c4892c2577db2da815e6731b882045</id>
<content type='text'>
m152: the Tier-2 shadow alias pool consumed one never-reused 128 B fetch
line per mapping per launch (512 lines/boot), so a normal launch mix
exhausted it permanently: every later launch that needed a new mapping
was refused (the deterministic r152 'launch refused: no Tier-1 mapping'
loop). Two fixes: (a) an HPA-keyed alias cache in map_shadow_locked that
returns the existing never-rewritten VA for a page already mapped, so
repeat launches of the same buffers/sem pages consume nothing; a hit
reports line_out = ~0 so contiguity bookkeeping never extends an old
line; (b) a 48-window extension pool at VA 0x04000000 (PD0 indices
32..79, one 48-page PT chunk) raising capacity to 2048 lines/boot.

m153: the intermittent per-boot mis-execution classes (engine wrote
nothing; or wrote into a lower operand window while the output operand
stayed untouched - both complete with qmd_rel/ch_rel satisfied, live
evidence in r152 smiley: passes wrote b into the a window / nothing /
correct-after-10s-retry) are now detected by the m151 retirement wait
and retried: refill the bounce window from the guest inputs, re-publish
the same method block on a fresh ring entry, re-issue schedule, re-poll,
re-wait - bounded by the timeout path's attempt budget. Gate param
gsp_phys_rmcall_gr_nowrite_retry (default 1).
</content>
</entry>
<entry>
<title>vgsp: m113 - re-register the VAS page directory after planting data (re-commit probe)</title>
<updated>2026-10-07T19:33:31+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T19:33:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=d9c2545fac3c37c57e56b892ed3d0e054d8f6816'/>
<id>urn:sha1:d9c2545fac3c37c57e56b892ed3d0e054d8f6816</id>
<content type='text'>
All late engine-tree writes are invisible to the SM walker (only the
commit-time snapshot resolves); the mail injection at a main-window fresh
slot also fails (m112). Probe whether UNSET+SET_PAGE_DIRECTORY on the
ladder VAS after planting forces the server walker to re-snapshot the tree;
gated by gr_recommit.
</content>
</entry>
<entry>
<title>vgsp: m106 - pre-install the data PT window pool in stage 3 (pre-commit)</title>
<updated>2026-10-07T19:05:08+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T19:05:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=d2848c109761e3ccde81a742f4569730254031f8'/>
<id>urn:sha1:d2848c109761e3ccde81a742f4569730254031f8</id>
<content type='text'>
Post-commit UPDATE_PDE_2 installs are accepted (status 0x0) but ineffective
(m94's scratch windows, m101-m105's reloc windows: the SM never resolves
them), while the stage-3 ctx-window installs are honoured. Add a fixed
32-window pool at GSP_PHYS_RMCALL_VA_GR_DATA_BASE (0x100000000 + k&lt;&lt;21,
inside the server-managed region), each backed by a module PT page
installed through UPDATE_PDE_2 during stage 3; the engine data map then
only writes leaf PTEs into those fresh PT pages at launch (the P6b-proven
'direct leaf write into a walker-installed fresh table' pattern). The mail
injection uses the reserved last window (k=31); service data windows cap
at 31 and use the same fixed layout.
</content>
</entry>
<entry>
<title>vgsp: m104 - inject the mail_kernel module-data base when bank-4 is empty</title>
<updated>2026-10-07T18:59:19+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T18:59:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=6351a2231ee58317d3c7a237192773b46618399c'/>
<id>urn:sha1:6351a2231ee58317d3c7a237192773b46618399c</id>
<content type='text'>
The forwarded mail_kernel reads __device__ kMail through c[0x4][0x0] (the
driver-provided module-data base), but the guest's bank-4 page content is
zero in the launch (the driver's value never lands in the resolved page).
With gr_mail_patch set, when bank 4's first 8 bytes are zero, allocate a
module page holding the demo message, map it at server-managed VA
0x11ff00000 (UPDATE_PDE_2, inside [0x100000000,0x11fffffff)) and point
c[0x4][0x0] there. The kernel then reads the message from device memory and
writes out[i] through the already-relocated bank-0 pointer; vadd (params
only) becomes the real relocated-data acceptance test.
</content>
</entry>
<entry>
<title>vgsp: m96 - gr_pte_kind: set the Turing v2 PTE KIND on the window-0 shadow pool</title>
<updated>2026-10-07T17:55:54+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T17:55:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=118b22c288e75ee6da6e3edb7318270a5a2ee0f7'/>
<id>urn:sha1:118b22c288e75ee6da6e3edb7318270a5a2ee0f7</id>
<content type='text'>
UVM's Turing PTE maker sets KIND=GENERIC_MEMORY (0x06) in PTE bits 63:56
because PITCH no longer exists on Turing (uvm_turing_mmu.c:32-34,106;
NV_MMU_PTE_KIND_GENERIC_MEMORY=0x06, NV_MMU_VER2_PTE_KIND=63:56). Our
shadow PTEs encode kind=0. The SM I-fetch refuses the kind-0 PTE with
MMU_NACK while the FE tolerates it, so gr_pte_kind (default 0) selects the
KIND for the window-0 pool. Also log the VASPDB root DMA at
SET_PAGE_DIRECTORY time (settles whether the SC PDB the server programs is
our chunk).
</content>
</entry>
<entry>
<title>vgsp: m95 - program GPC MMU_CTRL from PFB MMU_CTRL (RM grInitGPCMmuPRIRegs copy)</title>
<updated>2026-10-07T17:28:37+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T17:28:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=450ddaeb41e57846692e1c6eaa84185d9fd2f7b1'/>
<id>urn:sha1:450ddaeb41e57846692e1c6eaa84185d9fd2f7b1</id>
<content type='text'>
The real RM initialises every GPC's NV_PGPC_PRI_MMU_CTRL (0x500880 +
gpc*0x8000) from NV_PFB_PRI_MMU_CTRL (0x100C80) using the TU102
hub-to-GPC matching fields (VM_PG_SIZE, COMP_FAULT, MISS_GRAN, CACHE_MODE,
USE_PDB_BIG_PAGE_SIZE, ATOMIC_CAPABILITY_MODE, ATOMIC_CAPABILITY_SYS_NCOH;
ext-tree gr_gk104.c:3340-3380 + gr_tu102.c:229-238). Our ladder never
programmed it (grep-verified). The m93 INST dump shows the server's SC(0)
PDB carries USE_VER2_PT_FORMAT + BIG_PAGE_SIZE=1, so a GPC/hub MMU_CTRL
mismatch is a candidate for the GPC-side walker refusing the SM I-fetch
with MMU_NACK while hub-side reads resolve. Gated by
gsp_phys_rmcall_gr_gpc_mmu_init (default 0); sampler now reads
GPC0/GPC1_MMU_CTRL (0x500880/0x508880) and PFB_MMU_CTRL (0x100C80).
</content>
</entry>
<entry>
<title>vgsp: m91 - gsp_phys_rmcall_gr_ptr_guest: keep QMD pointer pairs at the guest VAs</title>
<updated>2026-10-07T17:12:06+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T17:12:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=1b44cef6c6ae6c9889950f915682b749855fbe6a'/>
<id>urn:sha1:1b44cef6c6ae6c9889950f915682b749855fbe6a</id>
<content type='text'>
The m90/m91 trap decoded the SM I-fetch failure precisely: GPC0/GPC1 TPC0
SM0 WARP_ESR ERROR=0x20 ADDR_ERROR_TYPE=0xb = MMU_NACK, PC=0x109880 (the
rewritten window-0 shadow program VA). The FE reads the same small-PT line
fine (the forwarded inline QMD in the qmdwin page is processed to CWD
ACTIVE), so the SM walk is not using the channel/ladder VAS the shadow
lives in - it appears to use the guest subctx page directory (instance
SC_PAGE_DIRECTORY_BASE 0x10956b000), which maps the guest VAs the real
client's captured QMD points at, and not our window.

Add gr_ptr_guest: when set, the forwarded launch leaves the QMD pointer
pairs (param w32/33, program w48/49, prefetch w8/w31) exactly as the guest
driver wrote them (as the real driver's captured QMD carries), and only
relocates the QMD page itself (qmdwin, a proven FE read). Shadows are still
copied for logging but unused.
</content>
</entry>
<entry>
<title>vgsp: m86 - sticky gsp_phys_rmcall_gr_override_hex module parameter</title>
<updated>2026-10-07T16:03:02+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T16:03:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=8b1198126605dc29a49b1dfe728409d2fa25a5ab'/>
<id>urn:sha1:8b1198126605dc29a49b1dfe728409d2fa25a5ab</id>
<content type='text'>
The override blob can now be supplied at load (hex string, &lt;= 1 page) and is
parsed at the first forwarded launch, so the minimal-kernel experiment no
longer depends on a debugfs write racing the guest's launch. Also observed in
the m86 attempt: after many failed launches the forwarded ring desynced
(USERD GP_PUT rewound to 1 while the engine's GP_GET was 513; IQ2M sentinel
intact, no FE fetch) - a fresh boot is required per experiment.
</content>
</entry>
<entry>
<title>vgsp: m84 - stage-4 CE read-back of the GR context image header and VEID0 subctx header</title>
<updated>2026-10-07T15:35:52+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-07T15:35:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=4148a6b1e3c0c4c4cc68739315d6dc9c6a8d3233'/>
<id>urn:sha1:4148a6b1e3c0c4c4cc68739315d6dc9c6a8d3233</id>
<content type='text'>
gsp_phys_rmcall_gr_img_probe=1: after the stage-4 GR sem proof the ladder
re-binds the rmcall channel to COPY0, copies image VA 0x2200000 and the subctx
header VA 0x22f3000 into the DST sysmem chunk through the real CE, dumps the
header pointers, and re-binds GR0. This is the missing read path for the
FBMEM context image (the GPC exception at QMD activation needs the image's
PATCH/PM/ZCULL/priv-map/global pointers and the subctx header content to be
compared against the expected VAs).
</content>
</entry>
</feed>
