diff options
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index b43b222..7467b45 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -44,6 +44,7 @@ #include <linux/workqueue.h> #include <linux/mm.h> #include <linux/vmalloc.h> +#include <asm/unaligned.h> #include "nvidia-vgpu-vfio.h" #include "gsp_sema_service.h" @@ -3330,6 +3331,21 @@ static void svc_gr_cand_capture(struct svc_channel *ch, svc_gr_cand.param_size, svc_gr_cand.rel_va, svc_gr_cand.rel_payload, svc_gr_cand.rel_flags, svc_gr_cand.n_pointer, svc_gr_cand.n_inline); + if (push && push_len >= 16) { + u32 n = push_len / 4; + char buf[6 * 16 + 1]; + u32 i, o = 0; + + if (n > 32) + n = 32; + for (i = 0; i < n; i++) { + o += scnprintf(buf + o, sizeof(buf) - o, "%08x ", + get_unaligned_le32(push + i * 4)); + if (o >= sizeof(buf) - 12) + break; + } + pr_info("sema-gr: push[%u dwords]: %s\n", n, buf); + } } /* @@ -7987,6 +8003,15 @@ struct svc_fwd_req { u64 gr_push_va; u32 gr_push_len; u64 gr_qmd_dev_va; + /* + * The QMD buffer page (the inline-QMD destination the CUDA driver + * uses), resolved VA->guest PA on the service thread. The work item + * turns gr_qmd_pa into an HPA; the backend maps that page and points + * SET_INLINE_QMD_ADDRESS_A/B at it so the IQ2M copies the QMD into + * the guest's own buffer, exactly like the driver's qmd->devVA. + */ + u64 gr_qmd_pa; + u8 gr_qmd_ap; /* SVC_APERTURE_* of gr_qmd_pa */ u32 gr_rel_flags; u64 gr_rel_va; u32 gr_rel_payload; @@ -8873,6 +8898,18 @@ static void svc_fwd_gr_work(void) gs.qmd = svc_fwd_req.gr_qmd; gs.qmd_words = SVC_GR_QMD_WORDS; gs.qmd_va = svc_fwd_req.gr_qmd_dev_va; + gs.qmd_hpa = 0; + if (svc_fwd_req.gr_qmd_pa) { + u8 qkind = (svc_fwd_req.gr_qmd_ap == SVC_APERTURE_FB) ? + SVC_APERTURE_FB : SVC_APERTURE_SYS; + u64 qhpa = 0; + u32 qoff = 0; + + if (!svc_fwd_operand_hpa(svc_fwd_req.vgpu, qkind, + svc_fwd_req.gr_qmd_pa, 0, + SEMA_PAGE_SIZE, &qhpa, &qoff) && !qoff) + gs.qmd_hpa = qhpa; + } gs.pages = pages; gs.n_pages = svc_fwd_req.gr_n_pages; gs.inl = (const struct gsp_phys_gr_inline *)svc_fwd_req.gr_inline; @@ -9229,6 +9266,23 @@ static int svc_gr_req_fill(struct nv_vgpu_device *vgpu, svc_fwd_req.gr_push_va = svc_gr_cand.push_va; svc_fwd_req.gr_push_len = svc_gr_cand.push_len; svc_fwd_req.gr_qmd_dev_va = svc_gr_cand.qmd_dev_va; + /* + * Resolve the QMD buffer page now, on the service thread. A miss + * leaves gr_qmd_pa 0 and the backend keeps the module scratch page as + * the inline-QMD destination (fail-open; the launch can still run). + */ + svc_fwd_req.gr_qmd_pa = 0; + svc_fwd_req.gr_qmd_ap = SVC_APERTURE_SYS; + if (svc_gr_cand.qmd_dev_va) { + u64 qpa = 0; + u32 qap = SVC_APERTURE_SYS; + + if (!svc_resolve_va(vgpu, svc_gr_cand.qmd_dev_va, &qpa, &qap)) { + svc_fwd_req.gr_qmd_pa = + qpa & ~(u64)(SEMA_PAGE_SIZE - 1); + svc_fwd_req.gr_qmd_ap = (u8)svc_ap_of(qap); + } + } svc_fwd_req.gr_rel_flags = svc_gr_cand.rel_flags; svc_fwd_req.gr_rel_va = svc_gr_cand.rel_va; svc_fwd_req.gr_rel_payload = svc_gr_cand.rel_payload; |
