From 725898e44666b4def396f7f3c5e50712fd37aa33 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 12 Nov 2026 20:01:04 -0500 Subject: vgsp: stop fabricating 0xFFFF into the nvPush error notifier; add r1780 GL ops tooling The uncommitted keep-alive change wrote 0xFFFF into slot 0's status field (u16 at notifier+0x0e) on the X DDX / GLX kick-idle channel families. Ground truth (570.144 reference sources + stock nvidia_drv.so disassembly): slot 0 of an nvPush notifier block is the ERROR notifier; nvPushCheckChannelError reads that status and 0xFFFF aborts every nvPushWaitForNotifier/idle wait as a channel error. There is no pb_kickIfIdle in 570.144 - the DDX DMA-idle test reads the progress-tracker semaphore word, not this slot. Leave slot 0 untouched; keep the 0x8000->0 completion ack for the remaining slots and the r864 0xFFFF/0x8000 completion on the RC-watchdog/beef families. Correct the CONT.408/409 comments accordingly. New host/guest tooling: gpa.py (QMP gva2gpa), tick_gen.py (guest-RM timer BO tick), guest_mode.sh (shared nvClip modeNum reader), gl_verify.sh (X/GLX bring-up with ScreenInit-lottery retries), push_gl_tools.sh, the gzdoom_pbuf_run.sh guest recipe and the test_tri SDL2 harness validation program; ignore tools/guest-diag/build/. --- kernel/gsp_sema_service.c | 54 ++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 96e135b..40b8063 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -20886,15 +20886,29 @@ static bool svc_ddx_notif_idle(const struct svc_channel *ch) * captured a class-2D NOTIFY VA therefore owns a kick-idle page for slots * 0..3; the RC-watchdog/beef kernel channels (which never arm notify2d) * keep the r864 behaviour. + * + * CONT.457: the "slot 0 status must be 0xFFFF" reading of the r1706/r1716 + * probes is RETRACTED - ground truth says slot 0 is the ERROR notifier + * and 0xFFFF there aborts the client as a channel error (see the + * correction note below svc_kick_idle_page). Do not re-add the write. */ static bool svc_kick_idle_page(const struct svc_channel *ch) { return svc_ddx_notif_idle(ch) || ch->notify2d_va != 0; } -static u32 svc_ddx_idle_log; -static u64 svc_ddx_idle_n; - +/* + * CONT.457 correction (570.144 ground truth; nvidia_drv.so disassembly): + * slot 0 of an nvPush channel's notifier block is the ERROR notifier + * (raw index 0). nvPushCheckChannelError reads its status u16 at +0x0e + * (DDX nvidia_drv.so+0xb66c0) and 0xFFFF means "channel error" - every + * nvPushWaitForNotifier/idle wait then aborts as errored. There is no + * "pb_kickIfIdle" in 570.144; the DDX DMA-idle test reads the + * progress-tracker semaphore word, not this slot. Never fabricate + * 0xFFFF into slot 0's status (the CONT.408/409 restore did), and never + * ack it from here either - a real 0x8000 arm on slot 0 is handled by + * the class-2D completion sweep (svc_client_slot_sweep). + */ static void svc_notify2d_keepalive(struct nv_vgpu_device *vgpu, struct svc_channel *ch) { @@ -20911,36 +20925,18 @@ static void svc_notify2d_keepalive(struct nv_vgpu_device *vgpu, u16 st; memcpy(&st, slots + slot * 16 + 14, 2); + /* Slot 0 is the nvPush ERROR notifier: leave it untouched. */ + if (slot == 0 && svc_kick_idle_page(ch)) + continue; /* - * CONT.408: on the X DDX family 0xFFFF is the kick-idle - * marker pb_kickIfIdle requires, never an arm. Restore it - * on slot 0 (the kick gate) instead of zeroing it, and only - * ack a real 0x8000 arm on the other slots. + * CONT.408/409: on kick-idle pages slots 1..3 carry class-2D + * user notifiers; ack only a real 0x8000 arm. Non-kick pages + * (RC watchdog / beef) keep the r864 behaviour: 0xFFFF or + * 0x8000 -> zeroed completion. */ if (svc_kick_idle_page(ch)) { - if (slot == 0) { - u16 idle = 0xffff; - - if (st == 0xffff) - continue; - if (svc_write_ap(vgpu, - ch->notifier_pa, - ch->notifier_as, &idle, - sizeof(idle))) - continue; - svc_ddx_idle_n++; - if (svc_ddx_idle_log < 32) { - svc_ddx_idle_log++; - pr_info("sema-chan: kick idle h=0x%x pa=0x%llx restored 0x%04x -> 0xffff (n=%llu)\n", - ch->h_object, ch->notifier_pa, - st, - (unsigned long long) - svc_ddx_idle_n); - } - continue; - } if (!(st & 0x8000)) - continue; /* 0xffff is idle here */ + continue; } else if (st != 0xffff && !(st & 0x8000)) { continue; /* not armed - nothing to ack */ } -- cgit v1.2.3