summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c66
-rw-r--r--kernel/gsp_phys_gpu.h6
2 files changed, 71 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 96fdc46..5f8df5e 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18715,6 +18715,28 @@ bool gsp_phys_rmcall_gr_raster_pre_value(void)
}
/*
+ * SESSION 155 CONT 18: follow a migrated screen page instead of skipping
+ * its write-back. The guest's video-memory manager migrates the X screen
+ * BO (the WGUARD-SKIP "used != now" case); the drawn content then sits in
+ * the bounce copy of the old page and is currently discarded. When this
+ * knob is on and the stale VA belongs to the captured screen surface, the
+ * page is written to the VA's CURRENT mapping (receipt
+ * WGUARD-STALE-WRITE) so the guest sees the frame. Off = the historical
+ * safe skip.
+ */
+static bool gsp_phys_gr_stale_write;
+static u32 gsp_phys_gr_stale_log; /* CONT 18 */
+module_param_named(sema_gl_stale_write, gsp_phys_gr_stale_write, bool,
+ 0644);
+MODULE_PARM_DESC(sema_gl_stale_write,
+ "Write a copy-out page to the screen VA's current mapping when the write guard reports a migration (default 0; safe skip)");
+
+bool gsp_phys_rmcall_gr_stale_write_value(void)
+{
+ return READ_ONCE(gsp_phys_gr_stale_write);
+}
+
+/*
* SESSION 155 CONT 15: where the synthesized GS SPH lives inside the
* program-family page. 0 = family+0x780 (below the window's own VTG bind
* at family+0x900), 1 = family+0xe80 (above it; the DS's PROGRAM_REGION
@@ -33179,7 +33201,49 @@ gr_page_unmapped:
if (!gsp_sema_gr_write_guard(req->data[wbi].va,
req->data[wbi].hpa,
"gr-bounce-copy-out")) {
- skipped++;
+ /*
+ * CONT 18: a migrated screen page - follow
+ * the VA's current mapping instead of
+ * dropping the frame (see the knob).
+ */
+ bool followed = false;
+
+ if (READ_ONCE(gsp_phys_gr_stale_write)) {
+ u64 sva = 0;
+ u32 snp = 0;
+
+ if (gsp_sema_surf_va_get(&sva, &snp) &&
+ sva &&
+ req->data[wbi].va >= sva &&
+ req->data[wbi].va <
+ sva + ((u64)snp << 12)) {
+ u64 rpa = 0, rval = 0;
+ u32 rap = 0;
+
+ if (gsp_sema_gr_va_snap(
+ req->data[wbi].va,
+ &rpa, &rap, &rval) &&
+ rpa) {
+ memcpy((u8 *)__va(rpa),
+ src,
+ GSP_PHYS_PAGE_SIZE);
+ followed = true;
+ if (gsp_phys_gr_stale_log <
+ 64u) {
+ gsp_phys_gr_stale_log++;
+ pr_info("vgsp-gr: WGUARD-STALE-WRITE va=0x%llx used=0x%llx now=0x%llx h=0x%x push=0x%llx\n",
+ req->data[wbi].va,
+ req->data[wbi].hpa,
+ rpa,
+ req->h_object,
+ req->push_va);
+ }
+ wrote++;
+ }
+ }
+ }
+ if (!followed)
+ skipped++;
continue;
}
memcpy((u8 *)__va(req->data[wbi].hpa), src,
diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h
index d84cd41..f74fff1 100644
--- a/kernel/gsp_phys_gpu.h
+++ b/kernel/gsp_phys_gpu.h
@@ -375,6 +375,12 @@ u32 gsp_phys_rmcall_gr_sph_gs_mode_value(void);
bool gsp_phys_rmcall_gr_raster_pre_value(void);
/*
+ * SESSION 155 CONT 18: follow a migrated screen page in the copy-out
+ * (sema_gl_stale_write).
+ */
+bool gsp_phys_rmcall_gr_stale_write_value(void);
+
+/*
* SESSION 155 CONT 15: synthesized GS SPH placement/maps/context A/B.
*/
u32 gsp_phys_rmcall_gr_sph_gs_addr_value(void);