summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 3887dbb..88c519d 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -14635,18 +14635,45 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
if (w == n_cand && n_cand < ARRAY_SIZE(wins))
wins[n_cand++] = wv;
}
- /*
- * relfix PART 3 (fill candidate superset): the rewrite scans
- * the WHOLE authored param page (0x0..0xfff) and re-resolves
- * every device-VA-shaped word it finds; any word this scan
- * does not collect resurfaces as a RELOC-GAP (r217: the two
- * words the late path fixed were param/program descriptor
- * fields below 0x150 / past 0x800 the argument scan never
- * looked at). Collect the page remainder with the same shape
- * test, after the argument region so the operand pages keep
- * budget priority (m120/m121). Launch-internal pages remain
- * filtered at resolution time below (R3 hygiene).
- */
+ /* m144: also scan the fresh inline-captured parameter block,
+ * so a reused/stale guest page cannot hide the kernel's device
+ * pointers. */
+ svc_gr_scan_inline(wins, &n_cand, pp->va);
+ }
+ /* m150: everything collected so far came from the c[0x0] argument
+ * page (or its inline bytes) - these are the pointers the kernel
+ * actually dereferences. */
+ for (w = 0; w < n_cand; w++)
+ is_arg[w] = true;
+ /*
+ * relfix PART 3 (fill candidate superset): the rewrite scans the WHOLE
+ * authored param page (0x0..0xfff) and re-resolves every
+ * device-VA-shaped word it finds; any word this fill does not collect
+ * resurfaces as a RELOC-GAP (r217: the two words the late path fixed
+ * were param/program descriptor fields below 0x150 / past 0x800 that
+ * the argument scan never looked at). Collect the page remainder here,
+ * AFTER the argument marking, so these page words keep is_arg=false -
+ * the per-argument hold and diagnostic semantics stay exactly as
+ * before. Budget priority is also unchanged: the argument candidates
+ * above are resolved first. Launch-internal pages remain filtered at
+ * resolution time (R3 hygiene below).
+ */
+ for (i = 0; i < svc_fwd_req.gr_n_pages; i++) {
+ const struct svc_gr_page *pp = &svc_fwd_req.gr_pages[i];
+ u64 hpa = 0;
+ const u8 *page;
+ u32 k;
+
+ if (pp->qmd_word != 32u || !pp->pa)
+ continue;
+ kind = (pp->ap == SVC_APERTURE_FB) ? SVC_APERTURE_FB :
+ SVC_APERTURE_SYS;
+ if (svc_fwd_operand_hpa(vgpu, kind, pp->pa, 0,
+ SEMA_PAGE_SIZE, &hpa, &off) || off)
+ continue;
+ page = (const u8 *)__va(hpa);
+ if (!page)
+ continue;
for (k = 0; k < SEMA_PAGE_SIZE / 8; k++) {
u64 v, wv;
@@ -14663,16 +14690,7 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
if (w == n_cand && n_cand < ARRAY_SIZE(wins))
wins[n_cand++] = wv;
}
- /* m144: also scan the fresh inline-captured parameter block,
- * so a reused/stale guest page cannot hide the kernel's device
- * pointers. */
- svc_gr_scan_inline(wins, &n_cand, pp->va);
}
- /* m150: everything collected so far came from the c[0x0] argument
- * page (or its inline bytes) - these are the pointers the kernel
- * actually dereferences. */
- for (w = 0; w < n_cand; w++)
- is_arg[w] = true;
for (i = 0; i < svc_fwd_req.gr_n_pages; i++) {
const struct svc_gr_page *pp = &svc_fwd_req.gr_pages[i];
u64 hpa = 0;