From 90ed3273a6b7b0241954fde6b2d34ab3270d9081 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 9 Oct 2026 15:45:21 -0400 Subject: vgsp-sema: CE layout USERD accepts on PUT alone; GET is GPU-owned (ISSUE-0002) r47 guest truth (channel_info walk in the hung second client): every CE channel's GP_PUT/GP_GET GPU VAs are ring+0x2008c / ring+0x20088 and the live rank0 USERD is the layout block at fb 0x90000 (the emulation's offsets were right all along). The coherence gate required g <= p, but the GET word is GPU-owned and holds leftovers (session 2 rank0: PUT=1, GET=136 from the previous session) - so the live block was rejected forever (r44 strict never accepted; r42/r46 latched the stale registered candidate). Accept the CE layout block when the PUT word is plausible; the pump tracks ch->last_get and rewrites GP_GET as it consumes entries. --- kernel/gsp_sema_service.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 43a8d62..1637d63 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -7789,10 +7789,30 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, va >= 0x120000000ULL && va < 0x121000000ULL && len >= 4 && len <= 0x10000; } - if (ring_ok) - rc = svc_userd_probe(vgpu, ring_pa + 0x10000, - ring_ap, ch->gpfifo_entries, - &p, &g); + /* + * ISSUE-0002 (r47): read only the PUT word for the CE layout + * block. The GET word is GPU-owned and its initial content is + * not coherent - session 2 rank0 read PUT=1 / GET=136 (a + * leftover from the previous session) and requiring g <= p + * rejected the LIVE layout block forever (r44 strict never + * accepted it; r42/r46 fell back to the stale registered + * candidate instead). The pump tracks its own position in + * ch->last_get and rewrites GP_GET as it consumes entries, so + * the initial GET value is irrelevant. + */ + if (ring_ok) { + if (!svc_read_ap(vgpu, + ring_pa + 0x10000 + SVC_USERD_GP_PUT, + ring_ap, &p, sizeof(p))) { + (void)svc_read_ap(vgpu, + ring_pa + 0x10000 + + SVC_USERD_GP_GET, + ring_ap, &g, sizeof(g)); + rc = p <= ch->gpfifo_entries ? 0 : -EINVAL; + } else { + rc = -ENOENT; + } + } /* * ISSUE-0002 (r46 diag): name the exact failing check on the * CE discovery decision. Three lines per rank, 36 per session. -- cgit v1.2.3