summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 9d3697f..5307bdd 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -10809,6 +10809,12 @@ static void svc_notify2d_write(struct nv_vgpu_device *vgpu,
if (svc_write_ap(vgpu, pa, svc_ap_of(ap), zero, sizeof(zero)))
return;
svc_notify2d_done++;
+ /*
+ * r834: pin the page that accepted the ack; the same stale-map
+ * defense as the push-side pin in the decode.
+ */
+ svc_pin_store(ch->notify2d_va & ~(u64)(SEMA_PAGE_SIZE - 1),
+ pa & ~(u64)(SEMA_PAGE_SIZE - 1), svc_ap_of(ap));
if (gsp_sema_dbg && svc_notify2d_log < 16) {
svc_notify2d_log++;
pr_info("sema-notify2d: h=0x%x va=0x%llx -> pa=0x%llx zeroed (RC watchdog acked)\n",
@@ -11378,6 +11384,21 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
switch (addr) {
case SVC_2D_SET_NOTIFY_A:
ch->notify2d_va = (u64)(v0 & 0x1ffffff) << 32;
+ /*
+ * r834: this method stream reached us through
+ * a REAL read (svc_read_last_pa); pin its page
+ * so the watchdog's push translation cannot go
+ * stale later - the content-scanned map answers
+ * a zero page once the injected pin ages out,
+ * staging exactly the starvation the ack must
+ * not depend on.
+ */
+ if (svc_read_last_pa)
+ svc_pin_store(push_va &
+ ~(u64)(SEMA_PAGE_SIZE - 1),
+ svc_read_last_pa &
+ ~(u64)(SEMA_PAGE_SIZE - 1),
+ SVC_APERTURE_SYS);
break;
case SVC_2D_SET_NOTIFY_B:
ch->notify2d_va |= (u64)v0;