<feed xmlns='http://www.w3.org/2005/Atom'>
<title>open-iov.git/kernel/gsp_sema_service.h, branch m32reorder</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=m32reorder</id>
<link rel='self' href='https://git.vgpu.io/open-iov.git/atom?h=m32reorder'/>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/'/>
<updated>2026-10-05T17:40:24+00:00</updated>
<entry>
<title>vgsp: guest GR forwarding backend and capture (gsp_phys_gr_forward, default off)</title>
<updated>2026-10-05T17:40:24+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-05T17:06:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=d3f061966bb9e23fdba7f6cc0aa231acdf31f36e'/>
<id>urn:sha1:d3f061966bb9e23fdba7f6cc0aa231acdf31f36e</id>
<content type='text'>
Add a default-off guest GR (compute) forwarding path so a guest CUDA
launch submitted on its GR channel can be executed by the physical GR
engine on the ladder channel, with fail-closed fallback to the host CUDA
bridge and the unchanged software release path.

- New module parameter gsp_phys_gr_forward (default 0) and accessor.
- New GR execution gate: boot_stage.rmcall_gr_exec_ok, latched only after
  a real GR submission logs REAL GR SEM OK; the backend refuses while it
  is unset.
- Sema capture: a completed 64-word inline QMD on a trusted, non-replay
  GR decode becomes an svc_gr_cand (push identity, decoded release0,
  parameter/program/pointer fields, up to 8 captured inline-write
  records); the CUDA bridge stays authoritative while the parameter is
  off and is reached in order forward -&gt; bridge -&gt; software release.
- Backend: gsp_phys_backend_guest_gr_submit() maps pages at their own
  guest VAs through fresh Tier-1 small-PT pages/PDE installs or relocates
  inline-captured pages to ladder shadow pages (Tier 2), builds
  SET_OBJECT + the inline-QMD method run + REPORT_SEMAPHORE on the
  compute subchannel, reuses the shared GPFIFO/USERD/doorbell publish
  tail (extracted from the CE submit path, CE bytes unchanged) and polls
  the QMD release and/or module semaphore, draining the epoch-gated
  fault queue on timeout.
- Sema wiring: GR requests reuse the INFLIGHT/hold/deferral machinery so
  the guest channel release applies only on the submit's success/failure
  edge; hold shims preserve the channel engine type.
- Counters and a work_gr state line plus a stats accessor.
- Bounds are fixed: 16 pages, 8 inline records, 64 QMD words; every
  pointer/size checked, pool exhaustion and stale mappings fail closed.
- New ABI layouts pinned with static_asserts.

Compile-only change: no device test performed.

(cherry picked from commit ae507e6f241c7e3498728f9d1ffc2d41ede5cd64)
</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>vgsp: host CUDA bridge + sema release recovery; greeneye simulator wave</title>
<updated>2026-10-03T18:05:38+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-03T18:05:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=cc79b478843f0230fe6aa8ecd822de7ba71c891e'/>
<id>urn:sha1:cc79b478843f0230fe6aa8ecd822de7ba71c891e</id>
<content type='text'>
- kernel: gsp_cuda_bridge (QMD launch capture, debugfs job/out/done, param+output resolution cached from inline writes), sema drain fixes (never hold/starve a channel), GR ring autopin + counter autoreg, per-page push reads, counter-derive gate; module builds clean
- tools/cuda-bridge: CUDA driver-API daemon executing mail/vadd kernels on the physical GPU, CUBB2/CBD2 v2 protocol, layout check + self-tests
- tools/guest-diag + tools/cuda-ab: scanner/pin fixes, victory push-only mode
- debug/risc-v-gsp-rm-vm: Phase S simulator wave (GSP device model, boot ladder, triage/re-demo harnesses, docs 30-41), GPGPU-sim scaffolding
- STATE-CURRENT/docs updates
</content>
</entry>
<entry>
<title>gsp-phys: relay verify hardening and counter exposure (default off)</title>
<updated>2026-10-02T12:41:17+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T12:41:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=ae441e307665e748d3d5bd9ec028b3262b216a95'/>
<id>urn:sha1:ae441e307665e748d3d5bd9ec028b3262b216a95</id>
<content type='text'>
- the work_relay state line now reports the real backend data-compare
  verify_fail plus a verify_transient count, distinct from the sema-service
  hold re-read verify_fail (previously the backend counter was dropped)
