summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 12:13:10 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 12:13:10 -0400
commit1612492982479bc4e1f722c8e52d22ef37b0280f (patch)
treed3816aaf013a5b7611c11089469868908b3cf6b1 /kernel
parent9521339338f096d76fe22c3496ff435a48dffba9 (diff)
downloadopen-iov-1612492982479bc4e1f722c8e52d22ef37b0280f.tar.gz
open-iov-1612492982479bc4e1f722c8e52d22ef37b0280f.zip
vgsp-sema: pair CE push-buffer vmap pages with the right offset; validated rescues repair injections
The CE push-buffer uvm_rm_mem is vmalloc'd as a 4097-page area: one leading page plus the 4096-page (16 MB) GPU data window, so GPU data page k lives at vmap page k+1. The kcore chain resolver paired page k with vmap page k, pinning the adjacent push for every page; the pump then read the wrong push, decode failed, and the host fell into the content rescue which crawled one entry per ~2 s (r115: rescue_run=4202, entry_va=0x12001b18c repeating). Verified against five independent content-validated rescue anchors (k=20..28, all delta +1), and the vmap area boundary confirms the extra page (nv_vm_map_pages 4097 pages). Five fixes: - resolve_mem_pins() takes page_off; the CE chain and uvbp push-buffer paths pass mem_page_off() (1 when the vmap is exactly 16 MB + 1 page; 0 for direct-mapped mems like the semaphore pool). - a content-validated rescue page now also replaces the injected-pin entry (svc_rescue_try / svc_rescue_run_try), so a stale or wrong injection can no longer shadow the validated page and re-run the rescue on every pass. Evidence: r115 rescue anchors va 0x120014000->pa 0x12a2e2000 .. va 0x12001c000->pa 0x12a2de000 all at vmap offset k+1; the candidate pages decode as the adjacent push (wrong semaphore payload) before the fix.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index d68b3d3..a0efef0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -9696,6 +9696,14 @@ static int svc_rescue_try(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
entry_len)) {
svc_pin_store(cand_va_page, cand_pa, SVC_APERTURE_SYS);
svc_lat_store(cand_va_page, cand_pa, SVC_APERTURE_SYS);
+ /*
+ * m150: a content-validated page is stronger evidence than an
+ * unverified host injection. Replace the injected pair so a
+ * wrong injection (e.g. an off-by-one watcher pin) cannot
+ * shadow the validated page on the next read and re-run this
+ * rescue per pass (the second-session rescue crawl).
+ */
+ svc_ipin_store(cand_va_page, cand_pa, SVC_APERTURE_SYS);
svc_mark_hot(cand_pa);
pr_info("sema-svc: content rescue ch=0x%x rank=%u slot=%u entry_va=0x%llx len=%u want=%u -> pa=0x%llx va_page=0x%llx (cand %u/%u)\n",
ch->h_object, ch->ce_index, 4 * ch->ce_index, entry_va,
@@ -9818,6 +9826,12 @@ static int svc_rescue_run_try(struct nv_vgpu_device *vgpu,
for (i = 0; i < npages; i++) {
svc_pin_store(pin_va[i], pin_pa[i], SVC_APERTURE_SYS);
svc_lat_store(pin_va[i], pin_pa[i], SVC_APERTURE_SYS);
+ /*
+ * m150: see svc_rescue_try - validated pages replace
+ * a wrong injection so the rescue is paid once, not
+ * on every rewind pass.
+ */
+ svc_ipin_store(pin_va[i], pin_pa[i], SVC_APERTURE_SYS);
svc_mark_hot(pin_pa[i]);
}
svc.resc_run++;