summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 23:37:32 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 23:37:32 -0400
commit8948759ebdfd1372829222c03c90edfa44d93d72 (patch)
tree1b4722a144ac6c8081d2c7d7193c3087f0957b10 /kernel/gsp_phys_booter.c
parent1448acfa25b3dcd7884af1c1201afce6229928da (diff)
downloadopen-iov-8948759ebdfd1372829222c03c90edfa44d93d72.tar.gz
open-iov-8948759ebdfd1372829222c03c90edfa44d93d72.zip
vgsp: m68 - rewrite the QMD program-prefetch pair to the shadow copy + dump the program target
m67 decoded the QMD (v02_03, SASS_version 0x75, block 64x1x1, grid 1x1x1) and showed the host rewrote PROGRAM_ADDRESS (w48/49) to a Tier-2 shadow copy but left PROGRAM_PREFETCH_ADDR (w8 = LO32(prefetch>>8), w31[8:0] = HI32(prefetch>>8)) pointing at the guest VA 0x7a90ed44c800 - unmapped in the execution VAS. Rewrite the prefetch pair to the same shadow copy when the prefetch lies in the shadowed page (preserving prefetch size and SASS_VERSION), and dump the program target's 16 instruction words in the post-mortem to prove the SASS landed.
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 47068c4..8de8408 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -15990,6 +15990,41 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
(qmd[pg->qmd_word + 1] &
~0x1ffffu) |
((u32)(ptr_va >> 32) & 0x1ffffu);
+ /*
+ * m68: the program-prefetch pair (w8
+ * LO32(prefetch>>8), w31[8:0]
+ * HI32(prefetch>>8)) still carried the
+ * guest VA; a prefetch into our unmapped
+ * VAS may be what cancels the QMD after
+ * SKED schedules it. If the original
+ * prefetch address lies in the page we
+ * just shadowed, point it at the same
+ * shadow copy (preserving SASS_VERSION /
+ * prefetch size in w31).
+ */
+ if (pg->qmd_word == 48) {
+ u64 orig_pref =
+ ((u64)(qmd[31] &
+ 0x1ffu) << 40) |
+ ((u64)qmd[8] << 8);
+
+ if ((orig_pref &
+ ~(u64)(GSP_PHYS_PAGE_SIZE - 1)) ==
+ pg_va) {
+ u64 new_pref = ptr_va |
+ (orig_pref &
+ (GSP_PHYS_PAGE_SIZE - 1));
+
+ qmd[8] = (u32)(new_pref >> 8);
+ qmd[31] = (qmd[31] &
+ ~0x1ffu) |
+ ((u32)((new_pref >> 40)) &
+ 0x1ffu);
+ pr_info("vgsp-gr: program prefetch rewritten to shadow 0x%llx (was 0x%llx)\n",
+ new_pref,
+ orig_pref);
+ }
+ }
mapped = true;
if (n_sh_rec < ARRAY_SIZE(sh_rec)) {
sh_rec[n_sh_rec].guest_va =
@@ -16350,6 +16385,41 @@ gr_page_unmapped:
get_unaligned_le32(qp2 + 116),
get_unaligned_le32(qp2 + 120),
get_unaligned_le32(qp2 + 124));
+ if (qp2) {
+ u64 pva = ((u64)(get_unaligned_le32(qp2 + 196) &
+ 0x1ffffu) << 32) |
+ get_unaligned_le32(qp2 + 192);
+ u64 sb = boot_stage.rmcall_va_guest_pt;
+
+ if (pva >= sb) {
+ u32 slot = (u32)(((pva - sb) >> 16) & 0x1fu);
+ u32 poff = (u32)(pva & (GSP_PHYS_PAGE_SIZE - 1));
+ const u32 *sp =
+ gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_gr_shadow,
+ slot);
+
+ if (sp && poff + 64 <= GSP_PHYS_PAGE_SIZE)
+ pr_info("vgsp-gr: post-mortem program target va=0x%llx slot=%u off=0x%x w0..15 = %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ pva, slot, poff,
+ get_unaligned_le32((u8 *)sp + poff),
+ get_unaligned_le32((u8 *)sp + poff + 4),
+ get_unaligned_le32((u8 *)sp + poff + 8),
+ get_unaligned_le32((u8 *)sp + poff + 12),
+ get_unaligned_le32((u8 *)sp + poff + 16),
+ get_unaligned_le32((u8 *)sp + poff + 20),
+ get_unaligned_le32((u8 *)sp + poff + 24),
+ get_unaligned_le32((u8 *)sp + poff + 28),
+ get_unaligned_le32((u8 *)sp + poff + 32),
+ get_unaligned_le32((u8 *)sp + poff + 36),
+ get_unaligned_le32((u8 *)sp + poff + 40),
+ get_unaligned_le32((u8 *)sp + poff + 44),
+ get_unaligned_le32((u8 *)sp + poff + 48),
+ get_unaligned_le32((u8 *)sp + poff + 52),
+ get_unaligned_le32((u8 *)sp + poff + 56),
+ get_unaligned_le32((u8 *)sp + poff + 60));
+ }
+ }
for (i = 0; i < req->n_pages && i < 16; i++)
pr_info("vgsp-gr: post-mortem page[%u] va=0x%llx hpa=0x%llx qmd_word=%u\n",
i, req->pages[i].guest_va,