summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_rm_emulation.c19
-rw-r--r--kernel/gsp_sema_service.c94
-rw-r--r--kernel/gsp_sema_service.h12
3 files changed, 122 insertions, 3 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 957729b..b928faf 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -4273,6 +4273,25 @@ static void gsp_rm_handle_rm_alloc(struct gsp_emu_context *ctx,
memcpy(&rp[3], reply + GSPRM_ALLOC_HDR_SIZE + 12, 4);
gsp_rm_grobj_note(ho, class_id);
+ /*
+ * eng23 (CONT.483): the RM record is the direct-GL lane's
+ * class bind. The X lane carries its C597 SET_OBJECT inline
+ * in the init push (hw class bind, sticky); the direct-GL
+ * client's channel (0xbeef01xx family) binds the class
+ * channel-side - it allocates TURING_A (0xc597) with
+ * hParent = its own channel (measured: alloc 0xc597
+ * h=0xbeef9097 parent=0xbeef0100 client=0xc1d0001a, twice,
+ * while 0xbeef0100 was a registered channel with engine 0)
+ * and never re-emits a bind push. Without the note the
+ * section recognizer's sticky-attachment gate drops every
+ * one of that channel's pushes and no C597 section is ever
+ * opened (CONT.481/482: 0 sections for 0xbeef0100 on a boot
+ * where the whole setup push was readable). Report hParent
+ * to the sema service, which applies it as the sticky 3D
+ * bind on its own thread.
+ */
+ if (hp && hp != hc)
+ gsp_sema_service_gl_attach(hp, 0);
if (rm->gr3d_alloc_log < GSPRM_GR3D_LOG_MAX) {
rm->gr3d_alloc_log++;
nv_vgpu_info(ctx->vgpu,
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index efb4fc1..de92b8e 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -9946,6 +9946,51 @@ static bool svc_gl_att_accept_run(u64 h, u32 subch)
}
/*
+ * eng23 (CONT.483): the RM-record attach request.
+ *
+ * The attachment tables above are owned by the service thread (only the
+ * decode path writes them). The GSP-RM emulation thread learns the
+ * direct-GL client's class bind from the 0xc597 allocation's hParent and
+ * must not write those tables directly (a memmove under a concurrent
+ * svc_gl_att_has reader could expose a torn table). Queue one request
+ * (handle + subchannel + generation) and apply it on the service thread
+ * at the top of each pass - the attach is sticky, so a one-pass delay is
+ * harmless, and a later 0xc597 re-alloc simply refreshes the same entry.
+ */
+static u64 svc_gl_att_req_h;
+static u32 svc_gl_att_req_sub;
+static u32 svc_gl_att_req_gen;
+static u32 svc_gl_att_req_done;
+
+void gsp_sema_service_gl_attach(u32 h_object, u32 subch)
+{
+ if (!h_object || subch > SVC_SUBCH_CE)
+ return;
+ WRITE_ONCE(svc_gl_att_req_h, h_object);
+ WRITE_ONCE(svc_gl_att_req_sub, subch);
+ WRITE_ONCE(svc_gl_att_req_gen, READ_ONCE(svc_gl_att_req_gen) + 1);
+}
+
+static void svc_gl_att_drain(void)
+{
+ u64 h;
+ u32 subch, gen;
+
+ gen = READ_ONCE(svc_gl_att_req_gen);
+ if (gen == svc_gl_att_req_done)
+ return;
+ h = READ_ONCE(svc_gl_att_req_h);
+ subch = READ_ONCE(svc_gl_att_req_sub);
+ svc_gl_att_req_done = gen;
+ if (!h)
+ return;
+ svc_gl_att_note(h, subch);
+ if (gsp_sema_dbg)
+ pr_info("sema-gl: RM-record attach h=0x%llx subch=%u (0xc597 alloc parent; sticky)\n",
+ h, subch);
+}
+
+/*
* SESSION 153 (G-B gate: the client's own C597 draws must open sections).
* The replay guard at svc_gl_flush consults svc_gr_cand_push_seen(), which
* returns true when the push VA sits in the GR candidate ring - even when
@@ -15901,7 +15946,18 @@ static bool svc_fb_push_rescue(struct nv_vgpu_device *vgpu, u32 h_object,
{
static struct svc_fb_push_hit hits[8];
u8 *base = vgpu->bars[1].vaddr;
- u64 lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x4000000ULL), off;
+ /*
+ * eng22: the old 64 MiB scan cap assumed every push window parks in
+ * the low FB. The two recovered windows sat at fb 0x16290c/0x1f6110,
+ * but the 59556-byte setup push found no window below the cap. Since
+ * the GL client's pushbuffer is a vidmem allocation written through
+ * the BAR1 aperture, its mirror offset in the 2 GiB mdev shadow is
+ * allocation-dependent and may land above 64 MiB; whether the cap is
+ * what hid the big push is exactly what widening it tests. A
+ * zero/fill shadow stays cheap: all-zero windows never pass
+ * svc_method_stream_plausible, and a hit is cached per length.
+ */
+ u64 lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x80000000ULL), off;
/*
* The client writes the pushbuffer at its VA's page offset inside the
* BAR1 window, so a push whose VA is 0x...004 starts 4 bytes into a
@@ -21653,7 +21709,16 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
cnt2 = (h2 >> 16) & 0xfff;
sc2 = (h2 >> 13) & 0x7;
ad2 = (h2 & 0x1fff) << 2;
- if (op2 == 4 && ad2 == 0x1618 && sc2 == 0) {
+ /*
+ * eng23 (CONT.483): the direct-GL client's BEGIN
+ * (0x1618) rides inside a multi-method INC run
+ * (op 1), not as the one-word IMMD (op 4) this
+ * scan was written for; accept both shapes so the
+ * late-attach path fires on its pushes too.
+ */
+ if ((op2 == 4 && ad2 == 0x1618 && sc2 == 0) ||
+ (op2 == 1 && cnt2 && sc2 == 0 && ad2 <= 0x1618u &&
+ (0x1618u - ad2) < cnt2 * 4u)) {
svc_gl_att_note(ch->h_object, 0);
if (gsp_sema_dbg && svc_gl_draw_log < 64) {
svc_gl_draw_log++;
@@ -21986,10 +22051,30 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* The window then runs from gl_win_start to the pass end
* (the section close at the END method / push tail), which
* svc_gl_flush slices into the verbatim 3D replay.
+ *
+ * eng23 (CONT.483): the direct-GL client emits NVC597_BEGIN
+ * (0x1618) as a METHOD INSIDE a multi-method INC run - the
+ * value census decoded `method=0x1618 op=1 value=01047220`
+ * from a payload word of a run that started below 0x1618 -
+ * not in the one-word IMMD form (op 4) the X lane's driver
+ * emits. The same holds for the render-target setup family
+ * (0x840): the direct-GL draw push carries it inside a run
+ * whose start covers it (measured c335: run addr=0x80c
+ * count=256 covers 0x80c..0xc0c, i.e. 0x840 and the whole
+ * viewport/clip block in one run). Accept both inside-run
+ * forms on attached channels too (the run carrying the
+ * method opens the section; the run body itself is scanned
+ * into the window like the IMMD/RT-setup openers' preceding
+ * state).
*/
if (gsp_sema_gl_xlate && !ch->engine_type &&
((op == 4 && addr == 0x1618) ||
- (op == 1 && addr == 0x840 && count >= 4)) &&
+ (op == 1 && addr == 0x840 && count >= 4) ||
+ (op == 1 && count &&
+ ((addr <= 0x840u &&
+ (0x840u - addr) < count * 4u) ||
+ (addr <= 0x1618u &&
+ (0x1618u - addr) < count * 4u)))) &&
!svc_gl.seen &&
svc_gl_att_accept_run(ch->h_object, subch)) {
u64 keep_rel = svc_gl.rel_va;
@@ -50642,6 +50727,9 @@ static int svc_thread(void *arg)
/* Host-injection queue drain: once per pass, not per guest. */
svc_handle_map_add();
+ /* eng23 (CONT.483): apply RM-record 3D attaches on this
+ * thread (the only writer of the attachment tables). */
+ svc_gl_att_drain();
for (g = 0; g < n_vgpus; g++) {
struct svc_guest_sess *sess;
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index 36f9902..6f07209 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -107,6 +107,18 @@ struct sema_vaspace_desc {
void gsp_sema_service_vaspace_add(const struct sema_vaspace_desc *desc);
void gsp_sema_service_vaspace_del(u32 h_vaspace);
/*
+ * eng23 (CONT.483): RM-record 3D-class attachment. The X lane carries its
+ * C597 SET_OBJECT inline in the init push, but the direct-GL client's
+ * channel binds the class channel-side: the client allocates TURING_A
+ * (0xc597) with hParent = its own channel and never re-emits a bind push
+ * (observed: alloc 0xc597 h=0xbeef9097 parent=0xbeef0100). The GSP-RM
+ * emulation reports that allocation here, and the service thread applies
+ * it as the sticky attachment the section recognizer gates on (same
+ * effect as the X lane's inline bind). Called from the RM thread, applied
+ * on the service thread - no shared-table writes cross threads.
+ */
+void gsp_sema_service_gl_attach(u32 h_object, u32 subch);
+/*
* CONT.407: a client's DUP_OBJECT of a VAS gives the destination client a
* NEW handle for the SAME page directory (measured: the GL client dups X's
* VAS 0x10005 as 0xbfef0001, then allocates its GR channel with