summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 21:46:02 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 21:46:02 -0400
commit66e6d16680d77a58fa235d837ba897879e8ae1f9 (patch)
treee655c043e6df6102bc02046afafbabbdc8a988b2 /kernel/gsp_phys_booter.c
parente0e96fe151e9bf690dd215e46da135da1dcc2317 (diff)
downloadopen-iov-66e6d16680d77a58fa235d837ba897879e8ae1f9.tar.gz
open-iov-66e6d16680d77a58fa235d837ba897879e8ae1f9.zip
vgsp: point inline-QMD launch at the guest QMD buffer + GR post-mortem logging
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index b95bd81..7113663 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -13024,6 +13024,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
bool qmd_rel = false, ch_rel = false;
u64 qmd_rel_hpa = 0, ch_rel_hpa = 0;
u64 ch_sem_va = GSP_PHYS_RMCALL_VA_SEM + 4;
+ u64 qmd_dst = GSP_PHYS_RMCALL_VA_SRC;
u32 qmd_rel_off = 0, ch_rel_off = 0;
u32 poll = 0, w0 = 0, w1 = 0;
int ret = 0;
@@ -13351,6 +13352,38 @@ gr_page_unmapped:
}
/*
+ * Inline-QMD destination: the CUDA driver points ADDRESS_A/B at its
+ * own QMD buffer (turing_launch.c:1629) and the IQ2M copies the 64
+ * inline words there before scheduling. Map the guest QMD page and
+ * use it as the destination when the caller resolved it; a Tier-1
+ * install keeps the guest VA (the guest sees its own QMD), a Tier-2
+ * alias keeps the launch runnable, and an unresolved page keeps the
+ * module scratch VA.
+ */
+ if (req->qmd_hpa) {
+ u64 qmd_page = req->qmd_va & ~(u64)(GSP_PHYS_PAGE_SIZE - 1);
+
+ if (qmd_page &&
+ !gsp_phys_rmcall_gr_map_va_locked(bar0, qmd_page,
+ req->qmd_hpa, epoch)) {
+ qmd_dst = qmd_page;
+ } else {
+ u64 sh_va = 0;
+
+ if (n_shadow < GSP_PHYS_RMCALL_GR_SHADOW_PAGES &&
+ !gsp_phys_rmcall_gr_map_shadow_locked(
+ n_shadow, req->qmd_hpa, &sh_va)) {
+ n_shadow++;
+ qmd_dst = sh_va +
+ (req->qmd_va &
+ (GSP_PHYS_PAGE_SIZE - 1));
+ }
+ }
+ pr_info("vgsp-gr: inline-QMD dest va=0x%llx hpa=0x%llx -> 0x%llx (shadow=%u)\n",
+ req->qmd_va, req->qmd_hpa, qmd_dst, n_shadow);
+ }
+
+ /*
* Channel release: author it into the guest semaphore page when the
* caller resolved one, else into the module semaphore's second word.
*/
@@ -13380,9 +13413,12 @@ gr_page_unmapped:
wmb();
words = gsp_phys_rmcall_build_gr_launch(methods, qmd,
- GSP_PHYS_RMCALL_VA_SRC,
+ qmd_dst,
ch_sem_va, want_ch);
memcpy(gsp_phys_chunk_page_va(pb, 0), methods, words * 4);
+ pr_info("vgsp-gr: qmd w0..3=%08x %08x %08x %08x w4..7=%08x %08x %08x %08x w23..25=%08x %08x %08x w32/33=%08x %08x w48/49=%08x %08x\n",
+ qmd[0], qmd[1], qmd[2], qmd[3], qmd[4], qmd[5], qmd[6], qmd[7],
+ qmd[23], qmd[24], qmd[25], qmd[32], qmd[33], qmd[48], qmd[49]);
ret = gsp_phys_rmcall_publish_locked(bar0, boot_stage.rmcall_va_pb,
words, &sub);
@@ -13436,6 +13472,41 @@ gr_page_unmapped:
}
}
}
+ /*
+ * Post-mortem: if the IQ2M landed the QMD in the guest
+ * buffer, the inline window was processed; GP_GET shows
+ * the front-end consumed the entry; the release word is
+ * re-read one last time.
+ */
+ {
+ u8 *ud = gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_chunks
+ [GSP_PHYS_RMCALL_BUF_USERD],
+ 0);
+ u32 gpget_post = ud ?
+ get_unaligned_le32(
+ ud + GSP_PHYS_RMCALL_USERD_GPGET_OFF)
+ : 0;
+ u32 q0 = 0, q1 = 0, q23 = 0, q24 = 0, q25 = 0;
+ u32 relw = 0;
+
+ if (req->qmd_hpa) {
+ u8 *qp = (u8 *)__va(req->qmd_hpa);
+
+ q0 = get_unaligned_le32(qp);
+ q1 = get_unaligned_le32(qp + 4);
+ q23 = get_unaligned_le32(qp + 92);
+ q24 = get_unaligned_le32(qp + 96);
+ q25 = get_unaligned_le32(qp + 100);
+ }
+ if (qmd_rel_hpa)
+ relw = READ_ONCE(
+ *(u32 *)((u8 *)__va(qmd_rel_hpa) +
+ qmd_rel_off));
+ pr_info("vgsp-gr: post-mortem gpget=%u->%u qmd_page w0=%08x w1=%08x w23..25=%08x %08x %08x relw=%08x\n",
+ sub.gpget, gpget_post, q0, q1, q23, q24,
+ q25, relw);
+ }
poll = w1;
ret = -ETIMEDOUT;
goto out;