summaryrefslogtreecommitdiffstats
path: root/kernel
Commit message (Collapse)AuthorAge
* vgsp-sema: release the UVM channel tracker slot tooArthur Hanson Rasmusson12 hours
| | | | | | | | | | | | r1642 gdbstub proved the guest polls pool map slot 1 while the push releases slot 0: rank-0 UVM channel's uvm_gpu_tracking_semaphore resolves map_base + index*4 (index=1) = 0x121000004 (PA 0x104ea2004), the release decoded from its push targets 0x121000000, and writing the payload into 0x104ea2004 cleared uvm_push_end_and_wait. When a CE channel releases the pool map page, also apply the forward-only value to map_base + 4*(rank+1) through the verified pool resolver (read-back proven), and log pool-tracker-wr.
* vgsp-sema: backfill a promoted pool semaphore pageArthur Hanson Rasmusson13 hours
| | | | | | | | | | | | | | r1640: UVM's channel-pool release was written to the boot-cache page (pa=0x2600000) and 54 ms later a verified VAS walk promoted a different page (pa=0x103ac0000, sysmem) to primary. The value was never carried over, so the guest tracker polling the walk page read 0 and GZDoom spun forever in uvm_channel_manager_create -> uvm_push_end_and_wait -> uvm_spin_loop. On every primary/secondary swap in svc_pool_boot_store(), max-merge the old primary page into the new primary page (semaphore words are forward-only monotonic counters; read both pages first, never write on a read failure, never merge a page into itself) and log pool-merge.
* vgsp-disp: map class 0xc57b to its real control window (window-imm)Arthur Hanson Rasmusson14 hours
| | | | | | | | | | | | | The header labelled 0xc57b CURSOR and mapped it to the cursor-PIO block at 0x6d8000+n*0x1000, but 0xc57b is the immediate-mode window class whose control window is 0x690000+(n+32)*0x1000 = 0x6d0000+n*0x1000 (0xc57a is the PIO cursor channel, valid=0). The engine therefore polled the wrong window for every 0xc57b channel: their PUT was never seen, no UPDATE ever completed, and r1638's GZDoom-triggered mode set left X spinning in an RM ioctl after the window-imm flip. Rename the constants (WINDOW_IMM 0xc57b, CURSOR_PIO 0xc57a) and return the correct control offsets; cursor-PIO keeps 0x6d8000+n*0x1000.
* vgsp-disp: retry a lost UPDATE completion event from the pumpArthur Hanson Rasmusson14 hours
| | | | | | | | | r1636: the X-start mode set wrote FINISHED but the channel completion event was refused (event burst cap / transient status-queue state) and never retried, so NVKMS waited forever and X wedged in os_acquire_rwlock_write. Mark the channel event_pending on a failed post, retry it every pump pass (outside disp.lock), clear on success, and log the failure/recovery plus hObj in the UPDATE line.
* vgsp-disp: scan the BAR3 shadow for the display instance tableArthur Hanson Rasmusson15 hours
| | | | | | | | | r1635 live proof: the 32 MiB RM BAR2 aperture is the 64-bit PCI BAR2/3 pair and is enumerated as resource BAR3 (BAR2 empty), so the instance block lives in bars[3] (block base +0x3000 in the shadow; 0x10013 target=2 base=0x114103000, 0x10075 target=3 base=0x114138000). Scan bars[2] and bars[3] in the resolver and log the bar index; the BAR2-only scan found nothing (0 resolutions).
* vgsp-disp: resolve the display instance table in the guest BAR2 shadowArthur Hanson Rasmusson15 hours
| | | | | | | | | | | | | | | | | | The guest kernel RM builds the 64 KiB display instance block in FB but writes it through the guest's BAR2 virtual aperture (memdescMapInternal -> BAR2 with RMCFG_FEATURE_PLATFORM_GSP=0), while control 0x20800a49 hands only the FB PA to the display engine. The hash table therefore never appears in the FB shadow or guest RAM, which is why the notifier context-DMA handles 0x10013/0x10075 could not be resolved and FINISHED was never written (r1633). - add a BAR2-shadow hash/object-entry search (8-byte entry walk, 4 KiB block-base candidates, target/limit validation) to the resolution chain after FB/shadow/RAM; - fix the hash instance field mask to 11 bits (0x7ff); - carry the object target and route the notifier status through the FB shadow for target 1, guest PA for sysmem targets 2/3; - SET_NOTIFIER_CONTROL.OFFSET is in 16-byte units (was scaled by 4).
* vgsp: bar1_full A/B knob for the display instance-memory mappingArthur Hanson Rasmusson25 hours
| | | | | | | | | | | | The guest sees a 256 MiB BAR1 over a 512 MiB FB, so the display instance block at 0x1fff0000 (top of FB) is not directly mappable and the guest's hash-table writes never reach the emulated vidmem shadow (r1633: notifier ctxDMA handles 0x10013/0x10075 unresolvable; not in the shadow, not in guest RAM; 0x20800afa GSP-DMA never sent). bar1_full=1 exposes the whole emulated FB as BAR1 (the m143 behaviour) so the test can settle whether the aperture is the missing link; the default keeps the historical 256 MiB physical aperture (CUDA-safe).
* vgsp-disp: find the instance block by the ctxDMA handle anywhereArthur Hanson Rasmusson25 hours
| | | | | | | | | | | | | | | The guest BAR1 is a 256 MB window over a 512 MB FB, so the RM writes vidmem through a shifted BAR1 block and the announced instance PA does not index the shadow (r1632: hash_nz=0 at 0x1fff0000; scan also empty where it looked). Resolve like the hardware does, but empirically: parse the announced block; if the handle is not there, search the FB shadow (then guest RAM for the coherent-mapping case) for the 64 KB block that contains an entry for the ctxDMA handle and _parses_ into a valid object entry; use that block's object entry for PA/limit. Cheap for the 56-per-boot notifier writes: a failed handle is not rescanned for 5 s.
* vgsp-disp: retry the instance block through guest RAM when the shadow copy ↵Arthur Hanson Rasmusson25 hours
| | | | | | | | | is empty The RM's vidmem writes may use the coherent CPU mapping rather than the BAR1 aperture, in which case the display instance block lands at the announced address in guest RAM. Log the source used (src=fb|ram) and fall back to vfio_dma_rw before reporting the hash table empty.
* vgsp-disp: never publish GET past PUT; bounded no-parse push dumpArthur Hanson Rasmusson26 hours
| | | | | | | | | | | | | | | r1630: the window channel's first push read returned unparseable bytes (0 methods) and the parser walked off the 4 KB ring, publishing GET=0x1000 while PUT stayed 0x4e4. nvidia-modeset then wedged in 'Error while waiting for GPU progress', Xorg never started and glxinfo/ GZDoom never reached the GL path. Only consume a segment that parses exactly to the driver's PUT. On a short/invalid read, leave consumed unchanged: the pump retries next pass (which also covers a ring the guest kicked before its content is visible) and GET can never move past PUT. Dump the head of an unparseable segment (bounded, disp_dbg) to name what the ring holds. Reset dump budgets per mdev cleanup so each boot keeps its diagnostics.
* vgsp-disp: locate where the instance hash table actually landsArthur Hanson Rasmusson26 hours
| | | | | | | | The 0x20800a49 announce says vidmem PA 0x1fff0000 but that block reads zero in the function RAM shadow. Bound a one-shot whole-shadow scan for hash-entry-shaped words (word1 = {chn[31:25], instance[24:14], client[13:0]}) and log BAR1_BLOCK (BAR0 0x1704) so the BAR1 aperture shift, if any, becomes visible.
* vgsp-disp: resolve the notifier via the announced display instance memoryArthur Hanson Rasmusson26 hours
| | | | | | | | | | | | The guest announces the display instance-memory block (8 KB context-DMA hash table + entries, vidmem PA 0x1fff0000 on r1627) via NV2080_CTRL_CMD_INTERNAL_DISPLAY_WRITE_INST_MEM (0x20800a49), but the engine ignored it and scanned its FB shadow blindly, never finding the hash entry - so SET_NOTIFIER_DMA handle 0x10013 resolved to pa=0 and UPDATE never wrote FINISHED (r1627: UPDATE armed=1 notifier=0x0/0). Handle 0xa49, record pa/size/address space per guest, read the block through the FB shadow (or guest RAM for sysmem), and parse the hash table from the announced location with bounded diagnostics.
* vgsp-rm: report TU104 GR identity in KGR_GET_INFO (SM_VERSION 7.5)Arthur Hanson Rasmusson27 hours
| | | | | | | | | | nv3dAllocDevice reads SM_VERSION (GR info index 0x0c) through the 3D library; with the emulated KGR reply leaving it 0 it gets SM_VERSION_NONE, GetSpaVersion fails, nvHsAllocDevice returns FALSE silently and nvidia-drm reports 'Failed to allocate NvKmsKapiDevice' (r1626 gdb: nvHsAllocDevice -> nvHs3dAllocDevice -> nv3dAllocDevice). Fill SM_VERSION=0x705 (7.5) plus MAX_WARPS_PER_SM=64, MAX_THREADS_PER_WARP=32 and THREAD_STACK_SCALING_FACTOR=1.
* vgsp-disp: byte method addresses in the push parser (x4)Arthur Hanson Rasmusson27 hours
| | | | | | | | | The NV DMA METHOD_OFFSET field is a dword index; gsp_disp_method() compares against byte offsets (UPDATE 0x200, notifier 0x208/0x20c). The executor compared the raw index (0x82) against 0x200/0x208, so UPDATE and SET_NOTIFIER could never match and the FINISHED write never fired (exposed by the r1625 raw push dumps). Shift the decoded offset to bytes.
* vgsp-disp: bounded raw push dumps; 14-bit method offset decodeArthur Hanson Rasmusson27 hours
| | | | | | | | | | disp_dbg now dumps the head and tail of the first four executed push segments - the tail is where the core update completion lives (UPDATE 0x200 / SET_NOTIFIER 0x208/0x20c), and r1624's 16-byte second push carried neither parseable method. The NV DMA method offset field is 15:2 (14 bits), not 13:2; widen the parse mask so higher display method addresses are not truncated.
* vgsp-disp: fix disp.lock self-deadlock; backfill h_object from the allocArthur Hanson Rasmusson33 hours
| | | | | | | | | | | | | gsp_disp_engine_channel_add() took disp.lock and then called the self-locking gsp_disp_find_object(), deadlocking the RPC thread on the first display push-buffer control (r1621c: watchdog hard lockups in gsp_emu_0 channel_add+0x13b and gsp-sema-svc pump+0x88, R13=0xc57d). Use a caller-holds-lock helper instead. The push-buffer control arrives before the alloc (control, registration, alloc), so a channel registered from the control had h_object=0 and the completion-event post stayed inert. Backfill h_object when the alloc note lands for a registered channel.
* vgsp-disp: unconditional pushbuffer receipt log + NvBool valid fixArthur Hanson Rasmusson34 hours
| | | | | | | | | | | | | Log every NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) receipt with the decoded 56-byte params struct, and always log rejected channel registrations and SET_NOTIFIER_DMA - boot-only volume, settles whether the kernel RM ever programs the display push buffers through that control (r1621 follow-up). valid is an NvBool (1 byte); the previous u32 load could read the padding bytes and turn a PIO-channel valid=0 into a false positive. Raise the engine log budget to 4096.
* vgsp-disp: host-side EVO display engine (channels, push buffer, notifier, ↵Arthur Hanson Rasmusson38 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | raster) The guest nvidia-modeset drives the display through per-channel NV-DMA push buffers kicked via the BAR0 UDISP control windows. Emulate that engine contract host-side, unmodified guest: - channel registration: display-channel RM objects (core 0xc57d, window 0xc57e, cursor 0xc57b, 0xc57a) are noted from the alloc stream, and the internal control NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) records each push buffer (guest PA, size, class, instance, validity); - PUT polling + GET publication in the channel control pages (core 0x680000, window 0x690000+n*0x1000, cursor 0x6D8000+n*0x1000); - NV-DMA method parser (METHOD/ONE_INC/NONINC/JUMP/SET_SUBDEVICE_MASK) with the wrap-JUMP follow; - completion: SET_CONTEXT_DMA_NOTIFIER / SET_NOTIFIER_CONTROL tracking, exact notifier-surface resolution through the display instance hash table (no heuristic writes), NV_DISP_NOTIFIER FINISHED on UPDATE (0x200), and the channel completion event post; - free-running 1080p60 raster line for NVC57E_GET_LINE. All effects are behind independent knobs (disp_engine, disp_finish, disp_vblank, disp_events, disp_notifier_pa) with verbose diagnostics (disp_dbg, disp_dump), so the previous behaviour stays one load away.
* vgsp-rm: report connected DFP-0 + 1920x1080 EDID, accept IMP, route headArthur Hanson Rasmusson39 hours
| | | | | | | | | | | | - 0x730108/0x730240/0x73028a: display 0 connected, DFP, 600 MHz pclk - 0x730245 GET_EDID_V2: 128-byte EDID 1.3 (1920x1080@60 + range limits) - 0xc3720101 IMP: echo request + bIsPossible (byte 1904) so EDID modes validate - 0x73010b head routing map: displayMask=1, headRoutingMap=0 (display 0->head 0) - alloc dump limit raised to expose the display channel allocations The guest boot display init still needs the display engine (core notifier + vblank/swap-ready) before the mode set can complete; this is an incremental display-state step, not a boot-fix (evidence: backups/evidence-20261002-victory/r1619/).
* vgsp-rm: pump critical event posts instead of dropping on a full status ringArthur Hanson Rasmusson40 hours
| | | | | | | | | | | | | | | | r1615: the status queue declared itself full (free=0) while a critical completion event was pending and the old path dropped the event immediately (r1614: 'status ring full ... event dropped' during the X/GR bring-up). Critical event wake-ups now pump the guest's consumption cursor for up to 200 ms (1 ms sleeps, cursor re-read under the stat lock) before a drop is allowed; non-critical event wake-ups keep the immediate-drop policy and replies keep their 50 ms wait. The r1615c A/B shows the ring-full drops gone (only the separate 1 s event-burst cap remains, which is a rate limit, not a ring-space drop). Evidence: backups/evidence-20261002-victory/r1615/ (host dmesg window, guest poll). Unmodified-guest GL is still blocked by the nvClip modeNum bit0 (r1614); no video claim.
* vgsp-sema: ack the class-2d IMMD NOTIFY from the X DDX syncArthur Hanson Rasmusson43 hours
| | | | | | | | | | | | | The X server's nvFermiSync queues the class-2d completion as IMMD_DATA methods (SET_NOTIFY_A/B + NOTIFY 0x10c WRITE_ONLY). The run-shaped watchdog form was already handled; the IMMD form fell into the default case, so the zeroed NvNotification was never authored and the server spun in WAIT (0,8,0x8000,...) with the status left IN_PROGRESS. Handle the IMMD form and treat the 0x8000 IN_PROGRESS status as armed in the keepalive scan. The mode-set then completes and the 2D sync acks (verified on the emulated vGPU: no WAIT, sema-notify2d zeroed). The A/B knob sema_2d_notify_immd=0 restores the old dropped-NOTIFY behaviour.
* vgsp: display caps window seed A/B for the guest display subsystemArthur Hanson Rasmusson2 days
|
* vgsp-rm: report GPU GART size + DMA flags in BUS_GET_INFO_V2Arthur Hanson Rasmusson2 days
|
* vgsp-gl: author the PS/TCS stage images for the emitted mask slotsArthur Hanson Rasmusson2 days
|
* vgsp-gl: raster blend/alpha/cull/point/ZCULL neutral A/B stateArthur Hanson Rasmusson2 days
|
* vgsp-gl: follow migrated screen pages in the GR copy-outArthur Hanson Rasmusson2 days
|
* vgsp-gl: GS SPH placement/maps/context A/B knobsArthur Hanson Rasmusson2 days
|
* vgsp-gl: raster-enable prelude (CT_WRITE/depth/stencil/scissor) + DS reset fixArthur Hanson Rasmusson2 days
|
* vgsp-gl: GS-mode/FASTGS variants for the synth GS SPHArthur Hanson Rasmusson2 days
|
* vgsp-gl: synthesized GS SPH image + map variants for the SPH18 gateArthur Hanson Rasmusson3 days
|
* vgsp-gl: per-stage synth SPH disable mask (r1562: DS wall reduced to SPH18)Arthur Hanson Rasmusson3 days
|
* vgsp-gl: pair-safe synth SPH binds + per-stage bind disableArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | sema_gl_sph_bind_pair_safe (default 0) emits the synth SPH-BIND block only after closing a carried-open BEGIN/END pair, removing the r1558 EC 0x0d at 0x2018/0x1614. sema_gl_sph_stage_disable (default 0, bit j = suppress synth slot j) enables per-stage A/Bs. r1560 (mask 0x35, pair-safe on): 13 beef launches, 0 Class Error, DS 900400a0 (SPH5/7/18) - the synth-block fault is gone. r1561 (stage-disable TCS): VSB 5/7 cleared but VSA/TCS validation bits returned and GS 18 persisted; the remaining bits are stage/family state, not a universal missing bind. Changed pages max 2; frame black. Evidence and ranked next step: Handoff-vGPU-IO.md SESSION 155 cont 9.
* vgsp-gl: bounded setup-push hold for maturity debuggingArthur Hanson Rasmusson3 days
| | | | | | | | | | sema_gr_setup_hold_ms (default 0, clamp 2000 ms) holds/defer the draw window while the 60216-byte setup push pin is landing, replacing the ~50% IMMATURE-SKIP lottery. Measured: 2000 ms stalls the ring behind the unreadable 0x4021004 entry (8 launches then silence), so the default stays 0; the param is a debug gate only. r1557 with hold=0 produced 64 beef launches and the DS A/B baseline 80000000->a0040a06. Evidence: Handoff cont 8.
* vgsp-gl: engine-visible MME selector seed + RT0 third-dimension seedArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | sema_gl_mme_selector_seed (default 0) emits engine-visible 0x2380/0x2384/ 0x2388/0x238c (fixed-CB selector base>>8, d29) before the draw window; the old state seed only wrote MME shadow scratch, so with the selector programmer elided LOAD_CONSTANT_BUFFER (0x2390 <- 0xbf800000) failed with EC 0x03. r1545: 27 beef launches, 0 errors at 0x2390. sema_gl_rt0_third_dim (default 0) writes RT0 0x818 THIRD_DIMENSION=1 so the layered-RT validation matches the driver's layer-mode ONE; r1548: the 0x17e0/EC 0xd2 illegal color-target layer-vs-third-dimension error is gone and the DS reached validation with stage5 bound (0x19a0000). Both default-off; legacy bytes unchanged. Evidence: Handoff cont 5/6.
* vgsp-gl: add sema_sph_bind_mask for slot-selective synth SPH bindsArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | With sema_gl_sph_bind=0 the r1538 window carries only the client's two slot-1 (VERTEX_B) binds; the DS then faults a0040800 (PS stage SPH11|SPH18, stage5=0) because the PS program start is missing. Add sema_sph_bind_mask (bit j = synth slot j) so the PS bind can be re-enabled alone (0x20) while the vertex synth binds stay off; the legacy sph_bind=1 behavior is byte-identical (j2/j5 both emitted). r1541 (mask=0x20): the receipt fires (j5=1 x8) but stage5 stays zero and the launch poisons at LOAD_CONSTANT_BUFFER (0x2390 <- 0xbf800000, EC 0x03), so the j5 synth emission needs the r1456 selector/state fix before this axis can be evaluated. Parameter default 0; evidence in Handoff-vGPU-IO.md.
* vgsp-gl: close a BEGIN/END pair carried into the draw windowArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | r1526's first calls-kept draw window faulted with a GR class error at SET_FRONT_FACE (0x191c <- 0x901) EC 0x0d ILLEGAL_METHOD_IN_BEGIN_END: the window entered with a BEGIN..END pair still open from the previous emitted window, so the first client state method ran inside it. With the prelude CALL runs kept (iram_gate=0, hold_settle=0), r1529 then executed the draw macro (mac=0x22) with zero class errors and engine-side page writes. Add sema_gl_pair_close_entry (default 0, A/B): when the pair tracker carries an open pair into the window, emit the driver's own END form (0x1614 + event word, event 1 for split chains 1/2) before the first window run, then let the normal walk rebase the model. Receipt: PAIR-CLOSE-ENTRY split/ev/window. r1532 showed the close can misfire after refused launches (the injected END itself faulted at 0x1614), so the parameter stays off by default until the model is committed only on retire.
* vgsp-gl: spend the draw-coverage receipts on real-CB drawsArthur Hanson Rasmusson3 days
| | | | | | | | | The GL-COVER 12/boot budget was consumed by the pre-CB (synthetic identity) draws, so no clip-coverage receipt ever described a draw that used the client's real fixed CB. Emit the receipts only while svc_gl_cb_img_valid and re-arm the counter whenever a new CB image passes the strict projection gate, so the first draws after the real matrix lands carry the cover receipt.
* vgsp-gl: deliver the fixed CB to the engine-visible seed page directlyArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | The r1515/r1520 decode assembles the client's real fixed-CB image, but svc_gl_cb_copy()'s write to the forced seed VA (0x120700000) is refused by the r1506 authoring-VAS rule: the seed page belongs to the X server's VAS, so the beef channel write only updated the VA shadow while the engine kept reading the black screen page at pa 0x500000 (r1521 seed dump: the image never arrived; the engine fetched the RT clear). The seed is a service-forced engine input, not a client write, so resolve its VA through the VAS/walk/trusted chain and write the backing shadow/FB page directly with svc_write_ap(), bypassing the ownership rule. A bounded CB-SEED receipt reports the destination PA, aperture and the m80 words. Validated in r1522: the seed backing store at dpa 0x500000 holds the assembled image (m80 = the client's projection, e.g. 40a00000/40d55555/ bf9745d1/4211745c/bf800000/42200000) and cb-copy uses src=const-upload (ssrc=15).
* vgsp-gl: decode the 570.144 MME-wrapper fixed-CB upload formArthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | The guest GL driver streams the fixed constant buffer through the C597 MME macros, not the native SET_CONSTANT_BUFFER_SELECTOR/LOAD_CONSTANT_BUFFER methods the r1515 scanner decodes: - CALL_MME_MACRO(0) = SETUP_FIXED_CONST arrives as an IMMD run at method 0x3800 carrying the VPC dword offset (the macro converts it to a byte address, so the fixed-CB offset is imm << 2). - CALL_MME_MACRO(57) = LOAD_CONSTANT_BUFFER_BUG2548370 arrives as a run at 0x39c8 whose payload is [count][count dwords]; the macro writes the data at the current fixed-CB offset and auto-increments it. - CALL_MME_MACRO(58) = LOAD_CONSTANT_BUFFER_OFFSET arrives at 0x39d0 with [offsetBytes]. r1517's own CHUNK1 dump of the 7144-byte draw window carries the real glxgears MVP this way (pixel-space 5.0/6.667 scales, -1.1818/36.3636 near/far row and the -1/40 w row = glFrustum(-1,1,-0.75,0.75,5,60) x translate(0,0,-40)); the old scanner ignored those runs, assembled only the 10 state-patch words, and the strict gate never passed, so every launch ran with the synthetic identity and the geometry clipped. With the wrapper form decoded the assembled 4 KB image carries the client's real MVP at c[0x0][0x80..0xbc], passes svc_gl_cb_mvp_ok(), and svc_gl_cb_copy() delivers it to the forced MME seed page as src=const-upload (src_ssrc=15) instead of synthetic-id.
* vgsp-gl: decode the client fixed-CB upload runs and gate the assembled imageArthur Hanson Rasmusson3 days
|
* vgsp-gl: receipt the draw's clip coverage and refuse non-MVP fixed-CB pagesArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1512 adds one bounded GL-COVER receipt per replayed draw. It decodes the window's index buffer (0x17c8/0x17d8 + size), the stream-0 stride (0x1c00) and position offset (0x1160), resolves the CALL_MME_DATA (0x3810) stream base, reads the referenced vertices and evaluates the clip-space position in Q16.16 integer math with the exact c[0x0][0x80..0xbc] block the replay delivers, printing per-vertex clip codes plus clip/NDC/screen bboxes and the injected viewport scale/offset/clip. It also prints the fixed-CB copy provenance and tries the client's own scratch18 page read-only. Measured (r1512): real gear vertices (stride 24, position offset 0, 3.549 0.852 -0.5) but the delivered "matrix" was a rotation block (row3 = 0.1268 0.9922 0 1), giving clip w ~= 1.1 instead of the camera distance (~40) and 57/64 sampled vertices outside clip. The draw was clipped by a non-projection constant block, not by zero/garbage VS output. r1513/r1514 fix the source: the fixed-CB copy now prefers the client's SET_MME_SHADOW_SCRATCH(0x18) page and the client-CB VAs its own writes published (0x43e0000/0x4450000), requires a strict projection shape (|row3.x|,|row3.y| < 0.02 and row3.z/w not both zero), and the resolver no longer accepts an unresolved PA 0 page. Non-MVP pages (including the old forced 0x0cd70000 page) can no longer become the seed; when no real page is found the r1476 identity positive control is used. r1513/r1514 receipts: the strict gate finds no readable client MVP page on these boots (the client's fixed-CB content is not materialised in the emulated memory), so the seed is the controlled identity and the identity still clips gear radii > 1 (12 launches r1514, 20 poison, no fragments; root xwd 2 nonblack pixels at (216,0)-(409,2) 0x77edc). Next wall: get the client's fixed-CB contents into its own page (emulate the VPC/ LOAD_CONSTANT_BUFFER writes from the init push) so the VS receives a real MVP. Build: make -C kernel (green). Evidence: backups/evidence-20261002-victory/r1512..r1514.
* vgsp-gl: sweep the beef ring head for the client's init uploads and ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | quarantine the screen/code-heap overlap The GL client's one-shot LOAD_INLINE_DATA uploads (code images, vertex and index buffers) sit at the head of its GPFIFO ring, but the first observed GP_PUT can already be far past them (r1508: put=8982), so the continuation sweep never decoded them and the FB fetch pages stayed zero. Sweep the head once per beef channel in inline-only mode with the read-arbitrated, tail-aware decoder: r1509 receipts show 'sema-utilsweep swept=64 writes=16' and 'inline write dst=0x44ff000 -> pa=0xb9f000 bytes=1550 data8=9a996940...', after which sema_probe reads the client's real vertex floats and the u16 index stream at 0xb9d410/0xb9fcc8. The guest's shader/code-heap BAR1 upload can also land on the captured X screen's pages (r1508/r1510: vidmem 0x200000 held a program image while the X screen VA 0x120400000 maps there). Snapshot the captured surface at bind time; before a launch whose surface page 0 carries the code-heap/SPH signature, restore the surface from that snapshot (a black X-clear baseline when the bind happened after the upload). The quarantine is content-gated, preserves raster stores that follow, and r1509/r1511 show the clean page 0 (0xff000000) with no code bytes.
* vgsp-gl: scope client inline writes to the authoring VAS and receipt surface ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | ownership The captured 1280x720 colour-target bind is the X server's screen (VA 0x120400000, 900 contiguous FB pages from 0x200000 to 0x583000 in the emitting VAS 0x10005). The GL client uses the same 0x1200xxxxx VAs for its own allocations; its fixed-CB write (0x120700000) was resolved through the X VAS by the global cross-VAS walk and overwrote screen page 0x500000 with the CB matrix. Resolve client inline writes through the authoring channel's own VAS (GR handle 0xbeef0100 inherits its CE siblings' VAS 0xbeef0300) and refuse cross-VAS translation for a channel-owned page whose own VAS does not map it (VA shadow instead). Receipts: SURF-OWNER (emitting channel, VAS span coverage first/mid/last PA, retarget) and GRCE owner-vas. Add viewport mode 7 (the client's 800x600 window viewport) and a VP-METHOD census of viewport-family runs in trusted pushes; a bounded BAR1 screen-range write witness. r1506: the CB no longer touches the screen (vidmem 0x500000 reads the black clear), screen ownership proven. r1507/r1508: the active indexed draw's vertex/index pages are all-zero in its own FB shadow in those boots, so no fragments; the client never emits a real 0x0a00 viewport block (the 0xa00 hits are misaligned vertex floats), so the viewport stays synthesized.
* vgsp-gl: scope program pages to the emitting VAS, make the MME prelude ↵Arthur Hanson Rasmusson4 days
| | | | boot-independent, and discover the fixed CB by content
* vgsp-gl: deliver the real pixel-stage image and receipt the active draw's ↵Arthur Hanson Rasmusson4 days
| | | | topology/index args
* vgsp-gr: deliver empty FB fetch pages from real FBMEM, discover the CB per ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | boot, clear the DS latch after each window The active indexed draw's vertex/index buffers resolve through the client's page tables to vidmem pages whose emulated BAR1 shadow is empty (no emulated upload path ever populated it), so the engine fetched zeros and the draw stored nothing. Three delivery paths now cover the page: a real-FB VID leaf for launch fetch pages (QMD pointers, never the data-fill surface) and for vertex streams when every shadow byte is zero; a sysmem-backing copy when the same VA also has a nonzero SYS mapping; otherwise the existing shadow page is used untouched. Render-target pages keep their shadow identity so the copy-out can still ship stores back to the guest. The fixed constant buffer is discovered per boot: the captured SET_MME_SHADOW_SCRATCH(0x18) value is authoritative, the historically observed base is a gated fallback, and a resolved real page is remembered for later misses. The DS HWW ESR latch is now also cleared (W1C) after each replayed window, so a failed window cannot poison the next window's entry state. Validated with three supervised cycles (r1497-r1499): the active streams read the client's real vertex floats, the real MVP resolves, poison stays at 0-1 per run, and the engine clears the render target to opaque black (dump_vidmem 0x200000 = ff000000) with the guest window still all black - the remaining wall is geometry coverage, not data delivery.
* vgsp-gr: keep the validated fixed CB across launches and map each VTG stream ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | contiguously - Remember the last fixed-CB page that resolved through a SYS source and passed the matrix gate; a later resolution miss (or a method-page answer) reuses it instead of zeroing the seed page with the synthetic identity. Only a boot with no validated read ever uses the identity fallback. Do not skip the write on an unchanged hash: the seed page lives in the client's screen allocation and the guest can rewrite it between launches. - Treat the CALL_MME_MACRO(2) vertex stream as one range: map [base,end) into a fresh contiguous fetch line and rewrite both ends from it, preserving the client's stream length across 4 KB boundaries. Unresolvable pages map the module zero page (a zero vertex, never a fault). The generic per-word pass remains the fallback. - Diagnostics: cb-copy logs the first 8 seed-page words and the cached flag; MME-VSTREAM-LINE dumps the resolved base page (client VA, HPA, page count, first 8 words). - Evidence: r1494 (poison 11/17 -> 1/16, real vertex floats at the stream bases, CB cache verified live with src=vaswalk -> src=cached-real) and r1495/r1496 (the active draw's vertex/index page is an all-zero vidmem shadow page while the data exists in guest sysmem - the new wall).
* vgsp-gr: read the fixed CB from the engine-visible page and never deliver a ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | header-only VS image The GL draw's VS was reading two wrong inputs. First, the fixed-CB copy resolved the client VA through a learned/FB layer first, so it read the emulated BAR1 vidmem shadow - a buffer the engine never writes - and delivered unrelated vidmem (r1490 first=09037223 00000004; r1482 oscillated between a float row, method words and zeros). Resolve the CB the way the engine does: channel VAS, every registered VAS page-table walk, then the GR relocation resolver; only a SYS answer is content-valid and an FB answer is flagged. The matrix gate now requires four normal-magnitude floats in c[0x0][0x80..0xbc] (r1492 accepted a method page as a matrix); a rejected read authors the identity MVP. Second, the captured 1536 B VTG upload is spliced at a page boundary: the delivered image was the SPH header plus ZERO SASS, so the VS executed no code. Reject captured program images whose SASS body [0x80,min(len,0x200)) is zero (the real-upload ring record, the 020a0481 cache and the window's own upload all pass the gate) and deliver the built-in known-good VTG image (the client's own SPH V4T1 020a0481 + SASS) at the bind VA instead; sema_gl_vs_img=0 restores the old behaviour. Diagnostics: cb-matrix/cb-const dumps of every VS-read constant block, SPH-ALIAS code4 words at the bind, and MME-VSTREAM post-relocation stream/limit/address payloads. r1491-r1493 (VP_MODE=6, RT0=1): the bind page now shows the real SASS (code4=ff047321 0000a0ff ...) and the CB/identity delivery is logged, but the draw still produces no fragments (retirement 0-3/900 = the forced MME seed pages only; xwd decoration rows only). Next wall: the vertex attribute/staging fetch (slot-57 0x39c8 data and the staging scratch 0x36/0x37), not the shader image or the fixed CB.
* vgsp-gr: re-target the captured render surface per launch so a partial ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | VA-colliding allocation cannot receive the draw The SURF-PRELUDE target pair was patched once per capture generation and then reused; the re-patch test was dead because gsp_sema_gr_surf_recs() only fills in the VA when it returns true and the code negated the call, so 'want' could never be computed. A later draw whose ~10-page SYS allocation sits at the same 0x1204xxxxx VA as the X server's 1280x720 screen inherited the X server's 900-page target; the engine's RT pair then named the client's command/operand buffer, which is why the 'surface' held method words and copy-out saw no engine pixels. Add gsp_phys_gr_surf_launch_target(): only a complete contiguous rec run for the captured surface may use its data-rec bounce lane; a partial run falls back to the boot-time contiguous alias built from the captured bind's VAS pages (the real screen HPAs). Re-patch whenever the cached pair differs from that effective target (SURF-PRELUDE retarget); RT0 copies the same words, so the RT0==RT1 design is unchanged. r1490 (VP_MODE=6 RT0=1, r1476-args): 15 launches, poison=0, retarget have=0xa000000 want=0x15e0000 for the partial lane then 900-page targets, output retirement up to 3/900 with 2 copy-out pages changed by engine, and a non-empty 3.69 MB xwd. New wall: the draw still produces no raster fragments - the only changed pages are the forced MME constant-buffer pages inside the screen (offset pages 768/772/773, 0xff000000 fills). Also harden tools/guest-diag/qga_fetch.py (retry open, long timeout, atomic .part write, clear error exit) for evidence capture.
* vgsp-gr: hold calls on a stream-damaged push so a dropped chunk cannot run ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | LOAD_CONSTANT_BUFFER without its selector state A chunked GL draw whose earlier chunk was dropped (prelude LOAD-ONLY or the r1447 arming window hold) replayed the remaining chunks' calls alone; the constant-buffer selector (0x2380) lived in the dropped chunk, so the bug2548370 macro's LOAD_CONSTANT_BUFFER(0x2390) class-errored (ErrorCode 3) and the engine poisoned (badf1201 sentinel: pc=513/mac=0xf1 are its artifact, not a macro). Propagate the stream-relative chunk offset through the candidate and submit path, keep a per-push STREAM-DAMAGE record of the lowest dropped chunk, emit later chunks calls-held (the proven-safe shape), never arm the arming window-hold on a damaged stream, and start a fresh section at stream_rel==0. r1487: the exact r1485 damaging shape now retires clean (events=5, no poison) and the next chunk is captured; r1486 (holds off) still poisons because the first launch runs against a partially packed prelude, confirming the dropped chunk is the cause, not the hold release.