summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 40a8867..41a5c58 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -8776,7 +8776,27 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
if (slot_bytes > 0x8000 - 4)
slot_bytes = 0x8000 - 4;
}
- if ((trusted || allow_ops) && !gsp_sema_skip_ops &&
+ /*
+ * r391f once-only (the sum=0 class): a REPLAYED
+ * entry must not re-run its inline writes. The ops
+ * are already gated by allow_ops (entry_replay
+ * clears it), but the inline-write gate used
+ * `trusted || allow_ops` - and a replay is trusted
+ * by construction - so every re-decode of an
+ * already-processed push re-wrote its inline data
+ * into the vidmem shadow. victory_reduce's
+ * cudaMemset(d_sum,0,8) is exactly such an inline
+ * write (observed: `inline write
+ * dst=0x7845ef000000 -> pa=0x7c00000 bytes=8
+ * data8=0` firing 86 us before the D2H readback,
+ * zeroing the accumulator the launch had just
+ * written - the readback then reads zeros). The
+ * r383 replay-capture path only needs to CAPTURE
+ * the launch; the inline bytes were authored on the
+ * first (non-replay) pass.
+ */
+ if ((trusted || allow_ops) && !replay &&
+ !gsp_sema_skip_ops &&
st.have_out && st.line_length) {
u32 bytes = slot_run ? slot_bytes :
st.line_length *