- a relayed copy whose host-side compare fails is re-read and re-compared
  once after a short delay; a transient mismatch counts as success and only
  a persistent mismatch falls back to the software apply as before
- the final-mismatch diagnostic now logs the semaphore target/payload/poll
  time, the first differing byte and 16-byte dumps of live dst, live src and
  a submit-time analysis material, flagging source mutation vs snapshot/dst
- the fault no_event path logs the post reason/return
All changes are behind the default-off relay path.
</content>
</entry>
<entry>
<title>gsp-phys: P6c C3 - relay forwarded-engine faults to the guest (default off)</title>
<updated>2026-10-02T12:07:10+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T12:07:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=22105e4ec738ac72d010d930222f6d8e62b4116c'/>
<id>urn:sha1:22105e4ec738ac72d010d930222f6d8e62b4116c</id>
<content type='text'>
New default-off gsp_phys_fault_relay: when a relayed copy times out, the
GSP-RM status queue is drained and the first OS_ERROR_LOG (0x1006) recorded
after the submission's doorbell is decoded (NOCAT corroboration), matched
against the ladder channel's runlist/chid, and delivered to the guest by
writing its channel notifier (info32=exceptType, info16=engine type,
status=0xffff) and posting the channel event. A late-release recheck skips
delivery if the engine actually completed, one delivery per hold, and the
existing software fallback always runs first, so no release or data is lost.

- pure decode helpers extracted from the status printers; prints unchanged
- status-queue walks serialized with a mutex; unmatched 0x1006 records are
  no longer silently dropped
- fault epoch snapshot at the doorbell prevents stale records from matching
- fault counters and faults:/fault_relay: state lines
- default-off gsp_phys_fault_inject debug knob forces the next relayed
  pair's source PTE to zero to produce a real engine fault
- pump notifier latch prevents clobbering a delivered fault

Live: injection run produced a real CE0 FAULT_PTE (0x1f @0x200000), decoded
with errString, chid/runlist matched, notifier delivered, software fallback
applied (applied+fallback==engaged), clean release; the guest RM reacted to
the delivered fault by tearing down its channels (faithful semantics).
Healthy control: faults all zero, relay requested=40 ok=40, smoke
matched=64/64, clean release. Caveat: the auxiliary event post failed
(no_event=1, no MSI-X) and the guest teardown means fault injection is not
smoke-compatible; the parameter stays off.
</content>
</entry>
<entry>
<title>gsp-phys: P6c C0+C1 - engine-authored guest CE semaphore (default off)</title>
<updated>2026-10-02T11:43:05+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T11:43:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=fe95eadb2bc1cb9af49814528edecbc5e497d6cd'/>
<id>urn:sha1:fe95eadb2bc1cb9af49814528edecbc5e497d6cd</id>
<content type='text'>
New default-off gsp_phys_relay: for a forwarded guest CE copy whose push
ends in a one-word release, the release page is resolved at forward time,
mapped on a fresh scratch line, and the real engine writes the payload
directly into the guest-visible semaphore page; the deferred-release hold
then verifies that page and skips only that record's software apply. Any
failure (unresolvable target, refused kind, pool exhaustion, poll timeout,
data mismatch, channel teardown) falls back to applying every release in
software, so a release is never lost or duplicated.

- new exported gsp_phys_backend_guest_ce_copy_ex() + relay counters;
  gsp_phys_backend_guest_ce_copy() behavior unchanged (wrapper)
- new work_relay: counters line in gsp-phys-state
- relay limited to CE channels and one-word absolute releases; counter
  and reduction releases stay on the existing paths

