summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAge
* vgsp: RM-record 3D attach + inside-run C597 openers for the direct-GL ↵Arthur Hanson Rasmusson5 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | channel (eng23, mechanism validated) The direct-GL (GZDoom/glx) channel family 0xbeef01xx never opened a C597 section because its class bind is channel-side: the client allocates TURING_A (0xc597) with hParent = its own channel (measured: alloc 0xc597 h=0xbeef9097 parent=0xbeef0100 client=0xc1d00013) and never re-emits a SET_OBJECT push, so the section recognizer's sticky-attachment gate (svc_gl_att_accept_run) dropped every push. The X lane binds inline in its init push and was unaffected. - gsp_rm_emulation.c: report the 0xc597 allocation's hParent to the sema service (gsp_sema_service_gl_attach), which applies it as the sticky 3D attach on its own thread (pending-slot queue; no cross-thread writes to the attachment tables). - gsp_sema_service.[ch]: the queue + drain (svc_thread pass), and accept the inside-run opener shapes on attached channels: the direct-GL client emits NVC597_BEGIN (0x1618) and the RT-setup family (0x840) as methods INSIDE multi-method INC runs (measured: run addr=0x80c count=256 covers 0x840..0xc0c; census decoded method=0x1618 op=1 from a run payload), not as the one-word IMMD form the X lane emits. - Also carries the eng22-rescue scan-cap widening (0x4000000 -> full 2 GiB shadow; observed live: "no content-gated window in 0x80000000 shadow"). Validated live (c335/c337/c338, receipts /tmp/opencode/eng23-receipts-c331.txt): - RM-record attach fires and applies for 0xbeef0100 (c335 12:49:04, c338). - sections now open (c337) and capture (c338) on 0xbeef0100 incl. the 59556-B setup push and the 6400-B draw push (src=draw-synth). - first GR LAUNCH submitted for 0xbeef0100 (c338 13:01:58) - fails at the physical QMD release (qmd_rel=0xc0ffee01 want=0x600df00d); new frontier. - px0 still 00000000; mission not launched. A/B control: the same X-lane lottery behaviour was reproduced with the pre-change module (c333), so no X-lane regression is attributable here.
* tools: add sema_gr_fb_push=1 to params-r1624 (eng21: required for the ↵Arthur Hanson Rasmusson6 hours
| | | | FB-shadow push rescue at insmod)
* docs(wiki): refresh status to 436cbf9d - DDX/X-stability walls closed, ↵Arthur Hanson Rasmusson6 hours
| | | | sections execute, push bodies decode above 10 GiB; remaining wall = direct-GL payload delivery (setup push recycled; draws 0x4250000)
* vgsp: content-gated FB-shadow push rescue for recycled client pushes (eng20, ↵Arthur Hanson Rasmusson6 hours
| | | | | | | | | | | | | | | | | | end-to-end validation pending) The direct-GL client's one-shot 59,556 B setup push (VA 0x4001004) reads zero at decode time: the live page is recycled before our decode runs, so no C597 bind attaches for h=0xbeef0100. The rescue recovers the push body from the FB shadow with strict content gates: reject fill windows (require >=2 multi-word INC runs + >=8 distinct headers), scan at the push VA's in-page offset (0x4041004 starts 4 B into a page), and log the channel handle. eng20 refuted the unregistered-VAS hypothesis: the payload pages DO walk via VAS 0xbeef0300 (0x4000000->pa=0x342ead000, 0x4001000->pa=0x342eae000, consistent delta). Also found: sema_gl_xlate (absent from params-r1780; default 0) gates every C597 section-recognition site - with it on, the lane produced its first C597 captures (127x c305, 20x c307). Validation cyclic c308 (guest init panic) / c309 (QGA wedge) blocked; no observation yet. Unvalidated end to end.
* STATE-CURRENT: hourly check-back snapshot (2026-11-13 11:12:01)Arthur Hanson Rasmusson7 hours
|
* vgsp: extend the live PA acceptance bound to the registered guest-RAM top ↵Arthur Hanson Rasmusson7 hours
| | | | | | | | | | | | | | | | (svc_pa_max/svc_push_pa_ceiling) The direct-GL client parks its VAS page directory and push pages in the 4-14 GiB high RAM band while the runtime bound stopped at 10 GiB (param/compile), so svc_ap_ok rejected every walk read above 10 GiB before vfio_dma_rw could answer: the client ring walk reported 'L0 read fail' / 'walk rc=-2' on the one boot the RAM content scan latched the real ring (c296), and the push bodies stayed unreadable (src=3 window garbage / src=255). svc_pa_max() now never shrinks below the registered guest-RAM top (sanity-clamped to the scan max), and svc_push_pa_ceiling() floors on the same live bound. c297 (first boot with the fix): 'RING-VAS h=0xbeef0100 gpfifo=0x4020000 mapped by VAS 0xbeef0300 (pdb=0x110aae000) -> pa=0x23771f000' and pushdec 'src=4 plausible=1' with the read ceiling witness ceil=0x380000000.
* vgsp: reject the dense-lookalike class in svc_gr_ram_ring_scan ↵Arthur Hanson Rasmusson8 hours
| | | | | | | | | | | | | | | | | | (entry0==entry1 gate) The GL client ring content scan admitted the lookalike page measured at pa 0x10a828000 / 0x10ad3e000 (dword 0x04000100 repeating) whose entry0 and entry1 decode identically (va=0x4000100 len=262144) and which passed every window/terminus gate. The pump then read a phantom 256 KiB push at VA 0x4000100 forever (sema-rdw rc=-2, sema-entry: unread, unregistered submissions=0; c271/c285), poisoning the client-VAS verify chain. A real ring does not repeat one entry verbatim in slots 0/1. Partial validation: c288 (fixed module) resolved the REAL ring pair via the VAS (pa=0x235f7c000, entry0 va=0x4000000 len=2236) and decoded real client pushes (submissions=15, CB-DIAG match=67). End-to-end pixel validation (gl_frames px0 != 0) is still pending; c286/c287 did not exercise the scan (no channel created).
* vgsp: exclude the 0x40706c read sentinel from the pre-replay CWD-clear ↵Arthur Hanson Rasmusson9 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | predicate; add sema_gl_cwd_clear (A/B knob) FALSIFIED NOTE (eng16, c271/c272): the eng15 lead that the always-fire CWD-clear rode on the 0x40706c sentinel and caused the zero-store wall is FALSIFIED. A/B on the same launch shapes (h=0x1000013 push=0x1200107e4 words=50 / push=0x1200106bc words=53): - c260 (old code, clear fires 7x/boot on the sentinel): wrote=0. - c272 (clear fully off, sema_gl_cwd_clear=0): wrote=0 both launches, pbfetch=block end, intr0=0 - identical to c260. - c271 (predicate fixed, knob on): 0 CWD-CLEAR all boot (the sentinel no longer arms it; esr=80000000 / grfifo pending counts are clean). The change still lands because the old predicate was a bug either way: 0x40706c reads 0xbadf5040 always (read-only hardware sentinel; eng15 write test 0x0 -> 0xbadf5040), so every stream3d launch ran a TSG preempt/resched + MME latch wipe before a noQMD replay that never re-loads context - an unjustified per-launch context reset. The zero-store wall is unchanged and now localized: the stream3d lane only replays X DDX setup-only windows (c272 decode: INC6@0x840 SET_COLOR_TARGET_A(1) VA=0x0c000000 1920x1080 X8R8G8B8, INVALIDATE_*, INC5@0x180 LINE_LENGTH_IN/OFFSET_OUT - no BEGIN 0x1618 / no draw 0xd74 / no CALL run), while the pbuffer client's own push entry (0xbeef0100 va=0x4000100 len=262144) is unreadable host-side (rc=-2, channel unregistered, submissions=0) - so no draw reaches any lane.
* vgsp: eng15 diagnostics - 3D window 48->256, WINPROBE 64->2048, ↵Arthur Hanson Rasmusson10 hours
| | | | | | | | | | | | | | | NOWRITE-PBDMA dump Diag-only commit (eng15 receipts: /tmp/opencode/eng15-receipts-c260.txt). - gr3d_win_log 48 -> 256: keep the raw 3D window dump for the gl_frames-era replays (the 48/boot budget was consumed by earlier launches). - winprobe_log 64 -> 2048: keep WINPROBE samples for every stream3d launch. - NEW NOWRITE-PBDMA dump (stream3d-only, 256/boot): all 12 PBDMA instances' intr0/gp_put/pbfetch/off-in-block/hdr/pbcnt at the zero-write verdict. Produced the decisive c260 data: pbfetch == 0x101000+words*4 exactly (deposit fully fetched per launch), intr0=0. No behaviour change; logging only.
* vgsp: CB parser decode fix + pre-replay FE context clear attempt (cwd3 latch ↵Arthur Hanson Rasmusson12 hours
| | | | | | | | | | | | | | | | | | | | | | | | | survives; zero-store persists) (a) svc_gl_cb_upload_scan decode now follows the class definitions (cla16f.h: method 11:0, subchannel 15:13): addr=(hdr&0xfff)<<2, subch=(hdr>>13)&7; selector B/C swapped (0x2384=B=ADDRESS_UPPER high dword, 0x2388=C=lower, cla097.h); 0x238c runs apply [offset][constants...] inline data. CB-DIAG prints subch. Other classes untouched. (b) Pre-replay CWD poison clear for the stream3d lane: new gsp_phys_gr_cwd_clear_locked() (checks 0x404490/0x40706c/0x400504 for 0xbadf, runs the wedge recovery's bounded TSG preempt/resched re-arm + shared latch wipe) before build_gr_launch; once per launch, stream3d+sema_gr_wedge_recover gated (CUDA/CE unaffected). Validation (c250-c254, rich args, ladder armed): the re-arm probes green ('WEDGE-REARM probe rc=0 (engine ALIVE)') but the cwd3 latch does NOT move ('CWD-CLEAR after re-arm ... cwd3=badf5040') and wrote=0 persists (0/1024) with the 0x1528 trap gone under sema_gl_shader_exc=0 - clause (b) is falsified as sufficient: the poison is not the TSG/PBDMA context the re-arm touches. CB-DIAG on these draws shows n3800/n39c8/n2390=0 because bit 12 is 0 on that stream (old/new decodes identical there) - the parser fix stands on the class definition. X regressed to the DDX DMA wall on these cycles (DMA-init 0x51 + per-start SIGSEGVs), so clean gl_frames windows were rare.
* vgsp: admit short MME preludes and drop the 0x22c init method from replay ↵Arthur Hanson Rasmusson14 hours
| | | | | | | | | | | | | | | | | | | | | (stream3d zero-write fixes) NOWRITE decode (eng11): wrote=0/tracked=1024 is the retire scan; fe_esr= 0x80000000 is the CLEARED FE latch (not a live fault); trap=0x8000022c/... is PGRAPH_TRAPPED_ADDR naming method 0x22c (C597 SET_GO_IDLE_TIMEOUT, init-only, emitted once at channel init) - the FE traps on the replay of that init write and never reaches the draw. The c220 stack also showed a second defect: 'MME-PRELUDE deferred (window=20 prelude=13 sa=0 cap=2048)' -> MME-REGS esr=badf1201 miss=1 pc=513 -> grfifo poison -> warm sem rc=-110. Fixes (gsp_phys_booter.c): - A: admit a captured prelude shorter than 24 words (pl_room is clamped to pl_n, so pl_room >= 24u could never be true for preludes < 24 words and they were deferred forever). - B: add addr == 0x022c to gsp_phys_rmcall_gr_win_drop_auto_match() (knob sema_gl_win_drop_auto, default 1): drop the replay-hostile init write like the existing 0x10c/0x1b0/0x5e0/0x1b00 triggers. Validation pending (c221 no-capture lottery, c222 X death before the live A/B); receipts: eng11-*.
* vgsp: serve word-34..47 section pages from their resolved PAs; seed the ↵Arthur Hanson Rasmusson15 hours
| | | | | | | | | | | | | | | | | | | | | | | | | pointer pairs (n_data 0->1024) The final-pixel-wall data window: svc_gr_data_fill discarded a candidate page that HAD resolved in gr_pages (launch_internal blanket skip: c203 evidence 'page[2] va=0x120400000 pa=0xa00000 ap=2 word=34' + '10 candidate ptrs, 0 pages resolved; 7 dropped' -> GR-DEC n_data=0), and the stream3d lane (qmd=0x0) never seeded the capture's decoded operand pairs (inline-QMD words 34..47) as candidates. Serve word-34..47 pages from their resolved gr_pages PA (li_pa, span=1; word 32/48/49 stay excluded as before) and seed the pointer pairs from a request-carried copy (race-free vs the capture ring). Live proof c215: 'li cand va=0x120400000 word=34 pa=0xa00000 ap=2' -> 'GR-DEC n_data=1024' (was 0). Residual: the 1524 B first-frame's pointer pages are not yet resolvable at that instant (n_ptr_req=5 seed_add=0; frames 2+ resolve 1024) - resolver timing, documented. Also documented (no change): the copy-out refusal for dst=0x120700000 (the GL client's fixed-CB page) falls through to the forced-seed path and is benign for pixels; the TRUE px0 blocker is engine-zero-write: every stream3d launch ends 'NOWRITE-CONFIRMED ... n_data=1024 tracked=1024 wrote=0' + 'NOWRITE-REGS fe_esr=0x80000000 trap=0x8000022c/00000800/00000000' even with the full RT window (SURF-PRELUDE target=0xa000000) - the engine executes but stores nothing.
* tools: cycle-r1780.sh arms the GR lane per boot (rm-call ladder + guest-ram ↵Arthur Hanson Rasmusson16 hours
| | | | | | | | | | | | | | | | | | | | | | activation) Post-reboot cycles lost the pre-reboot 'arm the GR lane' steps, so gsp_phys_backend_gr_ready() stayed false (rmcall_gr_exec_ok=false) and every captured GL section died SILENTLY at svc_gr_request's first gate (c198: work_gr req=73 fallback=73 ok=0 refused=73 submitted=0 exec_ok=0; an ftrace run counted 2282 silent svc_gr_request calls). After 'guest agent up' the cycle now runs, with warnings only (never fails the cycle): echo 5; echo 3; echo 4 > gsp-phys-rm-call (order matters; 4 alone fails by design) echo '<mdev> /dev/shm/vgpu-guest-ram 0x80000000 0x0 0x300000000' > gsp-phys-guest-ram and logs both to <tag>-ladder.txt. Validated c203: 7x 'GR LAUNCH submitted' + 5x 'GUEST GR LAUNCH OK' from the captured GL sections (zero ever before), exec_ok=1, work_gr ok=4 backend_ok=4. Residual: gl_frames still black - GR-DEC n_data=0 dropped=24 (the section's data window resolves empty) and 'sema-grce: owner-vas h=0xbeef0100 ... dst=0x120700000 unmapped; cross-VAS walk refused (client-private page)' for the client copy-out operand - the old n_data/dstpend frontier, now with the forward live.
* vgsp: DDX latch adoption grace + last-proven-block parking (X now lives >10 min)Arthur Hanson Rasmusson16 hours
| | | | | | | | | | | | | | | | | | | | | | | | | Thread A of the X longevity wall, validated c195/c198 (rich args + tick): - Adoption grace: gr_ram_userd_adopt_at stamped at every DDX fresh-adopt site; svc_userd_ddx_reprobe refuses a speculative switch within 1 s of an adopt (kills the c190/c197 same-pass cascade to frozen lookalikes). - Clause 3: the last CONFIRMED block is parked (pa/as/put/probes) on every DDX confirm; svc_userd_ddx_park_probe checks it first in the re-probe and discovery scan and prefers it when its PUT advances across two probes (kick excluded, half-ring bound, reset re-syncs). Receipts: c195 X GREEN >10 min with 0 DMA failures ('shape scan fb 0x8f0000 -> CONFIRMED 2->6 at +63 ms, zero SWITCHED/DEFERRED/REJECTED all boot'); c198 GREEN >2 min likewise (+69 ms confirm, zero switches). Residual (documented): the RAM-scan 'LIVE' vote can still admit pool lookalikes on a first generation before any block is parked; the grace only delays that switch. Thread B (documented, no change): in c195's green window gl_frames still reads black (px0=0, ~12 s/frame) although the rich args capture the modern-GL sections ('sema-gl: 3D stream marked', 'section captured len=1524' + 2 draw sections, prog-images vs=1408 ps=384) - ZERO GR LAUNCH and zero readback/copy-out lines; the beef0100 channel re-registers every ~13 s with submissions=0. Modern-GL work is section-captured but never executed/forwarded - the next frontier.
* vgsp: refuse DDX-family garbage USERD candidates (get>put) and bound the ↵Arthur Hanson Rasmusson17 hours
| | | | | | | | | | | | | | | | | | | | | | | speculative CONFIRM jump Wall (a) garbage-admission fix, validated c190-c194 (rich args + tick): - svc_gr_ram_userd_scan and the FB shape scan (svc_chan_userd) now refuse get > put for the DDX family (svc_userd_ddx_family), dropping the entries>1024 exemption that admitted c181's 'put=1 get=288190567' block; bounded refusal logs ('RAM scan REFUSES ...', 'userdp ... REFUSES fb ... (DDX get>put; c181 garbage class)'). - The pump's speculative CONFIRM bounds a non-wrap DDX (non-kick) forward PUT jump to gpfifo_entries/2 (mirrors the wrap bound); a runaway jump like c181's 'put 1 -> 1170688059' now falls to the DEFERRED/REJECT ladder ('forward PUT jump REFUSED ...'). Kick any-step and wrap paths unchanged; SYS/CE/UVM untouched. Receipts (5 cycles): 146 refusal lines (80 RAM, 66 FB), ZERO huge-jump confirms (all 16 confirms are real small steps), real blocks serving 25+24 submissions from pristine fb 0x8f0000 and RAM 0x11ae6e000. Residual wall (a): a same-pass re-probe switch to a frozen lookalike (c190) and a late 'Failed to idle DMA' at 60-130 s of X life; gl_frames still reads black (px0=0, ~12 s/frame) in the windows it ran (c193/c194).
* vgsp: flip-event delivery defaults to assoc+strict (clears Flip event ↵Arthur Hanson Rasmusson18 hours
| | | | | | | | | | | | | | | | | | | | | | | timeout); DDX latch reset clauses Wall (b) 'Flip event timeout on head 0' fix (validated c171): NVKMS/kernel- callback events register hSrcResource=0, so every display UPDATE completion rode the all-events shotgun (6-7 POST_EVENT records each), the guest's status-queue read cursor fell 20-44 slots behind (rc=-11 ring-full bursts) and flip records arrived past the 3 s NvDrm window. Default the r1765 pair ON - gsp_rm_ev_assoc (hSrc==0 -> alloc-parent channel) and gsp_disp_events_strict (armed UPDATE posts only to that channel's events, no fallback) - the exact combination r1771 measured as '0 flip WARNs'. Validating cycle c171: registrations carry real sources (hEvent=0x1007a hSrc=0x1001b etc.), UPDATE posts are exact 1:1 (posts=27), WARN count 1 for the boot, serial timeouts=0 (c160 pre-fix: 34). Both stay runtime-writable. Also stage the gsp_sema_service.c candidates for wall (a) (the later-DMA 0x51 is a consequence of 'Failed to idle DMA' on a recycled channel): the served-refusal in svc_userd_ddx_reprobe now exempts a latch reset to put==0, and the put-reset latch keep extends to the DDX family (was kick-only). These clauses target c171's observed reset/junk-adopt sequence; validation pending on a roll where wall (a) is otherwise survivable.
* vgsp: display engine re-seeds GET on a driver ring wrap (fixes the ↵Arthur Hanson Rasmusson19 hours
| | | | | | | | | | | | | | | | | | | | nvidia-modeset GET-past-PUT wedge) Root cause of the post-ScreenInit Xorg kernel-mode spin (sysrq-t: Xorg R-state inside nvKmsIoctl -> nvkms_yield, utime frozen, stime 100%): the emulated display engine (core channel c57d) held GET=0xcd8 PAST PUT=0xcc8 for 50 s. gsp_disp_run only publishes GET when the parse reaches PUT exactly (by design, per its r1630 comment), so when the guest driver wraps/resets its push ring (PUT steps backward via nvEvoMakeRoom) the stale consumed can never resync and NVKMS spins forever. When put < s->consumed (wrap/reset), re-seed consumed=0/last_put=0 and republish GET=0 so the wrapped pushes are re-parsed from the ring base; the driver's PUT is authoritative. Validated c160 (rich args): bar0 channels now read PUT==GET (core 0x590, window c57e 0xe2c) with no wedge and flips parse (UPDATE armed=1 -> FINISHED posts=32..34); X advances past the spin and served xdpyinfo once. Remaining walls (next): the push-buffer 0x51 NV_ERR_NO_MEMORY allocation lottery and 'Flip event timeout on head 0' (Xorg D in nv_drm_atomic_commit).
* vgsp: DDX re-probe stops once the latch has served (stops lookalike switch ↵Arthur Hanson Rasmusson19 hours
| | | | | | | | | | | | | | | | | | thrash) In svc_userd_ddx_reprobe, refuse to switch while the current latch has just delivered decoded entries (ch->submissions != gr_ram_userd_latch_sub), the same 'served' criterion the pump's DEFERRED clause uses. The switch path resets defers=0, so a defers-based guard would have stopped only the first of c141's six switches; forward-only nput>oput is semantically wrong for DDX generations (a fresh block starts with a tiny put) and would lock onto the junk maximum. Validated c150-c153 (rich args + tick): latch SWITCHED 0/run (was 6-8 at ~2 s), sema-xchan uok=1 continuous, and c152/c153 Xorg logs show ZERO 'Failed to (idle|initialize) DMA'/push-buffer/AddScreen lines - the ScreenInit DMA instance is now stable on the deferral alone. Residual (next): Xorg then spins in-kernel (95% CPU, SIGKILL-immune, xdpyinfo unanswered; userd put=0 get=0 vs last=7098 in sema-xchan is the lead) - gl_frames still hangs at BAR map.
* vgsp: DDX-family USERD latch lifetime - served-latch deferral + live ↵Arthur Hanson Rasmusson20 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | re-probe + FB backoff The X DDX's push-on-demand generations allocate a new USERD control block every 11-24 s, but the 15 s no-advance judge dropped the latch that had just passed the DMA test, and the next scan adopted a frozen FB lookalike (put=2 get=0) - the retry window then closed with 'Failed to idle DMA'. For the DDX/kick handle families only (0x01xxxxxx / 0xbfef00xx; SYS/CE/UVM untouched): - svc_userd_ddx_family() gates all of it; - a latch that HAS delivered decoded entries (submissions advanced since adoption, no contradiction) is DEFERRED from rejection (bound 32; timer reset) instead of dropped; - before any latch decision (and on a 2 s cadence while unconfirmed) the content scan re-probes the live path and switches the latch in place to a newly validated block (svc_userd_ddx_reprobe; near-empty page + ring-entry validation + PUT-step liveness are the ownership proof); - after a rejection the FB shape scan backs off 6 s so the RAM scan wins the window; the DDX re-probe is exempt from the retired slice budget (rejects < 255). Validated (c141, rich r1624 args, tick): X ScreenInit passed with ZERO 'Failed to (idle|initialize) DMA' / push-buffer / AddScreen lines; the channel decoded a 5090+-entry burst and served across block moves (latch SWITCHED 0x24128e100 -> 0x103774100 -> 0x122309d00, uok=1 held). Known residual (next refinement): the switch is not yet forward-only/ rate-limited, so lookalike blocks can oscillate at ~2 s and starve the client; make the switch require nput > latch_put and a >=10 s cadence (or stop switching once defers>0), then the real block wins.
* vgsp: X-DMA wall witness for 0x1000013; add params-r1624.txt (rich bring-up set)Arthur Hanson Rasmusson20 hours
| | | | | | | | | | | | | | | | One rate-limited (0.5 s) sema-xchan line per pass for the X DDX channel: rrc/uok/upa/uas/put/get/last/ring_pa/entry0 - names the decode-gate state independently of the shared userdp budget. Diagnostic only, no behaviour change. params-r1624.txt is the rich r1624 insmod set as a durable tools/guest-diag file (INSMOD_PARAMS=tools/guest-diag/params-r1624.txt). Context (c130/c131 with the rich set): the DDX DMA test now PASSES on most attempts (tracker release decoded + delivered); the remaining gap is the USERD speculative-latch lifetime (a latch that delivered the test kick is REJECTED 15 s later with no PUT advance; the next generation then adopts a stale VRAM block, put=2 get=0, and the retry window closes) plus a later 'Push buffer object allocation failed: 0x51 NV_ERR_NO_MEMORY' (emulated heap accounting; 1872 MiB free).
* tools: fix cycle-r1780.sh env-var comment (INSMOD_PARAMS is what the code reads)Arthur Hanson Rasmusson21 hours
|
* tools: mission-gz guest loop (X retry -> gl_frames probe -> GZDoom pbuffer ↵Arthur Hanson Rasmusson21 hours
| | | | | | | | | | | capture); push/verify fixes mission-gz.sh runs the end-to-end guest pass in one shot (X bring-up with ScreenInit retries, GPU GL probe via gl_frames, GZDoom offscreen + gz_pbuf + sdl_cap under the tested wrapper, /tmp/mission-done result flag). push_gl_tools.sh runs vgpu_vm.py under sudo (QGA needs root); gl_verify.sh uses 'pkill -x Xorg' (the -f pattern self-matches the shell when the command line contains the Xorg invocation).
* vgsp: resolve the completion counter through its real aperture (fb/vidmem) ↵Arthur Hanson Rasmusson22 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | and use it on publish/flush The X DDX/kick channels' nvPush progress semaphore is a 4 KB sysmem surface whose GPU mapping resolves to the emulated VIDMEM aperture (va 0x20400ffe0 -> vidmem pa 0x3f8ffe0), while svc_counter_derive only accepted SVC_APERTURE_SYS translations; it therefore kept a false guest-RAM pair (a page holding unrelated data) and svc_counter_publish's put-advance both read and wrote the wrong page through the SYS aperture - the client's tracker never matched and the DDX failed 'Failed to initialize DMA' after its 10 s push-buffer sanity test. Carry the aperture with the registration (new svc_channel.counter_ap, svc_cnt_der[].ap): accept FB translations in the derive chain (chanvas, vaspaces, discovered; targeted stays SYS), probe with the found aperture, keep it through pin override/re-registration; svc_counter_publish and svc_counter_flush_pending read/write through it (release_pa stays SYS). Live receipts (c109/c110, 12 GiB guest, params-r1780): - counter derived h=0x1000013 ... pa=0x211c42fe0 (rank=1) with pub-adv writing 14..26 (was silently skipped on a false page in c107); - the DDX's OWN C36F tracker releases decode and land: 'sema-push h=0x1000013 va=0x1200a0000 ... rel=0x120001000 pay=1 have_rel=1' -> 'sema-sw h=0x1000013 va=0x120001000 pa=0x11cc68000 ap=1 val=0x1 rc=0 rb_ok=1' - the 10 s push-buffer test's exact wait word is delivered and the DDX proceeds to further work (values advancing 0x4017e..0x24024f); previously no release ever decoded. Remaining X-side flakiness (a later DMA init still failing on some instances) is tracked in the handoff.
* docs: 2026-11-12 status refresh - green X/GLX, non-black GPU captures, ↵Arthur Hanson Rasmusson22 hours
| | | | | | | | | | | | direct-GL stream frontier Refresh STATE-CURRENT.md and the open-iov.org wiki pages with the 2026-11-12 state: stock-driver X + GLX green (glxinfo 4.6.0 direct rendering, glxgears ~520 FPS), the pbuffer frame path captured 500/500 non-black frames (50 s 640x480 h264) plus the earlier 45.4 s capture, and the named frontier (direct-GL client command-stream delivery: setup push unreadable, CE ring 0xbeef0101 intermittent) alongside the guest-init/sizing fixes (RMInstLoc modprobe single-source, FB info in KB, 256 MiB GART).
* vgsp: stop fabricating 0xFFFF into the nvPush error notifier; add r1780 GL ↵Arthur Hanson Rasmusson22 hours
| | | | | | | | | | | | | | | | | | | | | ops tooling The uncommitted keep-alive change wrote 0xFFFF into slot 0's status field (u16 at notifier+0x0e) on the X DDX / GLX kick-idle channel families. Ground truth (570.144 reference sources + stock nvidia_drv.so disassembly): slot 0 of an nvPush notifier block is the ERROR notifier; nvPushCheckChannelError reads that status and 0xFFFF aborts every nvPushWaitForNotifier/idle wait as a channel error. There is no pb_kickIfIdle in 570.144 - the DDX DMA-idle test reads the progress-tracker semaphore word, not this slot. Leave slot 0 untouched; keep the 0x8000->0 completion ack for the remaining slots and the r864 0xFFFF/0x8000 completion on the RC-watchdog/beef families. Correct the CONT.408/409 comments accordingly. New host/guest tooling: gpa.py (QMP gva2gpa), tick_gen.py (guest-RM timer BO tick), guest_mode.sh (shared nvClip modeNum reader), gl_verify.sh (X/GLX bring-up with ScreenInit-lottery retries), push_gl_tools.sh, the gzdoom_pbuf_run.sh guest recipe and the test_tri SDL2 harness validation program; ignore tools/guest-diag/build/.
* tools: fix r1780 cycle prerequisites and add SDL GLX-pbuffer shimArthur Hanson Rasmusson23 hours
| | | | | | | | | | | | | - cycle-r1780.sh: load vfio modules one per modprobe (the multi-module form was silently treating the extra names as parameters and never loading mdev); auto-detect the vgpu mdev type and prefer the 2 GiB type used by the campaign. - sdl_cap.c: gate capture-file creation to processes that can actually read GL pixels (a child was truncating the capture), and log the capture pid/pointers. - gz_pbuf.c: LD_PRELOAD shim that gives an SDL2 GL client a GLX pbuffer context on the guest's NVIDIA X server (the proven gl_frames path), with SDL_GL_GetDrawableSize/SwapWindow interception.
* vgsp: accept wrapped FB USERD latches and dedup direct channel event postsArthur Hanson Rasmusson26 hours
|
* vgsp: direct-GL ring/push rescue, VAS/pdb scanners and PTIMER tick; r1780 ↵Arthur Hanson Rasmusson27 hours
| | | | cycle tooling
* docs: vGPU bring-up size/state traps (FB units, GART, modeNum parity)Arthur Hanson Rasmusson32 hours
| | | | | | | | | | | | Record the three independent guest-visible values that broke stock-driver bring-up: FB info kilobyte-vs-byte units (1024x framebuffer over-report), multi-GiB GPU GART allocation, and odd shared nvClip modeNum (clears the GL client's init bits so buffer maps fail). Each has a different diagnostic signature; the note separates allocation-size, userspace mapping-gate, and host VAS-translation failures. Evidence: c15-c26 bring-up, commits 8c7bf295/d1dc85a2/91aa8d91 and handoff-meta-plan.md CONT.435-CONT.441.
* vgsp: aperture-aware foreign USERD guard and wire fallbackArthur Hanson Rasmusson40 hours
| | | | | | | | | | | | | | c24 (V30) skipped the X/GLX channel's own sysmem USERD block because the same numeric PA 0x8f0000 is owned by the RC watchdog channel in vidmem; the X server then failed with 'Failed to initialize DMA' and 'Failed to allocate push buffer'. Compare the aperture as well as the page, and keep base 0 + userdOffset as a fallback when the client memory-object table cannot name the USERD (the resolver still wins when it has a verified object). This restores the c23 X bring-up while keeping the fail-closed table path. Validation pending a fresh V31 cycle: X starts, glxinfo/glxgears, chan_dump userd page/aper, and the USERD resolution/fallback witness lines.
* vgsp: resolve GSP-client USERD from hUserdMemory and skip foreign USERD pagesArthur Hanson Rasmusson40 hours
| | | | | | | | | | | | | | | | | | | | | | | | | GSP-client kernel channels carry their USERD as hUserdMemory[subdev] (NV_CHANNEL_ALLOC_PARAMS @32) plus userdOffset[subdev] (@64), leaving the userdMem memdesc (@168) zero. The service therefore adopted another live channel's USERD page (c23: h=0x1000013 took the RC watchdog h=0x31415900's block at fb 0x8f0000 every pass) and the Xorg PB progress wait never advanced. Remember client memory-object ALLOCs (class 0x3e sysmem, 0x40 vidmem; 0x70/0x50a0 are virtual ranges and are refused) in a bounded (hClient,hObject) table, alias them on DUP_OBJECT and retire them on FREE. At channel registration, if the wire userdMem base is zero, resolve hUserdMemory+userdOffset through that table and set userd_pa/userd_as only when the base is nonzero, page-aligned and in bounds; otherwise fail closed with a rate-limited reason. Also skip FB-sweep USERD candidates on a page already owned by another live channel. Validation pending a fresh V30 cycle: glxinfo -B exit 0, Xorg WAIT count 0, chan_dump h=0x1000013 userd!=0 ok=1 get advancing, sema-push have_rel=1, glxgears FPS unchanged, GZDoom -glversion 4.0 past V_Init. Evidence: handoff-meta-plan.md CONT.438; c23 X/GLX logs; ABI gsp_abi_check.c:1764, nvos.h:1631-1668, cl003e.h/cl0040.h.
* tools/debug: add read-only GMMU/pdb scanners for live guest RAMArthur Hanson Rasmusson41 hours
| | | | | | | | pdb_scan_gmmu walks the GP10X/VER2 GMMU page-table format (PD3/PD2/PD1/ PD0/PT, 16-byte dual PD0 entries, sys/vidmem apertures) and pdb_scan is the x86-64 index cross-check. Both map the QEMU pc.ram file correctly for the 2 GiB low + high-RAM q35 layout and are strictly read-only. Used to prove the ring page/VA and pdb chains in CONT.435/436.
* vgsp: default GPU GART size to 256 MiB (was 4096)Arthur Hanson Rasmusson41 hours
| | | | | | | | | | | | | | | | BUS_GET_INFO_V2 GPU_GART_SIZE at 4096 MiB made the guest RM allocate a 4 GiB system-memory GART object during X/GL init. That single allocation is the 1048576-page nv_alloc_pages spike that OOM-killed or crashed the 12 GiB guest in c15-c22; with the 4 GiB FB-info over-report fixed and UseSysmemPixmapAccel off, the GART was the remaining source. c23 with bus_gart_mb=256 and the guest X config UseSysmemPixmapAccel=false: X starts, MemFree stays 11 GB, no 1M-page allocation, and glxgears renders 2601 frames in 5 s (520 FPS) on the emulated vGPU. The default should not reintroduce the fatal allocation; 0 remains available for the historical A/B. Evidence: handoff-meta-plan.md CONT.436, c23 X/gzdoom/glxgears logs.
* vgsp: report FB info sizes in KB and use 0 for unsupported context buffersArthur Hanson Rasmusson44 hours
| | | | | | | | | | | | | | | | | The FB info ABI documents RAM_SIZE/TOTAL_RAM_SIZE/USABLE_RAM_SIZE/HEAP_SIZE/ MAPPABLE_HEAP_SIZE/HEAP_FREE/BAR1_SIZE/BAR1_AVAIL_SIZE in kilobytes; the emulation returned bytes, over-reporting the emulated framebuffer by 1024x to the X DDX. COMPRESSION_SIZE and L2CACHE_SIZE remain in bytes. KGR_GET_CONTEXT_BUFFERS_INFO reported NV_U32_MAX for buffer kinds Turing does not support. kgraphics treats size==0 as unsupported (skip); an NV_U32_MAX byte length rounds up to exactly 4 GiB in the page-count computation, which is the shape of the transient guest sysmem allocations. Report 0/0 instead. Evidence: handoff-meta-plan.md CONT.435 (c15-c21 allocation traces, the guest nvidia.ko disassembly of osAllocPagesInternal), kernel 570.144 ctrl2080fb.h units and kernel_graphics.c:1775-1800.
* vgsp: gate the injected shared-surface pin author (default off)Arthur Hanson Rasmusson47 hours
| | | | | | | | | | The strict signature scan used to locate the shared surface can match a guest page-table page: the same 1.4M 'refCount/lkr' values reappear at the same offsets across VMs, and writing the lkr into it coincides with guest bad-pmd and soft-lockup storms in unrelated processes. Keep the VAS-walk author on, but require sema_gl_shsurf_pin=1 for the injected-pin page; only a page proven to be the client's shared surface (release target VA resolved through a verified VAS) should be authored.
* vgsp: pdb neighbourhood discovery + injected shared-surface pin syncArthur Hanson Rasmusson47 hours
| | | | | | | | | | | | | | | | | - when a content-verified ring pair is known, also scan a bounded window around every COPY_SERVER_PDES candidate pdb for a root that reproduces the pair; register the found root under the candidate's VAS handle so the channel's own VAS lookup resolves the ring even when the offered pdb is a stale incarnation - the periodic shared-surface watchdog now also honours an operator-injected shared-surface pin (sema_map_add): read lastKickoffRefCount at +0x880 and author it into gpuRefCount at +0x800, forward-only and validated Live receipt (r1780 c14): with the strict shared-surface signature page injected, the pin sync advanced gpuRefCount 1420471 -> 1420488 (== lkr), the DDX idle warning did not repeat, and GZDoom reached V_Init with X alive. Next walls observed: the DDX push-buffer idle wait (W2) at teardown and a guest OOM that kills gzdoom.
* vgsp: periodic GLX shared-surface refCount watchdogArthur Hanson Rasmusson48 hours
| | | | | | | | | | | The GLX client writes lastKickoffRefCount during init before its first kick, while the X DDX may already poll gpuRefCount against it; if a previous client left the count lower the wait can only clear after the GLX request the DDX is blocking. Once per second (and on a manual sema_gl_shsurf_kick write) walk the known shared-surface VA and the last decoded release VA, and author the client's plausible lastKickoffRefCount forward-only. The strict lkr gate (high dword zero, small, cur < lkr) keeps it a no-op when the VA maps something else. Gated by sema_gl_shsurf_watch (default on).
* vgsp: direct-GL ring scan hardening + USERD orientation overridesArthur Hanson Rasmusson48 hours
| | | | | | | | | | | | | | - per-rank GR shadow-scan cadence (the global 1.5 s window was consumed by the first channel in pump order, starving the direct-GL ring scan) - low-aperture ring content gate: entry0 within +/-8 MB of the ring VA and a zero terminus within the first 128 slots (dense data pages and transient copies were being latched as the ring and fed phantom entries) - stop skipping the guest-RAM content scan when the shadow-scan window is closed; only the shadow scan is rate-limited now - strict shared-surface author: write lastKickoffRefCount only, never the raw payload into an unvalidated translation - dev-only sema_userd_swap / sema_userd_override to test the direct-GL USERD orientation and a known control page; both default off
* vgsp: GLX shared-surface refCount fan-out + persistent direct-GL ring scanArthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | V14: when the decoded GLX kickoff release targets the shared-surface gpuRefCount word, write the forward-only value through every published VAS translation and, when a candidate page carries a plausible lastKickoffRefCount at +0x880, author that value instead. The X DDX idle-channel wait compares those two words; a stale single-target write left it polling until its 5 s warning. Gated by sema_gl_shsurf_allvas (default on) with a bounded sema_gl_shsurf_dbg candidate log. V15: refresh the beef GR ring content-scan slice budget while the ring is unresolved and no submission has been observed, so a direct-GL client that registers an empty ring before its first kick is still found when it submits. Gated by sema_gr_ram_keep (default on). Adds a bounded per-second scan witness (cursor/passes/hit) and a read-failure witness.
* vgsp: verify the scrub ring ledger before authoring (P0 for the X/GL wedge, ↵Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | CONT.427) - Resolve the channel GPFIFO ring page through the GPU page tables (the same resolver the stash geometry path trusts) instead of deriving it as "hsem page - entries*8"; that subtraction is only correct when the buffer's GPFIFO and sema pages are PA-contiguous, and it could land on a stale or dense page (r1775/r1777 boots). - Validate the first read with the strict GPFIFO entry shape (flag bits, length field, push VA bounded around the channel's own gpfifo) plus a clean zero terminus (the next slot and the following 32 slots must be zero). An all-zero page, a dense data page or a dirty tail is not trusted as a submission ledger. - Detect a guest scrubber reset by a regressed finish word (or fin returning to 0 while a release was authored) and reseed the ledger instead of re-applying the pre-reset absolute count - that re-application underflowed the guest's scrub-list size (r1775 c6: 4076 into an empty list -> 0xFFFFFFFFFFFFF014 -> the scrubCheckAndWaitForSize spin, _nv052600rm+0x7b). - Never author the finish word from an unverified or unresolved ring: fin stays a no-op. A blocked scrub wait is recoverable; an underflowed list is not. A/B: sema_scrub_ring=0 skips the ledger entirely. Live validation of this build is pending (6-cycle wedge acceptance + GZDoom run).
* vgsp: client-VAS CE ring probe + L0 sanity gate (V12, default off)Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | - CE siblings (0xbeef0101/0102): extend the beef-family ring discovery with an identity probe and the GR guest-RAM content scan plus a sparse-run gate and a RAM ring-page ownership table; keep >=2 fresh same-VAS park candidates during the client's VAS churn. - Add svc_pdb_l0_sane() and apply it to unverified directory candidates so a freed/reused incarnation is skipped instead of walked. - Both behaviors are gated behind sema_ce_ram (default 0): the live A/B latched false positives on dense data pages and the L0 predicate needs tightening before it may guard the GR lane (the validated V9/V10 GR behavior is preserved by the default).
* wiki: remove virtio-gpu/virgl references (not part of this project's path)Arthur Hanson Rasmusson2 days
|
* wiki: 2026-11-11 status refresh - first non-black GPU frames + 45.4 s video; ↵Arthur Hanson Rasmusson2 days
| | | | direct-GL GR ring resolves; CE-ring/window walls (STATE-CURRENT too)
* vgsp: kick-lane + client-VAS ring resolution upgrades (CONT.421-423)Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | | | | | | | | - kick latch: keep an adopted-but-unconfirmed kick-family USERD latch across a transient put=0 (sema_kick_latch_keep, default 1) - the r1771 ADOPT->REJECT sequence dropped the block 7 s after adoption and left the GL/kick lane dark. - service-thread starvation: budget the VAS-PROMOTE walk log and back the promote sweep off 250 ms after a failed pass (sema_vas_promote_backoff, default 1); both brought ~100 pr_info/s down to <1/s during GZDoom's GL init stall; also budget the RING-VAS mapped print. - direct-GL client ring: always-probe the beef-family channels against the parked VAS candidates (sema_vas_client_ring, default 1, rate-limited per channel) with per-channel failure backoff, a smallest-unused-rank fallback (rank collision had disabled the content-scan backup) and oldest-same-VAS park eviction for the client's VAS churn. Live receipts: ring mapped, GR latch confirmed, push count 20->157, releases applied per frame (values 0x1->0x20), X channel-idle timeouts 0 during GL bursts. - Validation: glxgears 469-522 FPS (no regression); GZDoom now completes GL init and reaches screen allocation with the client lane live (~120 s) instead of dying seconds after V_Init.
* vgsp: ring-ledger scrub release + gated flip-event fixes (CONT.418-419)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | - gsp_sema_service: never fabricate scrub completions. The guest decrements its scrub-list size by the reported finish delta without a guard, so a fabricated delta larger than the pending list underflows it and the guest spins (~2^64) under the scrubber mutex (r1766-r1768 X soft-locks and guest panics; root-caused by static analysis + gdbstub decode of lastSeen/lastSubmitted/scrubListSize). The release now mirrors the registered channel's own ring: count new valid pushes (wrap-safe snapshot delta) and set the finish word forward-only to the cumulative count - exactly the work the guest submitted, never more. False ring-page registrations are detected and skipped (a mis-registered ring page had its first GPFIFO entry clobbered by an all-ones write). sema_scrub_ramp=0 keeps the legacy all-ones release for A/B; the finish word is never all-ones with the ledger enabled. - gsp_rm_emulation/gsp_display_engine: gate the hSrcResource==0 -> alloc parent event association behind ev_assoc (default 0) and keep strict display-event posting behind disp_events_strict (default 0) - both remain A/B knobs for the flip-event delivery fix. - Live validation (r1769): 4/4 green boots, 0 panics, 0 wedges; glprobe pixel=ff0000ff; gl_frames 500/500 non-black frames captured to a 45 s 640x480 mp4 via pbuffer -> sysmem -> ivshmem.
* vgsp: all-ones scrub release for registered waits; walk-page registration; ↵Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | GL frame publisher (CONT.416-417) - gsp_sema_service: merge a scanner registration arriving after the stash record instead of dropping it (a dropped registration let the next authoring pass write the blocking pair into the page the guest was polling, so the wait never ended); author the finish word all-ones for every registered record while the sema word stays put-based once real submissions were observed (CONT.416/417). - scrub_pin_qmp (host scanner): accept an unstable-but-live wait page instead of skipping it, and register the walk-resolved scrubber channel page - first the walk summary, then the per-VAS kernel row (h=0xc) when the summary path fails - so the release is armed before the guest polls (r1762/r1764 evidence). - guest-diag: add gl_frames, the direct-GL (GLX pbuffer) frame publisher; with it the stack produced the first non-black GPU-rendered frames (40/40, 640x480, animated) through pbuffer -> sysmem -> ivshmem -> host frame_reader. - gsp_rm_emulation: log the display-shim request words for triage.
* wiki: 2026-11-10 afternoon refresh - first real GPU readback; ↵Arthur Hanson Rasmusson3 days
| | | | | | | | | | | direct-GL/window walls Refresh STATE-CURRENT, the Main Page and the status/frontier pages: the DDX 3D replay executes and a guest pbuffer glClear+glReadPixels returns a red pixel (ff0000ff); the RM write-lock holder (Xorg in the DDX scrub wait) is fixed in df6e71bb. The direct-GL client channel still emits only setup/notify kicks (ops_runs=0), a window draw wedges X, and X startup/RM stability plus the DDX 4 GB sysmem allocation remain. Published to open-iov.org.
* vgsp: author the scrub release pair for scanner-registered waits (CONT.414)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | The X DDX vidheap scrub wait polls the finish payload at channel buffer +0x6c004 while the host still reads USERD GP_PUT=0, so put-based forward authoring wrote sema=entries-1 / fin=0: exactly the values that leave channelWaitForFreeEntry and channelWaitForFinishPayload blocked. Xorg then held the NVRM RM API write lock inside NV_ESC_RM_VID_HEAP_CONTROL, and the GL thread and nvidia-modeset both sat D-state on os_acquire_rwlock_write. A scanner-registered buffer with no observed submissions now gets the proven all-ones release pair (sema=fin=0xffffffff) and is re-authored every pass so a guest rewrite cannot re-block the wait. Put-driven records keep forward-only authoring. Result: the GL thread leaves D-state and a glClear+glFinish+glReadPixels probe returns rc=0 with pixel=ff0000ff (a real red readback).
* vgsp: USERD index/alias resolution, DDX kick-idle fix, completion-slot ↵Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | authorship (CONT.403-412) Ten debugging rounds against the direct-GL channel, each fixing the wall that blocked the previous one: - USERD index: honour USERD_INDEX_VALUE/PAGE_VALUE from NVOS04 flags (X idx=3, GL idx=4) instead of always reading the block at base+0. This fixed the X "Failed to initialize DMA" wall. - USERD alias: learn the BAR1-alias bias from the first ring-validated FB latch (wire 0x80600 -> live 0x910000) and prefer alias/wire-page candidates before falling back to the RAM scan, which previously adopted another channel's control page. - USERD latch: keep a ring-validated kick-family block across a transient put=0 instead of dropping it (bounded, per-channel log). - VAS alias: DUP_OBJECT copies pdb/entries/ap/verified so hVASpace 0xbfef0001 resolves to 0x10005 and its gpfifo VA stops re-resolving to a bogus FB PA. - Short-kick NOTIFY: complete a kick that has no armed class-2D target (release + event, no write) so the client proceeds past setup. - DDX kick-idle: slot 0 of the 0x01xxxxxx family is the pb_kickIfIdle gate and 0xFFFF is its IDLE value; the keepalive no longer zeroes it. Removes the GR-STALL-stale-wedge on the X channel. - Completion slots: register a per-channel completion on every successful kick and reuse it when a NOTIFY has no per-push SET_NOTIFY; prefer the channel's notifier page over the VA walk. - Empty/no-op submit: author the completion even when there is no push to replay, so a synchronous GL submit does not wait forever. - Scrub records: multi-record per guest, stash-first lookup, registered PA is authoritative against the GPU-VAS walk, scanner-only records author the proven 0xffffffff/0xffffffff pair. - GL attachment: accept a draw run whose own subchannel is the engine subchannel the channel uses (bind is subch 0, draws on subch 3), not only the bind subchannel. Measured: glxgears 427 -> 526 FPS sustained with no GR stall; X binds and renders its 2D path; 3D draw capture on the GL channel still does not occur (see CONT.412: the GL thread blocks on the NVRM RM write lock before it reaches any ioctl). Adds tools/guest-diag/scrub_pin_qmp.py to register guest channel-buffer vmap pages as scrub records from the host.
* vgsp: fix VAS-staleness on client restart + unstarve the ring scan (CONT.401)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three fixes, all verified live (cycle r1696): 1. Parked-VAS age-out flood. CONT.400 kept the candidate parked after registering it UNVERIFIED, so with sema_vas_cand_ms=1 the age-out re-registered and re-logged every pump pass (~480 lines/s) and each store memset the learned translation cache. Register once via a new 'aged_out' flag (reset when a slot is recycled); the candidate stays parked for the verified upgrade path. 2. Stale verified VAS on client restart. A client restart rebuilds its page directory under the SAME VAS handle (observed X 0x10005: pdb 0x12a82f000 -> 0x14b259000). CONT.400's 'never downgrade verified' guard then pinned the previous session's directory forever: the pump served stale ring/push pages, consumed zero entries and the DDX pushbuffer NOP test timed out ('Failed to initialize DMA' / 'Failed to allocate push buffer'). svc_chan_vas_candidate_promote now demotes a verified directory when a parked candidate names a different pdb, so the live one can be content-validated and installed. Result: X starts reliably and the pump consumes the 2D stream (chan_dump 0x1000014: get=1088 sub=1088). 3. Ring-scan starvation. The GR RAM content scan is budgeted to 40 slices per channel incarnation, and its only re-arm sits at the END of the pump loop, which is unreachable because svc_chan_userd() failure hits 'continue' first - exactly the unresolved-ring state that needs the scan. Re-arm before the USERD probe by reading the raw GP_PUT from the registered USERD block and resetting the bounded budget when it moves. Live result: glxgears now reports 529 FPS (was 0.15-0.22 FPS) with 'direct rendering: Yes' and the NVIDIA renderer string; the framebuffer is still black because the consumed command stream is not executed (see handoff CONT.401).