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