From 54ef117d77b2274a51b60524890078846f2823f6 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sat, 7 Nov 2026 13:19:09 -0500 Subject: vgsp-sema: ack the class-2d IMMD NOTIFY from the X DDX sync 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. --- kernel/gsp_sema_service.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index e42e23d..6f0103b 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -18233,6 +18233,13 @@ static void svc_push_raw_dump(const u8 *buf, u32 len, u64 push_va, static u64 svc_notify2d_done; static u32 svc_notify2d_log; +/* + * r1608 A/B: the X DDX's IMMD class-2d NOTIFY ack (the nvFermiSync + * completion). Enabled by default; set 0 to reproduce the pre-r1608 + * dropped-NOTIFY behaviour (the Xorg mode-set WAIT) without a rebuild. + */ +static bool gsp_sema_2d_notify_immd = true; +module_param_named(sema_2d_notify_immd, gsp_sema_2d_notify_immd, bool, 0644); static bool svc_notify2d_write(struct nv_vgpu_device *vgpu, struct svc_channel *ch, bool completion) @@ -18509,6 +18516,29 @@ static void svc_twod_method(struct nv_vgpu_device *vgpu, case 0x2ac: tw->operation = v; break; + /* + * r1608: the X DDX's nvFermiSync (nvFermiXAASync) queues the + * class-2d completion as IMMD_DATA methods: SET_NOTIFY_A/B name + * the NvNotification VA and NOTIFY (0x10c, payload 0 = + * WRITE_ONLY) must author the zeroed 16-byte notification. The + * watchdog path below has handled the run-shaped form since r828; + * the IMMD form previously fell into the default case and was + * dropped, so the X server's post-selection 2D sync spun in + * "NVIDIA(GPU-0): WAIT (0, 8, 0x8000, ...)" forever (the status + * word stayed IN_PROGRESS 0x8000). The mode-set never completed, + * glsStartServer/glsDeviceHandle never ran, and the GL client's + * physical-device init (class/gpuGartSize/+0x18e0) stayed empty. + */ + case SVC_2D_SET_NOTIFY_A: + ch->notify2d_va = (u64)(v & 0x1ffffff) << 32; + break; + case SVC_2D_SET_NOTIFY_B: + ch->notify2d_va |= (u64)v; + break; + case SVC_2D_NOTIFY: + if (v == 0 && gsp_sema_2d_notify_immd) + svc_notify2d_write(vgpu, ch, true); + break; case 0x2a0: tw->rop = v; break; @@ -18622,7 +18652,13 @@ static void svc_notify2d_keepalive(struct nv_vgpu_device *vgpu, u16 st; memcpy(&st, slots + slot * 16 + 14, 2); - if (st != 0xffff) + /* + * r1608: the 2D completion notifier is armed with + * NV9097_NOTIFICATION_STATUS_IN_PROGRESS (0x8000) while the + * GPU works on it (the X DDX's nvFermiSync waits for it to + * become 0); the older watchdog slots use 0xffff. Ack both. + */ + if (st != 0xffff && !(st & 0x8000)) continue; /* not armed - nothing to ack */ if (svc_write_ap(vgpu, ch->notifier_pa + slot * 16, ch->notifier_as, zero, sizeof(zero))) -- cgit v1.2.3