summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 14:28:49 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 14:28:49 -0500
commita4215afa400543f5468e269d7d09f74d05ceac19 (patch)
treec65992eb9e2f7b93c416721acedc12dfd6d067a2 /kernel
parentfd3157df0001e73bab69b58d35c24bc3a2b6925d (diff)
downloadopen-iov-a4215afa400543f5468e269d7d09f74d05ceac19.tar.gz
open-iov-a4215afa400543f5468e269d7d09f74d05ceac19.zip
vgsp: reject beef draw-synth windows whose last colour-target bind is unusable (eng25 correctness guard)
The direct-GL lane's draw-synth captures join the verbatim 3D replay lane by numerical run-cover alone, so a non-method data blob whose INC run merely spans the C597 RT block is replayed as state: its last A/B/W/H write per colour target is an unmapped 40-bit VA (c344: RT1 -> 0xff000480a0) and the engine retires with no stores (NOWRITE wrote=0). Gate the beef 'd' admission (single-block and chunk-split) on svc_gl_window_rt_valid(): walk the window with the run grammar, keep the last A/B/W/H write per colour target, and require at least one usable bind (A[7:0]<=1, B<2^30 aligned, 1<=W,H<=0x4000). Validated live (c346, mdev 53dc06b5, ENG26 instrument cycle): 23 bounded '3D mark rejected (beef draw-synth: no valid last colour-target bind)' rows, including the 14865-word 59580-B blob window @off=0x78 and the 542-word 0x4010ed0 twin; the one timing-variant window that does carry a usable RT bind still passed and replayed (wrote=0), and the X lane is unregressed (15x '3D stream marked h=0x1000013' + 'GUEST GR LAUNCH OK' ok=16/17). Refs: CONT.486/487; eng25/eng26 evidence under /tmp/opencode/eng26-*.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c83
1 files changed, 81 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index e0f1897..4c05935 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -11766,6 +11766,69 @@ static void svc_gl_watch_note(const struct svc_channel *ch, const char *why,
svc_gl.blob_len, svc_gl.subch);
}
+/*
+ * eng25 (CONT.486): last-write colour-target validity for a beef-family
+ * draw-synth window. The direct-GL draw captures admitted by the r929/eng24
+ * lane can be non-method data whose large INC run happens to cover the
+ * C597 RT block (c344: window push=0x4010ed0, 7-word SURF prelude then
+ * 31000201 = INC cnt=0x100 mthd=0x804). That run's last RT writes are
+ * RT0 A=0x00 B=0x041e0f0c W=0x040f4800 H=0x02027b60
+ * RT1 A=0xff B=0x000480a1 W=0x000ea200 H=0x000b7326 -> VA 0xff000480a0
+ * i.e. it OVERWRITES the prelude's valid 0x0c000000 bind with an unmapped
+ * 40-bit VA; the engine then retires the stream with no stores
+ * (NOWRITE wrote=0). Require at least one target whose LAST A/B/W/H is a
+ * usable bind before the window is admitted/replayed. The X-lane window
+ * (RT1 A=0 B=0x15d0000 W=0x780 H=0x438) passes; the c344 beef window fails.
+ */
+static bool svc_gl_window_rt_valid(const u8 *buf, u32 len, u32 start_off,
+ u32 at_off)
+{
+ u32 A[4] = { 0 }, B[4] = { 0 }, W[4] = { 0 }, H[4] = { 0 };
+ bool seen[4] = { false };
+ u32 o = start_off, j;
+
+ if (!buf || start_off >= at_off || at_off > len)
+ return false;
+ while (o + 4u <= at_off) {
+ u32 h, op, cnt, m, span = 1u, k;
+
+ memcpy(&h, buf + o, 4);
+ op = (h >> 29) & 7u;
+ cnt = (h >> 16) & 0xfffu;
+ m = (h & 0x1fffu) << 2;
+ if ((op == 1u || op == 3u || op == 5u) && cnt &&
+ o + 4u + cnt * 4u <= at_off)
+ span = 1u + cnt;
+ for (k = 0; k < span; k++) {
+ u32 mm = m + 4u * k, v = 0;
+
+ if (k && op != 1u && op != 3u)
+ break;
+ if (k)
+ memcpy(&v, buf + o + 4u + k * 4u, 4);
+ else if (op == 4u)
+ v = (h >> 16) & 0x1fffu;
+ else
+ continue;
+ for (j = 0; j < 4u; j++) {
+ u32 base = 0x800u + j * 0x40u;
+
+ if (mm == base) { A[j] = v; seen[j] = true; }
+ else if (mm == base + 4u) { B[j] = v; seen[j] = true; }
+ else if (mm == base + 8u) { W[j] = v; seen[j] = true; }
+ else if (mm == base + 0xcu) { H[j] = v; seen[j] = true; }
+ }
+ }
+ o += span * 4u;
+ }
+ for (j = 0; j < 4u; j++)
+ if (seen[j] && (A[j] & ~0xffu) == 0 && (A[j] & 0xffu) <= 1u &&
+ B[j] < 0x40000000u && (B[j] & 3u) == 0 &&
+ W[j] > 0 && W[j] <= 0x4000u && H[j] > 0 && H[j] <= 0x4000u)
+ return true;
+ return false;
+}
+
static void svc_gl_flush(struct nv_vgpu_device *vgpu,
struct svc_channel *ch,
const struct svc_push_state *st, const u8 *buf,
@@ -12846,7 +12909,8 @@ static void svc_gl_flush(struct nv_vgpu_device *vgpu,
*/
if ((op_src[0] == 's' || op_src[0] == 'h' ||
(op_src[0] == 'd' &&
- (ch->h_object & 0xfffff000u) == 0xbeef0000u)) &&
+ (ch->h_object & 0xfffff000u) == 0xbeef0000u &&
+ svc_gl_window_rt_valid(buf, len, svc_gl.start_off, at_off))) &&
svc_gr_cand.valid &&
len == svc_gr_cand.push_n * 4 &&
svc_gl.start_off + 8u <= at_off &&
@@ -12872,7 +12936,22 @@ static void svc_gl_flush(struct nv_vgpu_device *vgpu,
* diagnostic below names the failing condition (the next
* bound to size).
*/
- if (len == svc_gr_cand.push_n * 4 &&
+ if (op_src[0] == 'd' &&
+ !svc_gl_window_rt_valid(buf, len, svc_gl.start_off,
+ at_off)) {
+ /* eng25: bounded witness when a beef draw-synth
+ * window is refused - its last colour-target bind
+ * is not a usable C597 RT (see the clause above). */
+ if (svc_gl_mark_log < 64) {
+ svc_gl_mark_log++;
+ pr_info("sema-gl: 3D mark rejected (beef draw-synth: no valid last colour-target bind) h=0x%x push=0x%llx win=%u words @off=0x%x\n",
+ ch->h_object, push_va,
+ at_off > svc_gl.start_off ?
+ (at_off - svc_gl.start_off) / 4u :
+ 0u,
+ svc_gl.start_off);
+ }
+ } else if (len == svc_gr_cand.push_n * 4 &&
svc_gl.start_off + 8u <= at_off) {
svc_gl_stream_chunks(ch, buf, len, at_off);
} else if (gsp_sema_dbg && svc_gl_mark_log < 64) {