From e5d1b3d6ab61b85b945400fcbd3637052feb2ace Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 30 Sep 2026 05:23:28 -0400 Subject: sema-svc: sema_copy_watch (size-keyed src/dst byte audit for the CE data path) --- kernel/gsp_sema_service.c | 39 +++++++++++++++++++++++++++++++++++++++ kernel/gsp_sema_service.h | 6 ++++++ kernel/main.c | 8 ++++++++ 3 files changed, 53 insertions(+) (limited to 'kernel') 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 @@ -90,6 +90,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 diff --git a/kernel/main.c b/kernel/main.c index 52156dc..3a42132 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2457,6 +2457,14 @@ MODULE_PARM_DESC(sema_skip_ops, "Apply releases without executing pushed memsets 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. -- cgit v1.2.3