diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 0578d3c..5505c1e 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -313,6 +313,7 @@ struct sema_svc { u64 memsets_fail; u64 ring_ops; /* op runs from ring-decoded pushes */ u64 lda_log; /* LAUNCH_DMA inventory budget */ + u64 entry_log; /* per-push summary budget */ u64 releases_seen; u64 releases_applied; u64 releases_missed; /* no VA->PA entry */ @@ -1545,6 +1546,9 @@ struct svc_push_state { u32 sem_inc; u32 rs_upper, rs_lower, rs_payload; u32 have_rs_addr, have_rs_payload; + u64 rel_va; /* last release decoded in this push */ + u32 rel_payload; + u32 have_rel; }; /* ------------------------------------------------------------------ */ @@ -1725,6 +1729,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, struct svc_push_state st; struct svc_memset_op ops[SVC_MAX_MEMSETS]; u32 n_ops = 0; + u32 ops_runs = 0; u32 off = 0; memset(&st, 0, sizeof(st)); @@ -1825,11 +1830,15 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (page_pa) svc_mark_hot(page_pa); svc.pushes_seen++; + st.rel_va = va; + st.rel_payload = payload; + st.have_rel = 1; /* The push's work always runs; see the * REPORT_SEM comment below. */ if (allow_ops && n_ops) { svc_run_ops(vgpu, ops, n_ops); svc.ring_ops++; + ops_runs++; } n_ops = 0; if (!svc_sem_read(vgpu, va, &cur) && @@ -1889,6 +1898,9 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (page_pa) svc_mark_hot(page_pa); svc.pushes_seen++; + st.rel_va = va; + st.rel_payload = st.rs_payload; + st.have_rel = 1; /* * The push's collected work always runs on * real hardware; the semaphore release only @@ -1907,6 +1919,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (allow_ops && n_ops) { svc_run_ops(vgpu, ops, n_ops); svc.ring_ops++; + ops_runs++; } n_ops = 0; if (svc_sem_read(vgpu, va, &cur)) @@ -2044,6 +2057,9 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, svc.pushes_seen++; sem_va = ((u64)st.sem_va_hi << 32) | st.sem_va_lo; + st.rel_va = sem_va; + st.rel_payload = st.sem_payload; + st.have_rel = 1; if (st.have_sem && st.sem_payload && sem_va >= SEMA_VA_LO && sem_va < SEMA_VA_HI) { @@ -2067,6 +2083,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (allow_ops && n_ops) { svc_run_ops(vgpu, ops, n_ops); svc.ring_ops++; + ops_runs++; } if (pending) { svc.pushes_pending++; @@ -2090,6 +2107,21 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, } off += 4 + count * 4; } + + if (ch_h && svc.entry_log < 64) { + svc.entry_log++; + { + u8 tail[24]; + u32 tlen = len >= sizeof(tail) ? sizeof(tail) : len; + + if (tlen) + memcpy(tail, buf + len - tlen, tlen); + pr_info("sema-push: h=0x%x eng=%u len=%u ops_runs=%u rel=0x%llx pay=%u have_rel=%u tail=%*phN\n", + ch_h, ch_eng, len, ops_runs, st.rel_va, + st.rel_payload, st.have_rel, tlen, + tlen ? tail : NULL); + } + } } /* ------------------------------------------------------------------ */ @@ -3278,9 +3310,20 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) /* Rescue succeeded, retry the read. */ if (!svc_read_va_trusted(vgpu, va, pb, len)) { + /* + * Never run work decoded from a + * rescued page: the rescue matches + * the expected release bytes in + * arbitrary RAM and has matched GSP + * firmware/code pages, whose bytes + * decode as plausible but bogus + * method streams (ops_runs could + * fill vidmem with garbage). Only + * the release is applied. + */ svc_decode_stream(vgpu, pb, len, 0, - ch->engine_type != 0, + false, ch->h_object, ch->engine_type); ch->submissions++; |
