summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index ba9d3da..abc9b06 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -819,6 +819,7 @@ struct sema_svc {
u64 pushtrace_all; /* fail4: de-windowed push decode
* trace (every push, bounded) */
u64 opadd_log; /* fail4: every op appended */
+ u64 op2d_raw_log; /* r458: raw 2D-shaped copy pushes */
u64 dmatrace_log; /* fail4: denied-transfer trace */
u64 pend_dbg_log; /* fail4 r305: pending/hold witness */
u64 snap_gate_log; /* fail4 r311: capture-gate witness */
@@ -9907,6 +9908,23 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
break;
case CE_M_LINE_LENGTH_IN:
st.line_length = v0;
+ /*
+ * r458 THE memset2d root cause: the driver encodes
+ * LINE_LENGTH_IN (0x418) and the adjacent LINE_COUNT
+ * (0x41c) as ONE count=2 method group - observed raw
+ * push bytes `20028106 00001000 00000100` = header
+ * (subch 4, count 2, addr 0x418), line length 4096,
+ * line count 0x100 = 256. Reading only v0 left
+ * line_count = 0, so the 2D-copy builder below took
+ * the single-row path: one 4 KB op per push, and a
+ * 4 MB cudaMemcpy2D delivered exactly one page per
+ * 1 MB block (memset2d probe: per-MB ok=4096,
+ * bad=12.5M/12.58M). The GRCE variant below has
+ * always decoded the count=2 form; the CE path did
+ * not.
+ */
+ if (count >= 2)
+ st.line_count = v1;
break;
/* r402: 2D geometry (cudaMemset2D / cudaMemcpy2D). */
case CE_M_LINE_COUNT:
@@ -10214,6 +10232,39 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
m->spitch = spitch;
}
}
+ /*
+ * r458 memset2d forensics: the
+ * driver's cudaMemcpy2D pushes decode
+ * LINE_LENGTH=4096 with PITCH_IN/OUT
+ * present but LINE_COUNT absent
+ * (lc=0), so only one 4 KB row per
+ * push executes and a 4 MB copy
+ * delivers 4 pages. Dump the raw push
+ * (bounded) for every pitch-shaped
+ * copy so the method stream that
+ * carries the row count is on record.
+ */
+ if (gsp_sema_dbg &&
+ (st.have_pitch_out ||
+ st.have_pitch_in) &&
+ svc.op2d_raw_log < 12) {
+ u32 dl = len < 220 ? len : 220;
+
+ svc.op2d_raw_log++;
+ pr_info("sema-op2d-raw: h=0x%x push=0x%llx len=%u off=0x%x line=%u lc=%u po=%u/%u pi=%u/%u out=0x%llx in=0x%llx bytes=%u dma=0x%08x\n",
+ ch->h_object, push_va,
+ len, off,
+ st.line_length,
+ st.line_count,
+ st.have_pitch_out,
+ st.pitch_out,
+ st.have_pitch_in,
+ st.pitch_in,
+ m->dst, m->src,
+ (u32)m->bytes, dma);
+ pr_info("sema-op2d-raw: raw %*phN\n",
+ dl, buf);
+ }
n_ops++;
ops_seq++;
} else if (gsp_sema_dbg && svc.dma_skip_log < 32) {