| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- 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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The X DDX's NV_ESC_RM_VID_HEAP_CONTROL (ioctl 0x4a) allocates scrubbed
pages through the guest PMA's CeUtils scrubber channel; it waits on the
channel buffer's finish payload (channelWaitForFinishPayload), which the
host's svc_scrub_pass was supposed to author but never did because the
guest scanner had not registered fin_pa/hsem_pa (pa_ok=0 in every run).
The channel buffer is pb + GPFIFO + sema + finish, and the scrubber's
GPFIFO VA is pb + pbSize, so the host semaphore is gpfifo_va +
entries*8 and the finish payload is that +4. Resolve that VA through the
learned map or the VAS walk at the first pass and register the PAs in
place (SYS aperture only).
r1665: `scrub geometry hsem_va=0x12006c000 fin_va=0x12006c004 ->
hsem_pa=0x10f46a000 fin_pa=0x10f46a004`, then `scrub author put=1..11`
and the X server left the kernel scrub spin entirely: perf on Xorg is now
100 % in nvidia_drv.so+0xaee70 (a DDX userspace loop, next wall) with no
_nv018351rm/_nv015102rm samples.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The X server's class2d kick channel (bfef0002) has a 2-entry ring at a page
end (0x1203cfff0) and an FB userd offset the guest never writes; the pump's
USERD-miss path returned before the entry-0 arm decode, so the class2d
SET_NOTIFY target was never captured and every kick push had no address.
Decode the ring head directly when the USERD is missing (the ring PA still
resolves) and author the zeroed NvNotification at the captured target.
r1664: the first bfef0002 instance still missed, but the re-registered one
adopted its USERD on the PUT step (put 1 -> 2) at pa=0x10fecc000, decoded
its pushes at 0x1203c0000 (len 32/64, have_rel=1), and the notify2d writes
fire at va=0x12000d0b0. Xorg's spin moved off the control wait
(_nv015102rm 66 % -> 0) and now sits in _nv018351rm (30 %); GZDoom still
spins in glcore.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
post-reboot diagnostics
The direct-GL GL client's CE channels (beef0101/0102) declare a
pool-relative FB control page (0x244f800 / 0x244f400 in r1656) while their
GPFIFO ring is mapped in guest RAM, and their ring publishes from slot 2
(entry 0 stays zero). The entry-0 layout gate could never fire, the BAR0
fallback rejects offsets past its 16 MB shadow, and the GR-only VRAM shape
scan never ran for them, so the channels retired with submissions=0 and
the client's CE releases were never applied.
r1661/r1663 evidence: enabling the VRAM shape scan for the beef CE family
(hole-tolerant entry validation, newest-slot required, a GET bounded to
one ring) finds the real control page (fb 0xa00000, put=1) and the CE push
at 0x40e0000 decodes; beef0101 now retires submissions=1 with its
semaphore releases applied.
Also:
- resolve the non-pool direct-GL semaphore window (0x4000000..0x4300000)
through every published VAS translation (the general resolver can name
a stale page while the client polls the beef0300 walk page);
- author 0xffffffff in the beef channel's 128 kick-slot records (the
glcore 570.144 kick wait polls exactly that payload; r1662 writes are
visible in the guest page, but this is not yet the X-server wall);
- one-shot nonzero-word dump of the beef0100 push (r1663 proved the GR
init push's host semaphore is a true 32-bit VA 0x4238000 payload 1 with
hi=0 in v1, so that release is correct);
- name CE/GR in the VRAM-scan adoption line.
Next wall (r1663): the X server spins in _nv015102rm/os_schedule (66 %) and
_nv018351rm (30 %) after the GL client's GLX request; GZDoom blocks in
_xcb_wait_for_reply. The display UPDATE completion event was posted and
re-posted at 12:12:20, so this is the flip/GLX-sync path, not the lost
UPDATE event.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
direct-GL completions
The GL client's direct-GL init push (beef0100, va=0x4000000) decoded its
release (rel=0x4238000 pay=1) but never applied it: svc_fwd_defer_arm() is
global over the cross-pass GR candidate ring, so stale unoffered CUDA/RC
candidates made any later push "defer" its release. The record was then
wiped by the next decode pass (the r824 failure mode) - no sema-sw,
pending or deferred line, and the client's fence never advanced.
Apply the r824 rule already used by the C56F site to the SET_REPORT_SEMAPHORE
and LAUNCH_DMA sites: defer only when the candidate ring entry belongs to
this push (push_va match). A release whose push owns no candidate applies
inline. Also queue svc_rel_apply_906f() releases on a translation miss
instead of dropping them, add a bounded low-VA sema-sw provenance window,
and fan direct-GL semaphore completions (0x4000000..0x4300000) through
every published VAS translation (the general resolver can name a stale
page while the client polls the beef0300 walk page).
Evidence: backups/evidence-20261002-victory/r1656 (beef0100 release decoded,
never applied) and r1657 (sema-sw va=0x4238000 rb_ok=1 after the fix).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The GL client arms its class2d kick channel with SET_NOTIFY_A/B + NOTIFY in
the first GPFIFO entry, then submits short kick pushes (NOTIFY only) that
rely on the target staying programmed in the channel context. Two host
gaps left the short NOTIFY with no address, so no completion was authored
and the client spun in its kick/fence wait:
- a same-handle channel re-registration memset() erased notify2d_va even
though the guest kept using the target from the previous incarnation;
- the pump's walk seed consumes only the newest entries ending at the live
PUT, so entry 0 (the arm) could be skipped forever.
Preserve notify2d_va across a same-vgpu, same-handle, same-session
re-registration; fall back to it in the GL kick executor when the section
did not re-arm; decode the skipped head entries (bounded, up to 8) on
discovery and from the pump when the kick-family channel still has no
target; and name a NOTIFY that arrives with no target instead of dropping
it silently.
Evidence: backups/evidence-20261002-victory/r1652..r1655 (kick channel
0xbfef0002, short NOTIFY without SET_NOTIFY, walk seed last_get skipping
entry 0). Not yet observed clearing the GL client's glcore spin.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two live walls from the r1649/r1650 windowed-GZDoom runs:
1. Display completion wake-up. All NV01_EVENT registrations carry
hSrcResource=0, so gsp_rm_post_channel_event() always takes the shotgun
fallback, which skips events posted within the 250 ms hint dedup. When the
display UPDATE is the channel's last push, the pump's retry was gated on
new work (put != consumed) and never ran, so the X server's flip wait
spun in _nv018351rm/os_schedule forever. Add
gsp_rm_post_channel_event_force() (bypasses only the hint dedup; the
event burst cap and status-ring free-space discipline still apply), a
per-channel event_retry_at, and an idle-pass retry every 250 ms that
logs "re-posted after deferral". Also move event_burst_at after the cap
check so refused retries cannot keep the window fresh.
2. UVM channel init slot. r1651 gdb proved the channel's tracker entry waits
for value 2 while the authored pool word reads 1; a manual write of 2
cleared uvm_push_end_and_wait. The channel's control-entry + init pushes
are boot-time configuration, so keep the rank slot moving for 10 s after
first submission: one attempt per 250 ms per rank, escalating 1->2->3->4
through every published VAS translation. Values beyond that need the
real CE push decode.
Evidence: backups/evidence-20261002-victory/r1649/ (X spin perf, event
journal), r1650/ (re-post lines), r1651/ (tracker entry value=2, manual
write clears the spin).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
r1647 showed the pool semaphore page can move between the RM memdesc, the
self-discovered directory and the per-client VAS directories. The
first-success walk landed on a stale directory that mapped the pool VA to
the old page (0x2600000) while the guest polled the live page
(0x126502000): the UVM channel-init tracker read 0 and GZDoom spun in
uvm_push_end_and_wait. A manual write to the live page cleared the spin.
Add svc_walk_vaspaces_collect(), which walks one VA through every
registered VAS and returns the distinct translations, and
svc_pool_write_all_vas(), which writes a pool value through each (forward
only, read-back proven, identity and unreadable pages skipped, bounded
log). Pool releases and the tracker-slot fallback now fan out through the
collected translations in addition to the boot primary/secondary
candidates. The counter is forward-only, so a duplicate on a stale
semaphore page is harmless.
Evidence: r1649 (all six UVM channels authored; GZDoom leaves
uvm_spin_loop and advances to the GL client path).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
r1645 live proof fixes the channel-pool slot mapping: UVM allocates one
tracking semaphore per channel in channel-creation order, so channel rank N
owns pool slot N, and channel_init() waits for payload 1 at that slot. The
r1642 rank+1 fallback pre-satisfied the next rank before its
uvm_gpu_semaphore_alloc() zeroed the slot; the value was lost and the guest
spun in uvm_push_end_and_wait (r1644/r1645: manual write of 1 to the rank-1
slot cleared the spin).
- pool-tracker apply now targets slot = ce_index and fans the value out to
the secondary pool-page candidate, which flaps between the RM memdesc and
the guest's VAS walk (r1645: the guest polled the walk page while the boot
cache named a stale, reused page).
- first-submission authoring no longer requires an unlatched ring. A latch
with put=get=0 still needs the release (rank 5, r1646), so every UVM CE
pool channel authors its own rank slot once when the work-submit notifier
clears; one-shot per rank, forward-only, idempotent.
- widen the UVM CE GPFIFO window filter to 0x121800000.
Evidence: backups/evidence-20261002-victory/r1645 (channels advanced once the
rank slot was written) and r1646 (ranks 0-4 green; rank 5 exposed the
latched-but-undecoded gap).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
boot-independent, and discover the fixed CB by content
|
| |
|
|
| |
topology/index args
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
as immd13, and base the SPH region on the bound program's shadow page
- SVC_GR_PUSH_WORDS / GSP_PHYS_GR_RAW_WORDS raised 2048 -> 4096: the beef
full-frame push is 12288 B / 3072 words, so the 2048-word capture tail
failed the 3D mark (raw_ok=0 fit_ok=0) and the launch fell back to a
239-word stub, losing the real 2115-word draw. Now '3D stream chunked
window=1429 words -> 4 chunk(s)'.
- SET_SHADER_EXCEPTIONS (0x1528) is emitted as the client's immd13
(0x8000054a) and skipped when the window already carries it; the
remaining 0x1528 in the log is the client's own benign write.
- sema_gl_sph_region_bind (default 1): the SPH region base is the first
bound program's relocated shadow page, not the forced 0x1500000 pool
base; r1484 latched the fetched SPHs (0,019a0f00,019a0200,0,0,019a0000)
with ds=86040646 (region mismatch), r1485 uses base 0x19b0000 bind
0x19b0900 and the DS accepts (ds=80000000).
- r1484/r1485: the screen now shows gear-class pixels (xwd bbox spanning
the 800x600 window, multicolor); GUEST-WIT shows RT0 page 0 written. The
remaining wall is the MME draw macro 0xf1 / pc 513 poison on the first
calls+window launch after the arming hold is released.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
a cross-VAS 10-page operand buffer
The PS SPH has MRT_ENABLE=0 (writes RT0); the beef window binds no colour
target of its own, so the last trusted 0x800..0xbff run (the X screen
surface 0x120400000, 1280x720, 900 pages) is the render target. Its pages
were resolved through the global VA-keyed pin/ledger, which conflated
clients: the beef client's own injected pin for VA 0x120400000 (a SYS
staging/operand buffer holding SASS/method words) shadowed the X server's
surface VAS and cut the set at 10 pages. Capture the surface's source VAS
and resolve its pages through that VAS in the fill, bypassing the pin
override for this page set. Re-patch the SURF prelude when the launch's
rec base differs from the cached one, and copy the emitted SURF run's
target/geometry into the RT0 run so RT0 == RT1 every launch (was hardcoded
to the 0xa relocation half).
r1483: the beef retirement is now 0/900 pages of the visible surface (was
0/10), RT0-BIND target=0xa000000, data[0] va=0x120400000 pa=0x100000, n_data
=900, 6 launches, poison=0. The engine still stores nothing: GR-STATE sph is
zero at retire and the launch traps at method 0x1528, so the next wall is
making the pipeline program bind visible to the DS, not the RT VA.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
buffer to the engine-visible pages
- inline-apply writes the image into the guest HPA whenever the page is kept
at the guest VA (code_keep_guest), not only for stream3d windows; a shadow
copy is useless when the engine fetches the guest page (r1470: guest=0 VS
then lost to the window-0 shadow copy).
- the standalone 0x180/0x1b0 context-init upload pair (outside any C597
section) is also recorded in the GRCE destination ring, so a later draw
window can find the client's real VTG image at its bind VA.
- sema_gl_cb_copy_to / sema_gl_cb_src_va: copy the client fixed-CB page into
the forced, mapped MME seed page before the launch, so the vertex shader
reads the client's transform constants instead of screen/stale data. Falls
back to a synthetic identity MVP when the client VA cannot be walked.
- cache any push chunk whose first word is a real SPH (020a0481 VTG /
000a1482 PS) and use it as the program-record fallback when the window's
own bind-VA upload was never captured (the init push's continuation chunks
are otherwise judged implausible and never reach the ring).
- r1481/r1482: the real VS SPH+code and PS are applied guest=1 at the bind
VA, the client CB page resolves and is copied, poison=0 over 9-10 launches;
render-target writes still zero - the remaining wall is the draw's
render-target/colour-target binding (the beef window's output retirement
set is 10 pages of shader-like data, not the 900-page screen surface).
|
| |
|
|
| |
every 4KB page of the BAR1 shadow before the GR publish and diffs after the output-retirement wait, reporting any changed page outside the sampled output set; vidmem_hash_snap/vidmem_hash_diff manual module params; default 0 is a strict no-op
|