summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c21
-rw-r--r--kernel/gsp_phys_gpu.c27
-rw-r--r--kernel/gsp_phys_gpu.h5
3 files changed, 53 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index bbb6d52..f4e558f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18454,6 +18454,7 @@ static u32 gsp_phys_m91_fault_start;
static u32 gsp_phys_m91_cap_used;
static bool gsp_phys_m91_cap_suppressed;
static bool gsp_phys_m91_icache_log;
+static bool gsp_phys_gr_rel_membar_log;
static noinline void
gsp_phys_gr_m91_fault_cap(const struct gsp_phys_gr_submit *req,
const u32 *qmd, u64 qmd_dst, const u8 *qmd_dst_mem,
@@ -18963,6 +18964,26 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
}
}
/*
+ * r433 RELEASE_MEMBAR_TYPE A/B (gsp_phys_gr_rel_membar): force the
+ * forwarded QMD's RELEASE_MEMBAR_TYPE to FE_SYSMEMBAR (QMDV00_06
+ * word 11 bit 14) so the front-end flushes its pending system-memory
+ * stores before writing the release semaphore. The captured guest
+ * QMDs carry FE_NONE, so a grid that completes with its data still
+ * in the GPU's L2 releases the client while no store is host-visible
+ * - the post-dispatch store-loss signature. The release ordering then
+ * guarantees the host's retire scan and copy-out can never observe a
+ * completion whose data has not landed. 0 (default) keeps the
+ * guest's captured value.
+ */
+ if (gsp_phys_gr_rel_membar_value() && !(qmd[11] & (1u << 14))) {
+ qmd[11] |= 1u << 14;
+ if (!gsp_phys_gr_rel_membar_log) {
+ gsp_phys_gr_rel_membar_log = true;
+ pr_info("vgsp-gr: r433 RELEASE_MEMBAR_TYPE forced to FE_SYSMEMBAR in the forwarded QMD (w11=0x%08x)\n",
+ qmd[11]);
+ }
+ }
+ /*
* Two-step PCAS (gsp_phys_rmcall_gr_pcas_two_step): set the QMD's
* REQUIRE_SCHEDULING_PCAS (w4 bit12) so the copy PCAS does not
* schedule and the trailing schedule-only PCAS does.
diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c
index b93c254..4c0fd37 100644
--- a/kernel/gsp_phys_gpu.c
+++ b/kernel/gsp_phys_gpu.c
@@ -1057,6 +1057,33 @@ int gsp_phys_gr_icache_inv_value(void)
EXPORT_SYMBOL_GPL(gsp_phys_gr_icache_inv_value);
/*
+ * r433 RELEASE_MEMBAR_TYPE A/B (gsp_phys_gr_rel_membar; default 0). The
+ * captured guest QMDs carry RELEASE_MEMBAR_TYPE=FE_NONE (QMDV00_06 word 11
+ * bit 14 clear, w11=0x44010000), so when the front-end completes a grid it
+ * writes the QMD release semaphore without first flushing its pending
+ * system-memory stores. The post-dispatch store-loss signature (the engine
+ * processes the QMD, writes the release, the grid completes and ZERO data
+ * pages are host-visible) is exactly what an unflushed write-back L2 looks
+ * like from the host: the release is host-visible while the data sits in the
+ * GPU's L2. Forcing RELEASE_MEMBAR_TYPE=FE_SYSMEMBAR makes the release
+ * ordering guarantee the stores are in memory before the semaphore write, so
+ * the host's retire scan (and the copy-out) can never observe a completion
+ * whose data has not landed. 0 keeps the guest's captured value (the
+ * historical behaviour) for a one-flip A/B; read per launch.
+ */
+static int gsp_phys_gr_rel_membar_param;
+module_param_named(gsp_phys_gr_rel_membar, gsp_phys_gr_rel_membar_param,
+ int, 0644);
+MODULE_PARM_DESC(gsp_phys_gr_rel_membar,
+ "r433: force QMD RELEASE_MEMBAR_TYPE=FE_SYSMEMBAR (word11 bit14) on forwarded GR launches (default 0 = guest's captured FE_NONE)");
+
+int gsp_phys_gr_rel_membar_value(void)
+{
+ return gsp_phys_gr_rel_membar_param;
+}
+EXPORT_SYMBOL_GPL(gsp_phys_gr_rel_membar_value);
+
+/*
* m179 no-write retry budget (gsp_phys_gr_nowrite_retries; default 3, clamped
* to [0, 4]). The m153 outcome retry loop re-executes a data-bearing launch
* whose retirement wait saw zero engine writes; it shared the timeout ladder's
diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h
index e02d6d8..8158b46 100644
--- a/kernel/gsp_phys_gpu.h
+++ b/kernel/gsp_phys_gpu.h
@@ -388,6 +388,11 @@ unsigned int gsp_phys_gr_first_poll_ms_value(void);
* (default 1; 0 = pre-m91 QMD words). */
int gsp_phys_gr_icache_inv_value(void);
+/* r433: force QMD RELEASE_MEMBAR_TYPE=FE_SYSMEMBAR (QMDV00_06 word11 bit14)
+ * on forwarded GR launches so the engine flushes pending sysmem stores
+ * before writing the release semaphore (default 0 = guest's FE_NONE). */
+int gsp_phys_gr_rel_membar_value(void);
+
/* m179: dedicated re-execution budget for a data-bearing GR launch whose
* retirement wait saw zero engine writes, independent of the timeout ladder's
* attempt counter (default 3, clamped [0,4]). */