summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-05 11:24:16 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-05 11:24:16 -0500
commita3d801e394a1c57833c816edc3d3cee22dc4a78a (patch)
treefe906759f83571dfd81ea4e9b88afe5111ce0879 /kernel/gsp_sema_service.c
parent7d88261d01100e46a5160319b94b1e79b5eb1117 (diff)
downloadopen-iov-a3d801e394a1c57833c816edc3d3cee22dc4a78a.tar.gz
open-iov-a3d801e394a1c57833c816edc3d3cee22dc4a78a.zip
vgsp-gr: hold calls on a stream-damaged push so a dropped chunk cannot run LOAD_CONSTANT_BUFFER without its selector state
A chunked GL draw whose earlier chunk was dropped (prelude LOAD-ONLY or the r1447 arming window hold) replayed the remaining chunks' calls alone; the constant-buffer selector (0x2380) lived in the dropped chunk, so the bug2548370 macro's LOAD_CONSTANT_BUFFER(0x2390) class-errored (ErrorCode 3) and the engine poisoned (badf1201 sentinel: pc=513/mac=0xf1 are its artifact, not a macro). Propagate the stream-relative chunk offset through the candidate and submit path, keep a per-push STREAM-DAMAGE record of the lowest dropped chunk, emit later chunks calls-held (the proven-safe shape), never arm the arming window-hold on a damaged stream, and start a fresh section at stream_rel==0. r1487: the exact r1485 damaging shape now retires clean (events=5, no poison) and the next chunk is captured; r1486 (holds off) still poisons because the first launch runs against a partially packed prelude, confirming the dropped chunk is the cause, not the hold release.
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 327a932..1a8efd6 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -7516,6 +7516,10 @@ struct svc_gr_cand_rec {
bool stream_3d;
u32 stream_off; /* dword offset of the window inside raw[] */
u32 stream_n; /* dwords of the replayable window */
+ u32 stream_rel; /* stream-relative dword offset of this
+ * window (0 = the section's first chunk); the
+ * backend uses it to detect a dropped earlier
+ * chunk of the same push */
/*
* SESSION 153-CONTINUED-87: every SET_PIPELINE_PROGRAM_ADDRESS pair
* the captured window itself binds (VA + pipeline slot), copied from
@@ -9569,6 +9573,13 @@ static void svc_gl_stream_chunks(struct svc_channel *ch, const u8 *buf,
c->stream_3d = true;
c->stream_off = cur / 4u;
c->stream_n = (end - cur) / 4u;
+ /*
+ * Stream-relative offset for the backend's dropped-chunk
+ * detection. cur walks from svc_gl.start_off, so the first
+ * chunk of the section is 0 and each later chunk is exactly
+ * the number of words already sliced off.
+ */
+ c->stream_rel = (cur - svc_gl.start_off) / 4u;
n++;
cur = end;
}
@@ -28153,6 +28164,8 @@ struct svc_fwd_req {
bool gr_stream_3d;
u32 gr_stream_off;
u32 gr_stream_n;
+ u32 gr_stream_rel; /* stream-relative dword offset of this
+ * window (0 = the section's first chunk) */
u32 gr_raw[SVC_GR_PUSH_WORDS];
u64 gr_qmd_dev_va;
/*
@@ -28322,6 +28335,7 @@ static bool svc_gr_missre_arm(const struct svc_fwd_rel *rel, u8 nrel)
c->stream_3d = svc_fwd_req.gr_stream_3d;
c->stream_off = svc_fwd_req.gr_stream_off;
c->stream_n = svc_fwd_req.gr_stream_n;
+ c->stream_rel = svc_fwd_req.gr_stream_rel;
memcpy(c->raw, svc_fwd_req.gr_raw, sizeof(c->raw));
c->qmd_dev_va = svc_fwd_req.gr_qmd_dev_va;
memcpy(c->qmd, svc_fwd_req.gr_qmd, sizeof(c->qmd));
@@ -30975,6 +30989,7 @@ static void svc_fwd_gr_work(void)
if (svc_fwd_req.gr_stream_3d) {
gs.stream = svc_fwd_req.gr_raw + svc_fwd_req.gr_stream_off;
gs.stream_n = svc_fwd_req.gr_stream_n;
+ gs.stream_rel = svc_fwd_req.gr_stream_rel;
}
gs.prog_va = svc_fwd_req.gr_prog_va; /* CONT-87: family binds */
gs.n_prog_binds = svc_fwd_req.gr_n_prog_binds;
@@ -33569,6 +33584,7 @@ static int svc_gr_req_fill(struct nv_vgpu_device *vgpu,
svc_fwd_req.gr_stream_3d = svc_gr_cand.stream_3d;
svc_fwd_req.gr_stream_off = svc_gr_cand.stream_off;
svc_fwd_req.gr_stream_n = svc_gr_cand.stream_n;
+ svc_fwd_req.gr_stream_rel = svc_gr_cand.stream_rel;
svc_fwd_req.gr_n_prog_binds = svc_gr_cand.n_prog_binds;
{
u32 pb;