summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-20 23:53:08 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-20 23:53:08 -0400
commitf1c8349168cfcd3a2f0c293a4cf290be990d0e05 (patch)
tree2125d2c127b6ecad7a0036a23893b460e3e29be3
parent52a84dbe8908e51bbfa5eed7d207477946436749 (diff)
downloadopen-iov-f1c8349168cfcd3a2f0c293a4cf290be990d0e05.tar.gz
open-iov-f1c8349168cfcd3a2f0c293a4cf290be990d0e05.zip
sema/boot: r391c OUT-PAGE-WIT resolution witness for the sum=0 readback class
The GR copy-out now prints, per changed page, the landing-table resolution of the VA (the exact source the D2H reader's ledger-first branch uses) and its first 8 bytes beside the write target hpa - a launch/readback disagreement (write landed on another page/aperture than the reader resolves) becomes one line instead of a forensics session. Diagnostic only (bounded by the existing copywit budget).
-rw-r--r--kernel/gsp_phys_booter.c20
-rw-r--r--kernel/gsp_sema_service.c30
-rw-r--r--kernel/gsp_sema_service.h10
3 files changed, 58 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 4e296b9..5f57370 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -20944,14 +20944,30 @@ gr_page_unmapped:
*/
if (gsp_phys_gr_copywit_enabled() &&
outwit < GSP_PHYS_GR_COPYWIT_MAX) {
+ /*
+ * r391 diagnostic (sum=0 class): the
+ * landing-table resolution of this VA
+ * (the page the D2H reader will use)
+ * and its first 8 bytes beside the
+ * write target - a launch/readback
+ * disagreement in one line.
+ */
+ u64 rpa = 0, rval = 0;
+ u32 rap = 0;
+ bool rhave = gsp_sema_gr_va_snap(
+ req->data[wbi].va, &rpa,
+ &rap, &rval);
+
outwit++;
- pr_info("vgsp-gr: OUT-PAGE-WIT va=0x%llx hpa=0x%llx bi=%u first8=%016llx last8=%016llx pre=%08x post=%08x\n",
+ pr_info("vgsp-gr: OUT-PAGE-WIT va=0x%llx hpa=0x%llx bi=%u first8=%016llx last8=%016llx pre=%08x post=%08x res=%s pa=0x%llx ap=%u val8=%016llx\n",
req->data[wbi].va,
req->data[wbi].hpa, bi, f8,
(u64)get_unaligned_le64(
src + GSP_PHYS_PAGE_SIZE -
8),
- bounce_csum_in[bi], csum);
+ bounce_csum_in[bi], csum,
+ rhave ? "ledger" : "none",
+ rpa, rap, rval);
}
/*
* OUT-ALIAS-WIT: identical first 8 bytes as
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 97cbf57..2fb4fe1 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -17471,6 +17471,36 @@ bool gsp_sema_write_guard(u64 va, u64 pa, u32 ap, const char *path)
}
/*
+ * r391 diagnostic (sum=0 class): the landing-table resolution of a GR data VA
+ * plus the first 8 bytes read through it - the exact page the D2H reader's
+ * ledger-first branch will use. Printed by the GR copy-out next to the write
+ * target, so a launch/readback disagreement is visible in one line.
+ */
+bool gsp_sema_gr_va_snap(u64 va, u64 *pa, u32 *ap, u64 *val8)
+{
+ u64 lpa = 0;
+ u32 lap = 0;
+
+ if (svc_ledger_lookup(va, &lpa, &lap))
+ return false;
+ *pa = lpa & ~(u64)(SEMA_PAGE_SIZE - 1);
+ *ap = lap;
+ *val8 = 0;
+ if (!svc_fwd_req.vgpu)
+ return true;
+ if (lap == SVC_APERTURE_FB) {
+ u8 *base = svc_fwd_req.vgpu->bars[1].vaddr;
+ size_t size = svc_fb_shadow_size(svc_fwd_req.vgpu);
+
+ if (base && *pa + 8 <= size)
+ memcpy(val8, base + *pa, 8);
+ } else {
+ svc_read(svc_fwd_req.vgpu, *pa, val8, 8);
+ }
+ return true;
+}
+
+/*
* m144 (second-client launch-state divergence): collect device-VA-shaped
* candidate pointers from the bytes the ENGINE will actually execute.
*
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index 063ed5c..cef7b0a 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -408,4 +408,14 @@ int gsp_sema_gr_reloc_resolve(u64 va, struct gsp_sema_gr_reloc *out);
bool gsp_sema_gr_write_guard(u64 va, u64 hpa, const char *path);
bool gsp_sema_write_guard(u64 va, u64 pa, u32 ap, const char *path);
+/*
+ * r391 diagnostic (sum=0 class): resolve a GR data VA through the landing
+ * table (the exact source the D2H reader's ledger-first branch uses) and
+ * return the resolution plus the first 8 bytes read through it. The GR
+ * copy-out prints it next to the write target it used, so a launch/readback
+ * disagreement (the write went to another page/aperture than the reader
+ * resolves) is one line instead of a forensics session.
+ */
+bool gsp_sema_gr_va_snap(u64 va, u64 *pa, u32 *ap, u64 *val8);
+
#endif /* _GSP_SEMA_SERVICE_H_ */