summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c54
1 files changed, 25 insertions, 29 deletions
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 */
}