summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 6fae2f2..2f3202e 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -2634,6 +2634,18 @@ EXPORT_SYMBOL_GPL(gsp_phys_boot_rm_flags);
static void *gsp_phys_chunk_page_va(const struct gsp_phys_boot_chunk *c,
u32 page)
{
+ /*
+ * SESSION 141: an unallocated chunk (no per-page array AND no base
+ * va) must answer NULL. It previously returned
+ * (u8 *)NULL + page*PAGE_SIZE - a small non-NULL garbage pointer -
+ * so the caller's NULL guard passed and the empty-set post-mortem
+ * print dereferenced it: Oops #2 RIP
+ * gsp_phys_backend_guest_gr_submit+0x4394, CR2=0x1e93c with slot 30
+ * (0x1e000 = 30*0x1000 + 0x900 off). min_data=0's no-external-data
+ * forward hit this on its first pass.
+ */
+ if (!c->page_va && !c->va)
+ return NULL;
if (c->page_va)
return c->page_va[page];
return (u8 *)c->va + (size_t)page * GSP_PHYS_PAGE_SIZE;
@@ -17678,8 +17690,40 @@ static u32 gsp_phys_gr_data_bi(u64 reloc_va)
* launches resolve 968-969 records (the client's whole arena); a launch
* with only a handful after the fill's drops has an unresolved argument
* set and must not be handed to the engine (see the submit guard).
+ *
+ * SESSION 127: the Vulkan inline-QMD launch (the C5C0 translator) is a
+ * compute dispatch whose operand set is one descriptor page and one
+ * parameter bank - a handful of records is healthy for it. Tunable module
+ * parameter (default 16 preserves the CUDA-era threshold); the translator
+ * cycles pass gsp_phys_gr_min_data=2.
*/
#define GSP_PHYS_GR_MIN_DATA_RECS 16u
+static unsigned int gsp_phys_gr_min_data_param = GSP_PHYS_GR_MIN_DATA_RECS;
+module_param_named(gsp_phys_gr_min_data, gsp_phys_gr_min_data_param, uint, 0644);
+MODULE_PARM_DESC(gsp_phys_gr_min_data,
+ "GR submit minimum data records (degenerate-set refusal threshold, 0..4096; 0 = explicit bypass for the no-external-data launch class; default 16)");
+
+/*
+ * r801 (SESSION 143): 0 is an explicit BYPASS, not a clamp to 1. The
+ * Vulkan launch's single QMD pointer pair names its own QMD window and its
+ * params are scalars, so the launch has no external data by construction;
+ * the bare n_data>=min gate wrongly classifies it degenerate. The bypass is
+ * safe now that gsp_phys_chunk_page_va answers NULL for an unallocated
+ * chunk (r800): before that guard the empty-set post-mortem print
+ * dereferenced a garbage pointer and oopsed at
+ * gsp_phys_backend_guest_gr_submit+0x4394. The proper predicate (all
+ * candidates launch-internal-filtered, none unresolved => not degenerate)
+ * replaces the bare threshold next; until then 0 stays an explicit,
+ * opt-in debug/test value and the default remains 16.
+ */
+static unsigned int gsp_phys_gr_min_data_value(void)
+{
+ unsigned int v = READ_ONCE(gsp_phys_gr_min_data_param);
+
+ if (v > 4096)
+ v = 4096;
+ return v;
+}
#define GSP_PHYS_GR_GAP_MAX 4096u /* total late pages per launch */
/*
* relfix PART 3 (r217 span containment): the late path authors ONLY the
@@ -19289,10 +19333,11 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
* into the same software-completion fallback without touching the
* engine, and cannot wedge it for the next client.
*/
- if (req->n_data < GSP_PHYS_GR_MIN_DATA_RECS) {
+ if (req->n_data < gsp_phys_gr_min_data_value()) {
gsp_phys_gr_refused++;
pr_err_ratelimited("vgsp-gr: GR submit refused: degenerate data set n_data=%u (min %u) launch_va=0x%llx\n",
- req->n_data, GSP_PHYS_GR_MIN_DATA_RECS,
+ req->n_data,
+ gsp_phys_gr_min_data_value(),
req->push_va);
return -ENODATA;
}