diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-07 17:04:18 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-07 17:04:18 -0400 |
| commit | 2f7ae2edca2d13f863b8c1435e544182664c007f (patch) | |
| tree | de06bcc9dc028b1e29b961ce230d7bd5cd9131e3 /kernel | |
| parent | b50dbd98915d6557c165642298b06e017f96f64c (diff) | |
| download | open-iov-2f7ae2edca2d13f863b8c1435e544182664c007f.tar.gz open-iov-2f7ae2edca2d13f863b8c1435e544182664c007f.zip | |
vgsp: m121 - resolve param-page kernel-argument pointers (offsets >= 0x150) before the bounce cap
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 0be279e..86cee81 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -9586,6 +9586,47 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) * 2 KB is scanned for plausible device VAs. */ n_cand = 0; + /* + * m121: kernel-argument pointers first. The launched kernel's device + * pointers live in the param page (qmd_word 32, c[0x0]) at byte + * offsets >= 0x150 (m120: mail_kernel out@0x160, msg@0x168; vadd + * a/b/c@0x160/0x168/0x170). m120 lost them: 13 candidates, the + * driver-internal pointers resolved first consumed the 100-page + * bounce cap, and c[0x0][0x168] stayed a guest VA (the first LDG + * MMU_NACKed). Collecting the argument area first guarantees those + * pages are resolved and their pointer words rewritten. + */ + 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 = 0x150u / 8u; k < 256; k++) { + u64 v = get_unaligned_le64(page + k * 8); + u64 wv; + + if (v < 0x10000000ULL || v >= (1ULL << 47) || + (v & 3)) + continue; + wv = v & ~(u64)(SEMA_PAGE_SIZE - 1); + for (w = 0; w < n_cand; w++) + if (wins[w] == wv) + break; + if (w == n_cand && n_cand < ARRAY_SIZE(wins)) + wins[n_cand++] = wv; + } + } 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; |
