diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-06 23:59:07 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-06 23:59:07 -0500 |
| commit | 5f89d124d7c2cc4c8c8217e25510e001ac652dca (patch) | |
| tree | e074af85939a5a42e883fc570329b7d07dcd66f9 | |
| parent | db401573f1a8a2a926901f752b4401e8916d976c (diff) | |
| download | open-iov-5f89d124d7c2cc4c8c8217e25510e001ac652dca.tar.gz open-iov-5f89d124d7c2cc4c8c8217e25510e001ac652dca.zip | |
vgsp-gl: follow migrated screen pages in the GR copy-out
| -rw-r--r-- | kernel/gsp_phys_booter.c | 66 | ||||
| -rw-r--r-- | kernel/gsp_phys_gpu.h | 6 |
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); |
