summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:45:33 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:45:33 -0400
commit903ce168ca1ec9206a23aea66e9008346def74e2 (patch)
tree3abbf6f17d4246616925fa5e6caf90d6795f55b5
parent32446284021c44f46767ebffd1c64ffddfed1ed3 (diff)
downloadopen-iov-903ce168ca1ec9206a23aea66e9008346def74e2.tar.gz
open-iov-903ce168ca1ec9206a23aea66e9008346def74e2.zip
sema-svc: learn GR counter PA from pinned release VA (auto-register, publish puts)
-rw-r--r--kernel/gsp_sema_service.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index e21c997..d4cab22 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -2111,6 +2111,39 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h,
h, pa, payload, cur);
}
+/*
+ * Learn a GR channel's completion-counter guest PA from a release VA the
+ * push carried, so the publish path can advance the exact slot the client
+ * polls without any guest-side enumeration. Only a host-verified translation
+ * (pin/ipin) is trusted; the release VA of a GR push is the counter slot
+ * itself (0x20400fXX observed). No-op once registered.
+ */
+static void svc_counter_learn(u32 h, u64 sem_va)
+{
+ unsigned long flags;
+ u64 pa = 0;
+ int ap = SVC_APERTURE_SYS;
+ int i;
+
+ if (!h || sem_va < 0x204000000ULL || sem_va >= 0x204100000ULL)
+ return;
+ if (svc_pin_lookup_any(sem_va, &pa, &ap) || ap != SVC_APERTURE_SYS)
+ return;
+
+ spin_lock_irqsave(&svc.chan_lock, flags);
+ for (i = 0; i < SVC_MAX_CHANNELS; i++) {
+ if (svc.chan[i].valid && svc.chan[i].h_object == h) {
+ if (!svc.chan[i].counter_pa) {
+ svc.chan[i].counter_pa = pa & ~0x3ULL;
+ pr_info("sema-chan: counter learned h=0x%x pa=0x%llx (from release va=0x%llx)\n",
+ h, pa & ~0x3ULL, sem_va);
+ }
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&svc.chan_lock, flags);
+}
+
static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
u32 len, u64 page_pa, bool allow_ops,
u32 ch_h, u32 ch_eng, u64 push_va,
@@ -2557,6 +2590,14 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* translation. Same forward-only guard as the
* VA path.
*/
+ /*
+ * GR pushes release the per-channel completion
+ * counter; learn its guest PA from the (pinned)
+ * release VA so the publish path can advance the
+ * exact slot the client polls.
+ */
+ if (ch_eng == 0)
+ svc_counter_learn(ch_h, sem_va);
svc_counter_release_apply(vgpu, ch_h,
st.sem_payload);
/* release ends the push */