summaryrefslogtreecommitdiffstats
path: root/kernel
Commit message (Collapse)AuthorAge
* vgsp: add sema_draw_census - bounded draw-marker census over every client ↵Arthur Hanson Rasmusson3 hours
| | | | | | | | | | | | | | | | | | | | | push (eng26 instrument) One green cycle must answer 'which push carries the direct-GL draw'. The census scans every non-engine push with the canonical op/cnt run grammar and logs one bounded row per push containing any draw-family method id (BEGIN 0x1618, END 0x1614, VA_START 0xd74, DRAW_VERTEX_ARRAY 0xd78, index 0x17c8/0x17d8/0x17e0, draw list 0x1b0, vertex streams 0x1c00/0x1c10), with the hit's word index inside its run so a run that merely NUMERICALLY spans a method address is distinguishable from a real method data word. Beef pushes without hits are enumerated once per (va,len) so the cycle yields a full push inventory. Module param sema_draw_census (default 0), 256 hit + 256 push rows, read-only. Live result (c346): full beef push inventory captured; every marker 'hit' is a k>0 lattice artifact of a data blob (e.g. the 59580-B push's single m=0 run at off=0x78 covers 0x1b0..0x1c10 at fixed word indices, and its BEGIN-address word value changes between reads - 0x00058202 then 0x01047220), i.e. no push carries a real draw method stream. Companion to a4215afa; docs in CONT.487.
* vgsp: reject beef draw-synth windows whose last colour-target bind is ↵Arthur Hanson Rasmusson3 hours
| | | | | | | | | | | | | | | | | | | | | | unusable (eng25 correctness guard) The direct-GL lane's draw-synth captures join the verbatim 3D replay lane by numerical run-cover alone, so a non-method data blob whose INC run merely spans the C597 RT block is replayed as state: its last A/B/W/H write per colour target is an unmapped 40-bit VA (c344: RT1 -> 0xff000480a0) and the engine retires with no stores (NOWRITE wrote=0). Gate the beef 'd' admission (single-block and chunk-split) on svc_gl_window_rt_valid(): walk the window with the run grammar, keep the last A/B/W/H write per colour target, and require at least one usable bind (A[7:0]<=1, B<2^30 aligned, 1<=W,H<=0x4000). Validated live (c346, mdev 53dc06b5, ENG26 instrument cycle): 23 bounded '3D mark rejected (beef draw-synth: no valid last colour-target bind)' rows, including the 14865-word 59580-B blob window @off=0x78 and the 542-word 0x4010ed0 twin; the one timing-variant window that does carry a usable RT bind still passed and replayed (wrote=0), and the X lane is unregressed (15x '3D stream marked h=0x1000013' + 'GUEST GR LAUNCH OK' ok=16/17). Refs: CONT.486/487; eng25/eng26 evidence under /tmp/opencode/eng26-*.
* vgsp: route direct-GL draw-synth captures through the verbatim 3D replay ↵Arthur Hanson Rasmusson3 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lane; beef rel_mod launches may take the ch_rel release branch (eng24) Clause 1 (gsp_sema_service.c, svc_gl_flush): the direct-GL (beef-family) section captures opened by the eng23 inside-run openers carry synthesized PROG/PARAM/REL (src=draw-synth) but a REAL method window; include 'd' in the stream-3d marking (single 448-word block and the method-aligned chunk split) so the window replays verbatim on the engine like the X/stream/hold lanes, instead of waiting on a synthesized compute-QMD release the engine never writes. Verified live: '3D stream chunked h=0xbeef0100 push=0x4250110 window=779 words -> 3 chunk(s)' and 'GR LAUNCH submitted h=0xbeef0100 ... polling qmd_rel=0'. Clause 2 (gsp_phys_booter.c, gsp_phys_backend_guest_gr_submit): a beef-family launch whose QMD release0 was redirected to the module semaphore with the rel_mod sentinel (0x600df00d) may break its poll on the channel release alone (the X lane's proven branch) once the engine has retired the method block; witnessed by 'GR LAUNCH OK ch_rel branch (beef rel_mod; ...)'. Verified live: 4+ beef launches now complete (engine fetch OK, GUEST GR LAUNCH OK ok=22..25) where the c338 shape timed out (qmd_rel=0xc0ffee01 want=0x600df00d). Known residual (unchanged by this commit): the replayed beef windows retire without stores (NOWRITE-CONFIRMED/AMBIGUOUS, wrote=0 -> px0=0), the same engine-store wall the X lane shows; and with the default sema_mme_immature_skip=1 the service soft-completes replayed beef windows before any engine contact (A/B with the knob at 0 was used to put the real window on the engine).
* vgsp: RM-record 3D attach + inside-run C597 openers for the direct-GL ↵Arthur Hanson Rasmusson4 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.
* 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.
* 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 Rasmusson9 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 Rasmusson11 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 Rasmusson14 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.
* 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 Rasmusson16 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 Rasmusson18 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 Rasmusson19 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).
* vgsp: resolve the completion counter through its real aperture (fb/vidmem) ↵Arthur Hanson Rasmusson21 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.
* vgsp: stop fabricating 0xFFFF into the nvPush error notifier; add r1780 GL ↵Arthur Hanson Rasmusson21 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/.
* 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 Rasmusson26 hours
| | | | cycle tooling
* 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.
* 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 Rasmusson43 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 Rasmusson47 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 Rasmusson47 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 Rasmusson48 hours
| | | | | | | | | | | | | | | | 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).
* 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.
* 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).
* vgsp: family-aware GR ring scan + GR completion event post (CONT.400)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | 1. svc_gr_ram_ring_scan: the direct-GL client's kernel channels live in the RM low aperture (ring 0x4020000, pushes 0x4000000/0x4001004/0x4250000/ 0xcae2894). The scan rejected every one of them: entry VAs below SEMA_VA_LO (0x100000000), entry-1 outside +/-1MB of the ring, and the 1MB-alignment gate in svc_gr_entry_plausible. For the low family (gpfifo_va in [0x4000000,0x10000000) or h_object 0xbeef0xxx) accept any low-aperture push VA, drop the 1MB alignment to 4 bytes, and use the low aperture as the upper bound. High-family rules unchanged. 2. GR completion event: a launch completion is an RM event edge, not only a memory word. The guest client waits in the RM software event queue (NV_ESC_RM_GET_EVENT_DATA), populated only by a GSP 0x1003 EVENT_POST_EVENT record. Post it via gsp_rm_post_channel_event_force() after the release is visible, on both the hold success edge and the software/failure edge. Diagnostics added: VAS-PROMOTE walk results and the RING-VAS probe. Open (see handoff CONT.400): the beef ring VA is still not mapped by any registered VAS, not at guest PA 0x4020000, not at vidmem 0x4020000. The guest never publishes the channel's effective TSG/device-default VAS via SET_PAGE_DIRECTORY; all registered VASes come from COPY_SERVER_PDES. Guest screen is 100% black; glxgears 0.2 FPS.
* vgsp: verified-VAS tracking + ring-VAS probe (CONT.400)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | The beef GR client channel (0xbeef0100) declares hVASpace==0 and its ring gpfifo=0x4020000 was never resolved (ring_pa=0, rrc=-2) for whole boots, so the whole GL draw stream was never decoded (black screen, 0.2 FPS). Root cause chain fixed here: - svc_chan_vas_candidate_promote returned early because it gated on svc_vaspace_known(), and the bounded age-out (sema_vas_cand_ms) had already registered the directory UNVERIFIED. It now gates on a new svc_vaspace_verified() and keeps retrying by content. - The age-out no longer clears the parked candidate (it used to consume it), so the content-verified upgrade path still has something to walk. - New 'verified' flag on struct svc_vaspace/sema_vaspace_desc; RM's own SET_PAGE_DIRECTORY, the verified ring walk, and the auto-discovered client VAS mark it verified; an unverified registration never downgrades a verified one. - New RING-VAS probe: when no parked candidate maps the ring VA, walk every registered directory for it and adopt the first that yields a plausible entry-0 push. Result: VAS 0xbeef0300 now registers VERIFIED (was always UNVERIFIED). The ring VA itself is still not mapped by any registered directory - the guest never publishes SET_PAGE_DIRECTORY to us; all VASes come from COPY_SERVER_PDES discovery. Diagnostic added for the next step.
* vgsp: WIP beef ring VAS promote + widen CB scan to draw channel (CONT.399)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | - svc_chan_vas_candidate_promote: fall back to svc_channel_owner_vas when the GR client channel declares hVASpace==0 (the helper previously returned early for exactly the channel whose ring we need to resolve). - svc_gl_cb_upload_scan: also scan the 0x01xxxxxx RM-channel family (the channel that actually replays the draws), not only beef. NOT YET VERIFIED to resolve the beef ring: the CE siblings register ~19 ms after the GR channel, and VAS 0xbeef0300 is already 'known' (registered UNVERIFIED after 1 ms) by then, so the content-verify is skipped. The beef ring gpfifo=0x4020000 stays ring_pa=0 and the CB scan never runs. See CONT.399 in handoff-meta-plan.md for the full diagnosis.
* vgsp: fix X DMA init + GR backend timeouts (CONT.399)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | X-DMA-FIX (gsp_sema_service.c): - svc_chan_userd: run the pristine-FB USERD scan when the r496b sweep ran on a resolved-but-unvalidated ring (ring_pa!=0 but no entry decoded), not only when the ring is untranslated. A stale pin/foreign VAS left the channel without a USERD and X's 10 s pushbuffer NOP test timed out ('Failed to initialize DMA'). - svc_fb_userd_pristine_scan: claim-check with (off,off) so a second GR channel is not considered foreign against the first adopter's ring_off=0. - svc_chan_vas_candidate_promote: register the channel's own parked COPY_SERVER_PDES candidate at the pump turn once its GPFIFO entry 0 content-validates, instead of waiting for the 1000 ms age-out. - pump: fall back to svc_channel_owner_vas when hVASpace==0 (driver 'attach to the TSG address space') so the GR client ring resolves. PAIR-SAFE (gsp_phys_booter.c): default sema_gl_pair_close_entry and sema_gl_sph_bind_pair_safe ON. An unclosed BEGIN/END pair made the replayed window raise ILLEGAL_METHOD_IN_BEGIN_END (Class Error 0x2018 EC 0x0d), the FE parked before the release semaphore, and draws timed out (backend_timeout). Diagnostics: CB-DIAG/CB-DIAG2 per-push fixed-CB capture summary. Verified: X direct-rendering green on attempt 1; work_gr backend_timeout=0 (was 6), backend_ok=5-7.
* vgsp: probe the low-aperture GR ring identity, skip GR holes, widen the ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | pristine-FB scan The GL client's GR kernel ring lives in the RM low aperture (0x4000000..0xfffffff) and is not mapped by any published client VAS, so svc_lookup returns ring_pa=0 and the ring-gated USERD discovery never runs. - svc_pump_channels: for the 0xbeef0000 GR family, prove the ring content with a raw PA==VA read and adopt that identity translation (re-proven every pass so the churning ring VA re-resolves). - ce_fb_scan / svc_gr_ram_userd_scan: treat zero holes as not-a-window for the 0xbeef0000 GR family and accept entry VAs inside the SEMA VA window even outside the +-2 MB ring window. - svc_fb_userd_pristine_scan: raise the pristine-FB cap from 32 MiB to 512 MiB so the 32.5 MiB USERD candidate (0x207fc00) is scanned. These are defensive and do not by themselves dispatch the guest's real GL draws (the ring entry format and the missing default VAS are still open); see handoff CONT.393-CONT.395.
* vgsp: raise the GSP engine event interrupt so guest ISR drains events and ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | wakes poll() waiters The emulated GSP only signalled the MSI-X eventfd when it queued a status record. The guest's primary ISR (nvidia_isr) decides pending from the CPU_INTR leaf registers, which we never set for the GSP stall vector, so it returned IRQ_NONE: IRQ 33 counted thousands of interrupts while the nvidia event thread sat idle and a client blocked in poll() on /dev/nvidia0 (a GLX swap) waited forever even though the event was already in the status queue. Mirror what a real GSP-RM does when it queues an event: - program RISC-V IRQMASK/IRQDEST for SWGEN0 (read-only to the guest; the GSP firmware owns them), - set SWGEN0 in the falcon IRQSTAT, - latch GSP stall vector 155 in the CPU interrupt tree (LEAF[4] bit 27, UVM_SHARED subtree 2 -> TOP[0] bit 2), - signal MSI-X. Raise it only for POST_EVENT records (replies are polled by the client). Verified on r1680: the guest now writes IRQSCLR SWGEN0, kgspService_TU102 drains events, and glxgears renders (was a hard hang).
* vgsp: complete the X DDX's push-buffer notifications and class-aware display armArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Four fixes, built and validated on fresh boots (r1675/r1677): - gsp_display_engine: gsp_disp_update_armed() is class-aware. NVC57D (core) carries the NOTIFY bit (12:12); NVC57E (window) has no NOTIFY bit, so a bound notifier ctxDMA is the arm. Every c57e window flip computed armed=0 before this, so FINISHED and the channel event were never authored and the DDX's composite/flip waits sat out their timeout. - gsp_sema_service: complete the bfef family's NvNotification status (0x8000 -> 0) in svc_client_slot_sweep(). The DDX marks the record IN_PROGRESS before a submit and the GPU (or RM) must write it back to 0; the emulation never did. - gsp_sema_service: sema_gl_hold_apply (default 0) applies a decoded GL release forward-only at svc_gl_flush() out: when the draw section is not captured, with a stale-value and 1 MB jump guard. - gsp_sema_service: extend the 0x8000 sweep to the X DDX's own RM channels (h=0x01xxxxxx). pb_armNotifiers() writes 0x8000 at notif+0xe and pb_wait() polls it back to 0; the bfef-only filter skipped these channels, so the 8 s submit wait expired ("WAIT (2, 8, 0x8000, ...)" then "Wait for channel idle timed out") even though the class2d NOTIFY ack had zeroed the same page before the arm. Evidence: r1675 keeps the X alive past the old 212 s crash point with 0 "Caught signal" lines; the DDX's 2D pipeline runs (get word advances), the host decodes live 3D method streams (VP-METHOD ... 0x1618 BEGIN topology) and the release sweep applies thousands.
* vgsp-sema: read a channel's push through the VAS it declaredArthur Hanson Rasmusson4 days
| | | | | | | | | | Several VA spaces can map the same GPU VA. The push read's learned/pin chain is global over VASes, so the GL client's CE channel 0xcaf00012 (which pushes at 0x120000000) was answered with a zero page from another VAS and every entry was 'unreadable' while the channel's own VAS mapped the real method stream. Try the channel's declared VAS first; fall back to the existing source chain when it has no published directory or the walk misses.
* vgsp-sema: keep the scrubber release alive while the event pump blocksArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | The guest's PMA scrub wait and the host's status-queue pump can deadlock: the X server's scrub wait holds the guest RM lock the status consumer needs, the ring fills, and every critical event post then waits out its full 200 ms ring-full budget. A service pass can take many seconds, so the next pass's scrub step - the only thing that can release the scrub wait - is starved and the guest never makes progress. Run the scrub step from inside the send path's ring-full wait (service thread only), and re-resolve the scrubber's finish/host-sema words on every pass instead of once: the guest re-creates its RM kernel VAS and re-maps the channel buffer under the same GPU VA (observed: gpfifo VA 0x120064000 moved from PA 0x127e6a000 to 0x1122e9000), so a once-only resolution authored a page the guest no longer polled. Prefer the RM kernel VAS (h=0xc) RAM mapping over a client VAS vidmem mapping, and force re-resolution when a scrubber re-registers.
* vgsp-sema: resolve the scrubber's finish words through the GPU page tablesArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | The guest PMA scrubber's host-side completion (channel buffer + pbSize + entries*8) was resolved through the learned VA->PA pair map first. When the guest reused the scrubber's GPU VA for a new channel buffer, that map still named the previous allocation's page, and the host authored the finish payload there while the guest polled the new page through its kernel VAS (h=0xc). r1667 live proof: walk_probe 0x12006c000 -> only VAS[1] (h=0xc) resolves to PA 0x10812a000 (the page the guest's vmalloc mapping of the channel buffer points at, and the value it polls); the pair map returned 0x10526a000. Writing the finish value to the correct page (via the guest scanner registration) immediately released Xorg from the RM memory-manager wait and the queued GSP status records drained. Changes: - svc_scrub_pass(): resolve hsem/fin through svc_walk_vaspaces() first, fall back to the pair map only when no VAS maps the VA. - Struct svc_scrub gains authored_gen; a new pa_gen (fresh scanner registration or a corrected derivation) forces one authoring pass even when the scrubber's PUT did not advance, so an already-waiting guest is released without a new submission.