Live: param-off regression matched the wave-2 baseline exactly (req=101
ok=101 verify_ok=101, copy_skipped=119, smoke matched=64/64, relay zeros).
With the parameter on: requested=68 ok=67 skipped_sw=67, verify_fail=0,
resolve_fail=0, timeouts=0, smoke 64/64, and the engine-authored guest
semaphore was observed directly (sem=0x00000003 / 0x0000007e at the guest
page). One copy in 68 released its semaphore but failed the host-side data
compare; it fell back to the software apply (fallback accounting
applied+fallback==engaged) with the smoke green - residual to triage, which
is why the parameter stays default-off. A forced-unresolvable run
(requested=103, fallback=105, no relay submissions) kept the smoke green.
Every cycle: 5 power-domain locks held, driver rebound, WPR2 down, no rail
cycles, pstore empty, same boot.
</content>
</entry>
<entry>
<title>gsp-phys: P6b waves 1.5 and 2 - deferred release and hardware-authored guest copies</title>
<updated>2026-10-02T10:55:42+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T10:55:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=b75e316bd42cc34397e5f66b93f4c85181ad18c8'/>
<id>urn:sha1:b75e316bd42cc34397e5f66b93f4c85181ad18c8</id>
<content type='text'>
- new default-off gsp_phys_work_defer_release: a forwarded guest push's
  releases are recorded and its GPFIFO entry is held (no consume, no
  GP_GET write, no counter publish/stall) until the work item publishes
  completion; the service thread then delivers the releases, with a
  fallback on failure/timeout (500 ms cap enforced every pump pass)/
  pause/quiesce/channel-delete
- new default-off gsp_phys_work_hw_primary: the software copy is skipped
  for forwarded ops, so the physical engine authors the data; a once-only
  software copy runs before the releases on any hardware failure or when
  the request cannot be queued
- release-apply helpers extracted; exactly-once latches; channel-delete
  and teardown handling; counters and a work_guard state line
- live: deferred-release run engaged=75 applied=75 timeouts=0 with the
  full smoke green; hardware-primary run req=100 ok=100 verify_ok=100
  fallback=0 copy_skipped=119 copy_fail=0, smoke ALL OK 64/64 (guest read
  data the engine authored), with 19 fail-closed inline software
  fallbacks under single-inflight contention; a range-unregistered run
  proved the fallback (121 skipped copies, all recovered, smoke green)
- defaults off; the software path and all existing guards unchanged
</content>
</entry>
<entry>
<title>gsp-phys: P6b wave 1 - shadow-forward guest CE copies to the physical engine</title>
<updated>2026-10-02T09:04:44+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T09:04:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=6e7bad0791d9ff64531e1d670bfafa59a4c7fb63'/>
<id>urn:sha1:6e7bad0791d9ff64531e1d670bfafa59a4c7fb63</id>
<content type='text'>
- the sema service captures the first eligible copy per push from the
  software resolver's own operands (the real push shape mixes guest RAM
  with emulated-VRAM shadow addresses, including physical destinations)
- HPA resolution: guest RAM through the shared guest-RAM file page cache,
  emulated VRAM through the mapping of its kernel shadow
- new scratch page-table pool: 16 zeroed page-table pages with their
  page-directory entries built before any engine access, handing out one
  whole 128-byte GMMU PTE fetch line per copy pair (16 PTEs, 512 pairs
  per boot, never reused; a PTE written into an already-fetched line is
  not observed and there is no invalidate path)
- the backend submits the copy on the module-owned channel and verifies
  the result host-side; every miss falls back to the ladder shadow copy,
  and the software pump remains authoritative
- live (full smoke, both parameters on): req=42 ok=42 verify_ok=42
  verify_fail=0 fallback=0, guest payload roundtrip ALL OK 64/64,
  clean latched release; defaults stay off
