summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 05:23:28 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 05:23:28 -0400
commite5d1b3d6ab61b85b945400fcbd3637052feb2ace (patch)
treea250f2f419ce241d26abb3ae0acc91690bcfd25c /kernel
parentc9a7d464617f41c447d9e85082839b5b06e2abbd (diff)
downloadopen-iov-e5d1b3d6ab61b85b945400fcbd3637052feb2ace.tar.gz
open-iov-e5d1b3d6ab61b85b945400fcbd3637052feb2ace.zip
sema-svc: sema_copy_watch (size-keyed src/dst byte audit for the CE data path)
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c39
-rw-r--r--kernel/gsp_sema_service.h6
-rw-r--r--kernel/main.c8
3 files changed, 53 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 56285bf..4d3f6ef 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -343,6 +343,7 @@ struct sema_svc {
u64 memsets_fail;
u64 ring_ops; /* op runs from ring-decoded pushes */
u64 lda_log; /* LAUNCH_DMA inventory budget */
+ u64 copy_watch_log; /* sema_copy_watch log budget */
u64 entry_log; /* per-push summary budget */
u64 ops_denied; /* work refused: implausible stream */
u64 false_trans; /* resolvable VA mapped to non-push */
@@ -2019,6 +2020,41 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
src_aperture = aper;
}
+ /*
+ * Data-path watch: for copies of exactly sema_copy_watch bytes, log
+ * the first 8 source and destination bytes so a broken link in the
+ * chain (wrong source page, wrong destination, silent wipe) is
+ * visible directly in the log.
+ */
+ if (gsp_sema_copy_watch && total == gsp_sema_copy_watch) {
+ u8 sb[8] = {0}, db[8] = {0};
+
+ if (src_aperture == CE_APERTURE_VID) {
+ u8 *base = vgpu->bars[1].vaddr;
+
+ if (base && src + 8 <= vgpu->bars[1].size)
+ memcpy(sb, base + src, 8);
+ } else {
+ svc_read(vgpu, src, sb, 8);
+ }
+ if (dst_aperture == CE_APERTURE_VID) {
+ u8 *base = vgpu->bars[1].vaddr;
+
+ if (base && dst + 8 <= vgpu->bars[1].size)
+ memcpy(db, base + dst, 8);
+ } else {
+ svc_read(vgpu, dst, db, 8);
+ }
+ if (svc.copy_watch_log < 64) {
+ svc.copy_watch_log++;
+ pr_info("sema-copy-watch: total=%zu dst=0x%llx dap=%u src=0x%llx sap=%u src8=%02x %02x %02x %02x %02x %02x %02x %02x dst8_before=%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ total, dst, dst_aperture, src, src_aperture,
+ sb[0], sb[1], sb[2], sb[3], sb[4], sb[5],
+ sb[6], sb[7], db[0], db[1], db[2], db[3],
+ db[4], db[5], db[6], db[7]);
+ }
+ }
+
for (o = 0; o < total; ) {
size_t chunk = total - o;
u32 i;
@@ -3685,6 +3721,9 @@ bool gsp_sema_skip_ops;
/* Executed-op log cap (see header). */
unsigned gsp_sema_ops_log = 8;
+/* Data-path watch: copy size whose first bytes are logged (0 = off). */
+unsigned gsp_sema_copy_watch;
+
static unsigned long svc_gr_ring_tried; /* ranks that got a diagnostic line */
static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index 7eb7382..67d138d 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -91,6 +91,12 @@ extern bool gsp_sema_skip_ops;
extern unsigned gsp_sema_ops_log;
/*
+ * Data-path watch: for copies of exactly this many bytes, log the first 8
+ * source/destination bytes before the copy (0 = off).
+ */
+extern unsigned gsp_sema_copy_watch;
+
+/*
* Grace window (ms) an untranslatable GR GPFIFO entry is left pending before
* the pump consumes it as stale. The GR push pages are pinned from guest
* truth a moment after the channels appear; the window lets those pins land
diff --git a/kernel/main.c b/kernel/main.c
index 52156dc..3a42132 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2458,6 +2458,14 @@ module_param_named(sema_ops_log, gsp_sema_ops_log, uint, 0644);
MODULE_PARM_DESC(sema_ops_log, "Max executed CE ops logged with operands (default 8)");
/*
+ * Data-path watch: log the first source/destination bytes of every CE copy
+ * of exactly this size (0 = off), to audit the push-data chain:
+ * echo 256 > .../parameters/sema_copy_watch
+ */
+module_param_named(sema_copy_watch, gsp_sema_copy_watch, uint, 0644);
+MODULE_PARM_DESC(sema_copy_watch, "Copy size whose first bytes are logged (default 0)");
+
+/*
* Grace window (ms) an untranslatable GR entry stays pending before the pump
* consumes it as stale, so a late push-buffer pin can still make it readable.
*/