summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 07:17:42 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 07:17:42 -0400
commit8d8567c91f282078251d7bd2fc301e7fd438ec36 (patch)
tree20bd50b9526e74756f3ca4d037ad27dcd88638bb
parent6a88588bfddc9532becea5d14492ddb51d4eb6d4 (diff)
downloadopen-iov-8d8567c91f282078251d7bd2fc301e7fd438ec36.tar.gz
open-iov-8d8567c91f282078251d7bd2fc301e7fd438ec36.zip
wall-2 session-76 addendum (r681): decode the main-thread vkCreateDevice wait - should-wait = (readiness word != 1), readiness = u32 at nvidiactl-mapped holder+0x80 (VM_IO page, 39/39 reads zero, all fd polls time out), give-up predicate dcee20 fires -4 only on RM error flags (b29d60 / +0x70cc); the word's writer is the guest kernel driver/RM, not host RAM
-rw-r--r--tools/guest-diag/wall2/README-session76.md42
1 files changed, 42 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/README-session76.md b/tools/guest-diag/wall2/README-session76.md
index d78ed39..828b3b9 100644
--- a/tools/guest-diag/wall2/README-session76.md
+++ b/tools/guest-diag/wall2/README-session76.md
@@ -90,3 +90,45 @@ observable state change, while the main thread blocks elsewhere
be read by the sema service. Next lever is the main thread's wait
(what would make the /dev/nvidia0 poll return readable) or the GR
channel-init completion — not the a097 reply words.
+
+## ADDENDUM (r681) — THE MAIN-THREAD vkCreateDevice WAIT DECODED
+
+Live gdb on the main thread (r681, fresh boot) resolved the loop at
+eglcore 0xdceb80 (frame chain: poll <- a12de4 <- d69159 <- d6a02b <-
+dcebc6 <- d3838a <- ... <- libvulkan vkCreateDevice):
+
+* rbx (waitable, vt 0x...3f58f8): vt+0x18 = d69ee0 = "should wait"
+ (returns `(*0x48(*(rbx+0x70)) != 1)`); vt+0x28 = d69f50 = "wait"
+ (builds a pollfd array from the object's fd holder and poll()s up to
+ 16 fds with the 10 s timeout).
+* rbp (loop object, vt 0x...3f71f8): vt+0x38 = dcee20 = the give-up
+ predicate. dcee20 returns nonzero (-> return -4 = the client's
+ VKFAIL -4 origin) when either object at rbp+0x110 / rbp+0x120 shows
+ an error (b29d60(...) != 0 or *(obj+0x70cc) != 0); otherwise 0 and
+ the loop repeats. It also throttles itself at 1e6 (units) via
+ rbp+0x1b8.
+* The readiness value: sub = *(rbx+0x70) (0x...f7f0c90); sub+0x58 ->
+ obj2; obj2's vt+0x10 = 0xce71f0 = `read u32 at (*(obj2+0x58)) +
+ *(u32*)(obj2+0x60)` — i.e. a u32 word at holder_base + 0x80 (the
+ live object had obj2+0x60 = 0x80, obj2+0x64 = 0x1e). Observed: 0x0
+ every poll (39/39) -> should-wait = 1 forever.
+* The word lives in a **/dev/nvidiactl rw-s mapping**
+ (0x7623d0480000-0x7623d0484000) — a VM_IO driver page, not plain
+ guest RAM: /proc/PID/mem reads of it return zeros, and writing the
+ guest-RAM file at the pagemap-derived PAs (0x1036dd080 and both
+ hole-shifted candidates) did NOT change the client's behaviour.
+ The writer is therefore the guest kernel driver/RM when the awaited
+ operation completes (the same class as the SESSION-74 completion
+ slots) — not a host RAM poke.
+* All 20 sampled polls of the wait helper returned 0 (timeout): the
+ fd (/dev/nvidia0) never becomes readable (nv_poll reports
+ POLLPRI|POLLIN only when an nv_event is pending on the file).
+
+So vkCreateDevice waits for (a) the readiness word == 1, and the wait
+ends only when the driver/RM signals that word (or an nv_event arrives
+on /dev/nvidia0). The give-up path (-4) fires only if the RM error
+flags appear. Next: identify the operation whose completion writes the
+word (the object chain sub -> obj2 -> holder is a "signal/semaphore"
+object; dump the holder object and its creating control), then make
+the emulation drive the guest kernel to complete it (the engine/
+channel-init completion the sema service already tries to deliver).