</content>
</entry>
<entry>
<title>gsp-phys: freeze-safe release, boot-proof READY, and guest-wiring P2/P3/P5-wave1</title>
<updated>2026-10-02T06:07:52+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-02T06:07:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=c886760efda836b060fee03bfce852f16f04b5b8'/>
<id>urn:sha1:c886760efda836b060fee03bfce852f16f04b5b8</id>
<content type='text'>
Host-freeze fix bundle (validated 2/2 supervised cycles):
- power unlock now latches D0/D3cold by default (new gsp_phys_repower,
  default 0); releasing the claim can no longer power-gate the board and
  hard-freeze the host on resume
- bounded post-rebind readiness gate before dropping the locks; bounded D0
  settle/verify before the unbind
- READY means a live GSP-RM session: the async worker and the module-owned
  join only expose READY when init-done is seen and no unload was sent;
  otherwise the claim is released fail-open
- FWSEC reads DMEM0/IMEM back before STARTCPU and fails fast when the
  staging is not visible
- the claim harness leaves the board latched by default and takes
  --restore-power to opt back into the old restore

Guest-wiring:
- P2: generation-keyed fn65 static-config snapshot cache plus a default-off
  identity overlay (new gsp_phys_static_live) for name/short-name/VBIOS;
  the probe cycle runs once per backend generation at READY
- P3: default-off read-only RM_CONTROL forwarding whitelist (new
  gsp_phys_ctrl_forward) with emulated-handle translation to the adopted
  server handles and full emulation fallback
- P5 wave 1: default-off shadow execution of guest CE pushes on the ladder
  channel (new gsp_phys_work_forward) via a dedicated ordered work item;
  the ladder stage-4 submission is refactored into a shared bounded helper
  and the software release path stays authoritative

Live: module-owned boot to init-done, guest smoke ALL OK 64/64 with P2/P3
enabled, 514 shadow copies observed on the physical CE; all cycles released
cleanly with WPR2 down and no reboot.
</content>
</entry>
<entry>
<title>sema-svc: deliver UVM CE tracking releases without host-side pins</title>
<updated>2026-10-01T00:04:30+00:00</updated>
<author>
<name>Arthur Hanson Rasmusson</name>
<email>arthur@vgpu.io</email>
</author>
<published>2026-10-01T00:04:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vgpu.io/open-iov.git/commit/?id=7f84797323d1ce99e83f393b47ad5edcae5a34ed'/>
<id>urn:sha1:7f84797323d1ce99e83f393b47ad5edcae5a34ed</id>
<content type='text'>
The runtime client's registration stalled when no guest-side pin scanner was
running: the content rescue refused to run before the pool semaphore was
translated (its expected payload was unlearned), and unreadable CE entries
were consumed after two failed rescues ~40 ms apart, dropping the client's
wait. The push pages then could not be found within the entry's grace window.

- rescue: drop the learned-payload gate (the matcher only needs the channel
  rank and the release shape); keep unreadable CE entries pending for
  sema_ce_grace_ms instead of consuming after a fixed attempt count
- expected payload: re-learn from the pool whenever it advanced (a deferred
  release could land after the first read, leaving the expectation stale)
- matcher: require the expected payload exactly and validate the read-back
  stream carries it, so a recycled page of an older push cannot be pinned
- scan: descending full-range pass (the work allocations live in the high
  RAM block) plus a +/-512 MB near pass around the verified push-buffer base
- releases decoded with an untranslated semaphore are queued and applied
  when the page appears (svc_pending_add on both decode paths)
- a CE push that reads as a plausible stream but carries no release for the
  channel is re-routed through the rescue instead of silently consumed
- new module param sema_rel_recover (default off): after grace + rescue,
  apply the channel's expected tracking value so the client's wait clears;
  counter-visible as releases_recovered, distinct from sema_fake_rel

Evidence: fresh boot, real releases, no host watcher, no kprobes - the six
UVM CE first pushes are found by content rescue, their releases applied, and
the client reaches cudaGetDeviceCount rc=0 (it then waits for the third
push, which this change routes to the rescue).
</content>
</entry>
</feed>
