summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-31 04:35:05 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-31 04:35:05 -0400
commite3ecd6a3ff20196d6e768590ad5239caee138b60 (patch)
treedce56a13667eadceb8abe1714981b711a5306885 /kernel/gsp_phys_booter.c
parentc0ac656b3e28cf2daae224ea7feaaa8ad2e25664 (diff)
downloadopen-iov-e3ecd6a3ff20196d6e768590ad5239caee138b60.tar.gz
open-iov-e3ecd6a3ff20196d6e768590ad5239caee138b60.zip
vgsp: PBENTRY first-sighting watch (all 12 PBDMA intr0 bit18, PB_HEADER/COUNT/DATA0/HDR_SHADOW dump pre-rearm, 8/boot) + PB-FAULT-DUMP voff/tail/past-end; sema_gl_sdm_drop (op-0/2/6 single-word SDM entries from preludes+window); reloc level-2 fallback; sema_gl_miss_abort (pre-doorbell abort on residual MISS, feeds pin demand); gsp_sema_demand_note + attr-prelude ptr pages demand-recorded + sema_attr_settle_ms=8000 - **FIRST BEEF WINDOW RETIRES ON REAL HW** (poll break ch=0xc0ffee02 after 68us, 737-word block) but no-store retire (0/4 pages changed, NO-STORES); residual MISS flood (miss=11..17) blocked by FULL demand set (64/64 MAX) - SESSION 153 r1103-r1106
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c286
1 files changed, 275 insertions, 11 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index eba0305..7f41df6 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -5047,6 +5047,7 @@ static void gsp_phys_pbdma_fault_dump(u32 chid)
u32 trig;
const char *trig_src;
s64 off_words = -1;
+ s64 voff = -1;
if (!intr0 && !pbf && !hdrsh && !pbhd)
continue;
@@ -5073,8 +5074,20 @@ static void gsp_phys_pbdma_fault_dump(u32 chid)
fetch64 < gsp_phys_gr_last_pb_dma +
(u64)gsp_phys_gr_last_words * 4u)
off_words = (s64)(fetch64 - gsp_phys_gr_last_pb_dma) / 4;
- pr_info("vgsp-gr: PB-FAULT-DUMP P%u intr0=%08x gpf=%u pbfetch=0x%llx len=%u off=%lld hdr=%08x(%s m=0x%x cnt=%u sub=%u) cnt=%08x data0=%08x shadow=%08x pbhd=%08x(type=%s) TRIG=%08x(%s)\n",
- i, intr0, gpf, fetch64, pbfhi >> 11, off_words,
+ /*
+ * SESSION 153-CONTINUED-59: the SAME offset computed against
+ * the GPU VA the engine fetches (the r1102 WINPROBE/PB-FAULT
+ * agreement: pbfetch 0x101ebc with pb_va 0x101000 and 943
+ * words = exactly the block end). voff >= words is the
+ * past-the-block-end prefetch position.
+ */
+ voff = (s64)-1;
+ if (pb_va && fetch64 >= pb_va &&
+ fetch64 < pb_va + (u64)GSP_PHYS_PAGE_SIZE)
+ voff = (s64)(fetch64 - pb_va) / 4;
+ pr_info("vgsp-gr: PB-FAULT-DUMP P%u intr0=%08x gpf=%u pbfetch=0x%llx len=%u off=%lld voff=%lld/%u hdr=%08x(%s m=0x%x cnt=%u sub=%u) cnt=%08x data0=%08x shadow=%08x pbhd=%08x(type=%s) TRIG=%08x(%s)\n",
+ i, intr0, gpf, fetch64, pbfhi >> 11, off_words, voff,
+ gsp_phys_gr_last_words,
hdrsh, gsp_phys_pbdma_type_name(hdrsh >> 29),
(hdrsh & 0x1fffu) << 2,
(hdrsh >> 16) & 0xfffu, (hdrsh >> 13) & 7u,
@@ -5105,6 +5118,34 @@ static void gsp_phys_pbdma_fault_dump(u32 chid)
w + 12 < n ? pw[w + 12] : 0, w + 13 < n ? pw[w + 13] : 0,
w + 14 < n ? pw[w + 14] : 0, w + 15 < n ? pw[w + 15] : 0);
}
+ /*
+ * SESSION 153-CONTINUED-59: the block TAIL and the
+ * words PAST the block end (the r1102 fault fetch
+ * sits exactly at the end - voff == words). The past
+ * words are what a prefetching PBDMA decodes next;
+ * the tail shows whether the block itself ends at an
+ * entry boundary.
+ */
+ {
+ u32 words = gsp_phys_gr_last_words;
+ u32 lo = words > 48u ? words - 48u : 0u;
+ u32 hi = words + 32u;
+
+ if (hi > 1024u)
+ hi = 1024u;
+ for (w = lo; w < hi; w += 16) {
+ pr_info("vgsp-gr: PB-FAULT-DUMP %s[%3u]= %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ w < words ? "tail" : "past", w,
+ pw[w], w + 1 < 1024u ? pw[w + 1] : 0,
+ w + 2 < 1024u ? pw[w + 2] : 0, w + 3 < 1024u ? pw[w + 3] : 0,
+ w + 4 < 1024u ? pw[w + 4] : 0, w + 5 < 1024u ? pw[w + 5] : 0,
+ w + 6 < 1024u ? pw[w + 6] : 0, w + 7 < 1024u ? pw[w + 7] : 0,
+ w + 8 < 1024u ? pw[w + 8] : 0, w + 9 < 1024u ? pw[w + 9] : 0,
+ w + 10 < 1024u ? pw[w + 10] : 0, w + 11 < 1024u ? pw[w + 11] : 0,
+ w + 12 < 1024u ? pw[w + 12] : 0, w + 13 < 1024u ? pw[w + 13] : 0,
+ w + 14 < 1024u ? pw[w + 14] : 0, w + 15 < 1024u ? pw[w + 15] : 0);
+ }
+ }
}
}
}
@@ -17110,6 +17151,31 @@ MODULE_PARM_DESC(gsp_phys_rmcall_gr_3d,
"Replay a captured raw C597 method window verbatim instead of the compute prelude (default 1)");
/*
+ * SESSION 153-CONTINUED-59: drop single-word SDM-type entries (SEC_OP 0
+ * SSDM / 2 STORE_SDM / 6 USE_SDM, tu102 dev_esched_pbdma.h type map) from
+ * every replayed stream: the 3D window patch, the MME prelude and the attr
+ * prelude emission. The r1102 PBENTRY first-sighting forensics localized
+ * the fault decode point to the MME prelude head (WINPROBE/PB-FAULT-DUMP
+ * P0 HDR_SHADOW=04666d14 = prelude[2], PB_DATA0=04646d00 = prelude[3],
+ * pbfetch=0x101ebc = block end after the whole 943-word block was
+ * prefetched, intr0 bit 18 in the guest relay): the client's setup push
+ * carries a 21-word run of `04666d00 04666d10 04666d14 04646d00 ...`
+ * (SDM-family single-word encodings, method fields 0x3400/0x3440/0x3450)
+ * that svc_mme_prelude_capture stored verbatim; the physical PBDMA refuses
+ * them ("invalid method encoding used in method", NV_PPBDMA_INTR_0
+ * PBENTRY), which also explains why the whole block was fetched but the
+ * REPORT_SEMAPHORE never retired. The guest-vGPU parts (subdevice masks)
+ * are meaningless on the single-subdevice ladder channel - the same call
+ * the sub!=0 multi-word drop makes. Zero words are kept (benign padding).
+ * Default 1; A/B with 0.
+ */
+static bool gsp_phys_rmcall_gr_sdm_drop = true;
+module_param_named(sema_gl_sdm_drop, gsp_phys_rmcall_gr_sdm_drop, bool,
+ 0644);
+MODULE_PARM_DESC(sema_gl_sdm_drop,
+ "Drop single-word SDM-type entries (SEC_OP 0/2/6) from 3D window replays, the MME prelude and the attr prelude (default 1)");
+
+/*
* SESSION 153-CONTINUED-53: MME context-setup prelude. The r1073-r1077
* in-flight capture proved the draw-window replay raises a real MME
* ILLEGAL_OPCODE on CALL_MME_MACRO(2)=0x3810 (mme_pc=0, mme_ir=1, mme_mac
@@ -17236,18 +17302,50 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
(GSP_PHYS_RMCALL_GR_SET_OBJECT >> 2);
*p++ = GSP_PHYS_RMCALL_CLASS_GR_3D;
if (emit_prelude) {
- u32 g0 = pl_gen, g1 = 0;
+ u32 g0 = pl_gen, g1 = 0, sdrop = 0, pwords = pl_n;
- memcpy(p, pl, (size_t)pl_n * 4);
- p += pl_n;
+ if (READ_ONCE(gsp_phys_rmcall_gr_sdm_drop)) {
+ u32 r = 0, w = 0;
+
+ /*
+ * SESSION 153-CONTINUED-59: SDM sanitize (see the
+ * gsp_phys_rmcall_gr_sdm_drop comment). Walk the
+ * prelude verbatim but drop single-word SDM-family
+ * encodings; they are the r1102 PBENTRY offenders.
+ */
+ while (r < pl_n) {
+ u32 h = pl[r];
+ u32 op = (h >> 29) & 7u;
+ u32 cnt = (h >> 16) & 0xfffu;
+ u32 span = ((op == 1u || op == 3u ||
+ op == 5u) && cnt &&
+ r + 1u + cnt <= pl_n) ?
+ 1u + cnt : 1u;
+
+ if (h && (op == 0u || op == 2u ||
+ op == 6u)) {
+ sdrop++;
+ r += span;
+ continue;
+ }
+ memcpy(&p[w], &pl[r], (size_t)span * 4u);
+ w += span;
+ r += span;
+ }
+ p += w;
+ pwords = w;
+ } else {
+ memcpy(p, pl, (size_t)pl_n * 4);
+ p += pl_n;
+ }
/* seqcheck: a mid-copy append must not be recorded as
* emitted (the copy may be a torn prefix). */
gsp_sema_mme_prelude_get(NULL, &g1);
if (g1 == g0) {
WRITE_ONCE(mme_prelude_emitted_gen, g0);
- pr_info("vgsp-gr: MME-PRELUDE emitted gen=%u words=%u window=%u h=0x%x push=0x%llx\n",
- g0, pl_n, win3d_n, req->h_object,
- req->push_va);
+ pr_info("vgsp-gr: MME-PRELUDE emitted gen=%u words=%u window=%u h=0x%x push=0x%llx sdm_drop=%u\n",
+ g0, pwords, win3d_n, req->h_object,
+ req->push_va, sdrop);
} else {
pr_info("vgsp-gr: MME-PRELUDE copy raced an append (gen %u->%u); emitted words=%u, will re-emit next launch\n",
g0, g1, pl_n);
@@ -17286,6 +17384,18 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
if (off + span > attr_pre_n)
span = attr_pre_n - off;
+ /*
+ * SESSION 153-CONTINUED-59: the same SDM
+ * sanitize as the MME prelude (see
+ * gsp_phys_rmcall_gr_sdm_drop); the cursor
+ * still advances so the drop is permanent.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_sdm_drop) &&
+ hdr && (op == 0u || op == 2u ||
+ op == 6u)) {
+ off += span;
+ continue;
+ }
if (copied + span > avail)
break;
memcpy(&p[copied], &attr_pre[off],
@@ -19793,6 +19903,23 @@ static u64 gsp_phys_gr_surf_dummy_dma_locked(void)
* verbatim (it faults later and is named in the drain). Called with
* gsp_phys_rm_lock held.
*/
+/*
+ * SESSION 153-CONTINUED-59: window/attr operand-miss state for the
+ * pre-doorbell abort (see gsp_phys_rmcall_gr_3d_reloc's level-2 fallback
+ * and the MISS-ABORT site in gsp_phys_backend_guest_gr_submit). Reset at
+ * the start of each 3D-window patch pass; a nonzero count at the submit
+ * point means the emitted block still carries a raw client VA the physical
+ * engine cannot resolve, which is the r1104/r1105 lane-killing class.
+ * sema_gl_miss_abort=0 restores the historical submit-anyway behaviour.
+ */
+static u32 gsp_phys_rmcall_gr_3d_miss_n;
+static bool gsp_phys_rmcall_gr_miss_abort = true;
+static u64 gsp_phys_gr_miss_abort_n;
+module_param_named(sema_gl_miss_abort, gsp_phys_rmcall_gr_miss_abort, bool,
+ 0644);
+MODULE_PARM_DESC(sema_gl_miss_abort,
+ "Abort a 3D-window launch before the doorbell while a window/attr operand relocation MISSes (page demanded via the pin path; retried on the next forward; fail-open after 3000 aborts). Default 1");
+
static bool gsp_phys_rmcall_gr_3d_reloc(u32 *up_w, u32 *lo_w,
const struct gsp_phys_gr_submit *req,
u32 *n_shadow)
@@ -19841,6 +19968,40 @@ static bool gsp_phys_rmcall_gr_3d_reloc(u32 *up_w, u32 *lo_w,
*up_w = (*up_w & ~0xffu) | ((u32)(sh >> 32) & 0xffu);
return true;
}
+ /*
+ * SESSION 153-CONTINUED-59: level-2 late resolution, the same trusted
+ * chain the MME payload branch uses (ipin/pin/lat/map/walk then shadow
+ * map). The r1104 first beat window MISSed the program pair 0x2054
+ * (va=0x4350900) and the r1105 windows MISSed the index-buffer pairs
+ * (0x17c8, va=0x44fedf0...) whose pages were not in the launch page
+ * set at build time; the raw guest VA then let the engine fault the
+ * MMU (HUBCLIENT_PD) and the guest driver reset the channel. Resolve
+ * the page here if any stage knows it, so a MISS only survives when
+ * every source fails; a surviving MISS is recorded for the pin demand
+ * set and counts toward the pre-doorbell abort.
+ */
+ {
+ struct gsp_sema_gr_reloc r;
+ u32 line2 = 0;
+
+ if (!gsp_sema_gr_reloc_resolve(va, &r) && r.hpa &&
+ *n_shadow < GSP_PHYS_RMCALL_GR_SHADOW_PAGES &&
+ !gsp_phys_rmcall_gr_map_shadow_locked(*n_shadow, r.hpa,
+ &sh, &line2)) {
+ if (line2 != 0xffffffffu)
+ (*n_shadow)++;
+ sh |= va & (GSP_PHYS_PAGE_SIZE - 1);
+ *lo_w = (*lo_w & 0x3u) | ((u32)sh & 0xfffffffcu);
+ *up_w = (*up_w & ~0xffu) | ((u32)(sh >> 32) & 0xffu);
+ return true;
+ }
+ }
+ /*
+ * Unresolvable: demand the page for the pin path and count the miss
+ * (the submit path aborts pre-doorbell while the count is nonzero).
+ */
+ gsp_phys_rmcall_gr_3d_miss_n++;
+ gsp_sema_demand_note(page);
return false;
}
@@ -20190,13 +20351,14 @@ static bool gsp_phys_rmcall_gr_win_patch_find(u32 addr, u32 *out_data)
}
static u32 gsp_phys_rmcall_gr_3d_last_subdrop;
+static u32 gsp_phys_rmcall_gr_3d_last_sdmdrop;
static u32 gsp_phys_rmcall_gr_3d_patch_window(const u32 *in, u32 n, u32 *out,
u32 *out_n, u32 *n_dropped,
const struct gsp_phys_gr_submit *req,
u32 *n_shadow)
{
- u32 off = 0, wout = 0, reloc = 0, dropped = 0, subdrop = 0;
+ u32 off = 0, wout = 0, reloc = 0, dropped = 0, subdrop = 0, sdm_drop = 0;
*out_n = n;
*n_dropped = 0;
@@ -20237,6 +20399,21 @@ static u32 gsp_phys_rmcall_gr_3d_patch_window(const u32 *in, u32 n, u32 *out,
off += span;
continue;
}
+ /*
+ * SESSION 153-CONTINUED-59: single-word SDM-type entries
+ * (SEC_OP 0/2/6, see gsp_phys_rmcall_gr_sdm_drop). The
+ * retiring X-family windows never yield one; this guards a
+ * window that carries the client's SDM markers (the
+ * 0x1fff0-class marker words or the prelude 0x046x6dXX
+ * family), which the physical PBDMA refuses with PBENTRY.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_sdm_drop) &&
+ hdr && (op == 0u || op == 2u || op == 6u)) {
+ dropped++;
+ sdm_drop++;
+ off += span;
+ continue;
+ }
if (gsp_phys_rmcall_gr_win_drop_match(addr) ||
gsp_phys_rmcall_gr_win_drop_auto_match(addr)) {
dropped++;
@@ -20553,6 +20730,7 @@ static u32 gsp_phys_rmcall_gr_3d_patch_window(const u32 *in, u32 n, u32 *out,
*out_n = wout;
*n_dropped = dropped;
gsp_phys_rmcall_gr_3d_last_subdrop = subdrop;
+ gsp_phys_rmcall_gr_3d_last_sdmdrop = sdm_drop;
return reloc;
}
@@ -22029,15 +22207,19 @@ gr_page_unmapped:
*/
gsp_phys_gr_surface_alias_scan_locked(req->stream,
req->stream_n, req);
+ /* SESSION 153-CONTINUED-59: fresh miss census for this pass
+ * (window + attr patch below both feed it). */
+ gsp_phys_rmcall_gr_3d_miss_n = 0;
nrel = gsp_phys_rmcall_gr_3d_patch_window(
req->stream, req->stream_n, stream_patch, &win_n,
&ndrop, req, &n_shadow);
win3d = stream_patch;
win3d_n = win_n;
- pr_info("vgsp-gr: 3D window relocated %u operand pair(s) to shadow VAs (window=%u shadow=%u dropped=%u subdrop=%u)\n",
+ pr_info("vgsp-gr: 3D window relocated %u operand pair(s) to shadow VAs (window=%u shadow=%u dropped=%u subdrop=%u sdmdrop=%u)\n",
nrel, win3d_n, n_shadow, ndrop,
- gsp_phys_rmcall_gr_3d_last_subdrop);
+ gsp_phys_rmcall_gr_3d_last_subdrop,
+ gsp_phys_rmcall_gr_3d_last_sdmdrop);
/*
* SESSION 153-CONTINUED-57: patch the attr/pipeline prelude for
* this launch (relocation exactly like the window: the
@@ -22086,6 +22268,39 @@ gr_page_unmapped:
}
}
/*
+ * SESSION 153-CONTINUED-59: pre-doorbell MISS abort (see the
+ * gsp_phys_rmcall_gr_miss_abort comment). A window/attr
+ * operand whose relocation stayed a raw client VA after the
+ * level-2 resolver would make the physical engine read an
+ * unmapped page (r1104 MMU Fault HUBCLIENT_PD @0x4350000 ->
+ * guest channel reset; r1105 index-buffer misses). Ride the
+ * same failure path as RELOC-GAP-STRICT: the launch is not
+ * submitted, the caller falls back and authors the software
+ * release, the page is already in the pin demand set, and
+ * the next forward retries. Bounded: after 3000 aborts the
+ * check fails open so a page the resolver can never see
+ * cannot livelock the lane forever.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_miss_abort) &&
+ gsp_phys_rmcall_gr_3d_miss_n &&
+ gsp_phys_gr_miss_abort_n < 3000u) {
+ static u32 miss_abort_log;
+
+ gsp_phys_gr_miss_abort_n++;
+ if (miss_abort_log < 16u ||
+ !(gsp_phys_gr_miss_abort_n % 256u)) {
+ miss_abort_log++;
+ pr_info("vgsp-gr: MISS-ABORT h=0x%x push=0x%llx miss=%u n=%llu (operand page unresolvable; demanded via pin path, launch not submitted - retry next forward)\n",
+ req->h_object, req->push_va,
+ gsp_phys_rmcall_gr_3d_miss_n,
+ gsp_phys_gr_miss_abort_n);
+ }
+ mutex_unlock(&gsp_phys_rm_lock);
+ gsp_phys_gr_refused++;
+ ret = -EAGAIN;
+ goto out;
+ }
+ /*
* SESSION 153-CONTINUED-56: bounded RAW (pre-drop, pre-reloc)
* window dump so the emitted window can be diffed against the
* client's authentic bytes. r1091 faulted at method 0x1168
@@ -22753,6 +22968,55 @@ gr_page_unmapped:
w0 = READ_ONCE(*(u32 *)sem_va);
}
/*
+ * SESSION 153-CONTINUED-59: PBENTRY first-sighting watch.
+ * The r1102 fault was only captured via the GSP's 0x1006
+ * relay (seconds later, intr0 already cleared by the RM):
+ * here every 5 ms poll of a 3D-stream launch scans the 12
+ * PBDMA instances for NV_PPBDMA_INTR_0 bit 18 (PBENTRY) and
+ * on the FIRST sighting dumps the live PB_HEADER / PB_COUNT
+ * / PB_DATA0 / HDR_SHADOW set plus the raw 0x100..0x120
+ * block for the faulting instance, before any re-arm or RM
+ * clear can overwrite them. Bounded (8 lines per boot);
+ * read-only, no behavior change to the launch.
+ */
+ if (stream3d && bar0) {
+ static u32 pbentry_log;
+ u32 pi2;
+
+ for (pi2 = 0; pi2 < 12 && pbentry_log < 8; pi2++) {
+ u32 b2 = 0x40000u + pi2 * 0x2000u;
+ u32 i0 = ioread32(bar0 + b2 + 0x108u);
+
+ if (!(i0 & 0x00040000u))
+ continue;
+ pbentry_log++;
+ pr_warn("vgsp-gr: PBENTRY-FIRST-SIGHTING P%u intr0=%08x gpf=%u pbfetch=0x%llx hdr=%08x cnt=%08x data0=%08x pbhd=%08x h=%x push=0x%llx words=%u tick=%u\n",
+ pi2, i0,
+ ioread32(bar0 + b2 + 0x050u),
+ ((u64)(ioread32(bar0 + b2 + 0x058u) &
+ 0xffu) << 32) |
+ (ioread32(bar0 + b2 + 0x054u) &
+ ~3u),
+ ioread32(bar0 + b2 + 0x118u),
+ ioread32(bar0 + b2 + 0x088u),
+ ioread32(bar0 + b2 + 0x08cu),
+ ioread32(bar0 + b2 + 0x084u),
+ req->h_object, req->push_va, words,
+ sked_tick);
+ pr_info("vgsp-gr: PBENTRY-FIRST-SIGHTING P%u raw[0x100]=%08x [104]=%08x [10c]=%08x [110]=%08x [114]=%08x [11c]=%08x [120]=%08x\n",
+ pi2,
+ ioread32(bar0 + b2 + 0x100u),
+ ioread32(bar0 + b2 + 0x104u),
+ ioread32(bar0 + b2 + 0x10cu),
+ ioread32(bar0 + b2 + 0x110u),
+ ioread32(bar0 + b2 + 0x114u),
+ ioread32(bar0 + b2 + 0x11cu),
+ ioread32(bar0 + b2 + 0x120u));
+ gsp_phys_pbdma_fault_dump(0xffffffffu);
+ break;
+ }
+ }
+ /*
* SESSION 153-CONTINUED-13: early PBDMA fetch probe for a 3D
* stream launch - where is the front end while a DRAW window
* does not retire? One shot per launch at ~150 ms and ~1.2 s