summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/wall2/README-session77.md
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 17:21:25 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 17:21:25 -0400
commit5f8aa523a2dd29ef2fe48bc47c2af5937d8b53ac (patch)
tree66d6d0a9859f9577279b62012bcdd5d4d6b38ad4 /tools/guest-diag/wall2/README-session77.md
parent8700f65ae13ccdbeb6e66496ac2371c0a0fc0274 (diff)
downloadopen-iov-5f8aa523a2dd29ef2fe48bc47c2af5937d8b53ac.tar.gz
open-iov-5f8aa523a2dd29ef2fe48bc47c2af5937d8b53ac.zip
wall2 session 114: the COMPR+2MB VidHeap class (attr&0xF000==0x2000, owner 0x474C0000) is the last allocation gate - a live attr flip (COMPR_ANY->NONE at the ioctl) lets vkAllocateMemory through and the client runs the whole pipeline to the FIRST vkQueueSubmit, then times out on the FIRST fence (30 s, the new wall); the zero-touch create recipe is BC (eglcore+0xB33D30 marker clears) + BW (eglcore+0xDCEBD9 device wait-word chaser, the missing piece) + the a8clear count gate; the fence release (push-page readability/completion after the submit) is the only remaining gate to VKFRAME
Diffstat (limited to 'tools/guest-diag/wall2/README-session77.md')
-rw-r--r--tools/guest-diag/wall2/README-session77.md84
1 files changed, 84 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/README-session77.md b/tools/guest-diag/wall2/README-session77.md
index 1ae9a62..1834c29 100644
--- a/tools/guest-diag/wall2/README-session77.md
+++ b/tools/guest-diag/wall2/README-session77.md
@@ -1061,3 +1061,87 @@ service-side durable route: have the SERVICE write the marker into the
channel-buffer page once it can resolve it (the memdesc VA = the CE
channel's buffer; the service's channel registration fields + the PT walk
give the page candidates).
+
+**39. Sessions 112b-114: THE SCRUB GATE FELL, THE COMPR WALL WAS DECODED AND FLIPPED, AND THE FIRST VULKAN SUBMISSION LANDED (VKFENCES IS THE NEW WALL).**
+Context first (sessions 112b/112c, commits `97489187`/`cb7d8ce7`/`752e2b30`/
+`d6ccdaf3`/`8700f65a`): the CeUtils scrubber's finish payload is authored
+in-service (bound to the EXACT 4096-entry channel), the client then leaves
+`scrubCheckAndWaitForSize` permanently and runs
+vkCreateImage -> vkGetImageMemoryRequirements -> vkAllocateMemory; the
+remaining `-2` was decomposed to the guest-internal VidHeap `#149`-shape
+call (attr COMPR_ANY + 2MB page + owner 0x474C0000) returning 0x51
+NV_ERR_NO_MEMORY; session 113 read that as a 64KB comptag/CBM alloc. This
+session REFINED it: the COMPR+2MB class is not always 64KB - the r705
+runs show the *image data* alloc itself (size 0x140000 = 1.25 MB for
+640x480x4 + pad, attr 0x1002000, flags 0xc10d) in exactly the same shape.
+The "separate 64KB CBM" reading was too narrow; every alloc of the class
+{attr&0xF000 == 0x2000, 2MB page, owner 0x474C0000} fails 0x51.
+
+**A. THE ZERO-TOUCH CREATE RECIPE (NEW, SCRIPTED).** Two live assists are
+required per client, both proven again this session: (1) the
+instance-phase marker clears at eglcore+0xB33D30 (t106/t99 `BC`, 5
+clears); (2) THE DEVICE-PHASE WAIT-WORD CHASER at eglcore+0xDCEBD9
+(t99 `BW`: word = *(holder+0x58)+*(u32)(obj2+0x60) with
+obj2 = *(*(rbx+0x70)+0x58); write 1 when 0). Without (2) the client
+reaches `VKDEVICE`'s poll(`/dev/nvidia0`, 10 ms) retry loop and sits
+there INDEFINITELY (session-76 state; the a097 engine-monitor worker
+keeps polling 0x2080a097 every 1.25 s regardless - its reply words are
+still a red herring for the main-thread gate). With (1)+(2) the run is
+`VKINSTANCE ok / VKDEVS 2 / VKDEVICE ok family=0` then straight to the
+image path. `t99.py`-style attach works too: attaching `BW` to an
+already-stuck client writes the word and the client immediately
+proceeds (proven on a stuck pid 15797: WORDWROTE x2 -> VKDEVICE ok ->
+VKFAIL -2 at the alloc).
+NEW TOOLS: `t120.py` (BC+BW+single-shot COMPR->non-COMPR flip),
+`t121.py` (BC+BW+full VidHeap trace from #120), `t122.py` (BC+BW+flip
+for ANY COMPR+2MB internal alloc, size >= 0x10000), `a8clear.py` (the
+no-ptrace count-gate clearer for base+0x2070b7c, reconstructed).
+
+**B. THE FLIP (THE DECISIVE EXPERIMENT).** With `t122.py`: at the
+vidheap ioctl whose params match (attr&0xF000)==0x2000, owner
+0x474C0000, size>=0x10000, the script clears attr bits 13:12
+(COMPR_ANY -> NONE) in the client's own params before the kernel sees
+them. Result (r705c, reproducible twice on the same boot):
+`HIT149 size=0x140000 attr=0x1002000 -> 0x1000000` (image data alloc
+SUCCEEDS), a second `HIT149 size=0x140000 attr=0x1022004 -> 0x1020004`
+(buffer-class COMPR alloc) also succeeds, and the client runs the WHOLE
+pipeline for the first time in project history:
+vkCreateImageView -> buffer -> shader module -> descriptor set
+layout/pool -> pipeline layout -> compute pipeline -> command pool ->
+command buffer -> fence -> vkResetFences -> **vkQueueSubmit OK** ->
+`VKFAIL vkWaitForFences(dev, 1, &fence, VK_TRUE, 30000000000ull) -> 2
+(line 459)` - THE FIRST VULKAN SUBMISSION, then the FIRST FENCE TIMEOUT
+(30 s, the client's own bound; the run exits rc=1 cleanly).
+
+**C. THE NEW WALL = THE FIRST FENCE RELEASE.** Host-side evidence in the
+submit window: the client's GR channel registers
+(`sema-chan: h=0xbeec0100 eng=0 gpfifo=0x4cc0000 ent=32768
+userd=0xfee00 put=11 get=2 ring rc=0 pa=0x1217e3000 ap=1`) - the guest
+driver published 11 GPFIFO entries, the emulation's reader consumed 2;
+the service still reports the channel-init pushes unread
+(`sema-entry: unread h=0xbeec0100 idx=2 va=0x4ca059c len=976 want=0
+exp=0 unread=1`) and `gr_wedge` grew 3 -> 9 over the runs. So the fence's
+release is never authored after the submit - this is the session-76/93
+"wall #2" class (push-page readability/completion), now the ONLY gate
+between the flipped client and the first `VKFRAME seq/DONE` + PPM.
+
+**D. DURABLE-FIX LEADS (for the COMPR class, no guest patching).**
+(1) memmgrAllocHal_GM107 (570.144) downgrades COMPR_ANY -> NONE when
+`pMemorySystemConfig->bDisableCompbitBacking` is set - the guest's
+MEMORY_SYSTEM_STATIC_CONFIG comes from the GSP (the MEMSYS_GET_STATIC_
+CONFIG control 0x20800a1c / the GSP static info path); answering it (or
+the same knob wherever the guest's config actually comes from) is the
+host-side durable equivalent of the flip. 0x20800a1c was NEVER observed
+in the RM_CONTROL log, so first find where the guest's config is fed
+(control cache? GSP init args?) before coding the handler.
+(2) Alternatively locate glcore's COMPR decision (attr construction at
+eglcore+0x2c83fb/0x2c8465 and +0x50e038/0x50e894/0x50e8bd per session
+113) and answer the capability that drives it. (3) The session-85
+device-local -2 story (2g mdev type) remains a prerequisite context.
+
+NEXT (ranked): (1) author the fence release for the first submit (the
+push-page-5 content-match / pinning machinery; or have the service
+complete the fence when it consumes the submit's GPFIFO entries); (2)
+then the first VKFRAME seq/DONE + PPM; (3) fold the COMPR flip into a
+host-side answer (see D); (4) the mission series (Xorg/GZDOOM, KVMFR,
+CUDA 15/15 + soak, test series, video, Windows).