| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 UPDATE path posted the channel completion event on every UPDATE,
including armed=0 updates where no notifier was written (r1665 journal:
armed=0 `-> none` still posts). Those events drive the DDX's NVKMS
FLIP_OCCURRED handler (nvidia_drv.so 0xaee70), which reaps the four
notifier slots of every layer and has a fixed-point retry when the
completed layer does not match the first DPY object's layer; with
non-flip updates raising the event, Xorg spun there at 100 %.
Gate the post on `wrote` (armed + notifier written + FINISHED). r1666:
the 0xaee70 spin is gone from perf; Xorg moved on to a bounded XAA
action-list scan (nvidia_drv.so 0x4dc9c0, nvXAAHandleActionList) plus
do_vfs_ioctl/schedule, i.e. the server main loop is no longer wedged in
the flip reaper.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- 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/).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|