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.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 587fb96..6c75a9e 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -8341,13 +8341,24 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
struct svc_memset_op *lm = &ops[n_ops - 1];
/*
- * fail4 A/B note: a CE-style auto-advance of
- * st.offset_out per op was tried here and
- * reverted - it did not change the memset
- * coverage and the driver's per-op re-sets are
- * already decoded, so the executed dsts match
- * the stream.
+ * fail4 CE linear auto-advance, BOTH sides: the
+ * driver re-sets only ONE offset per op and the
+ * copy engine advances the other by the transfer
+ * size. H2D ops show an explicit advancing DST
+ * with a FIXED SRC base (every 1 MB chunk read
+ * the source base again: vector_add's device a
+ * held h_a[0..1MB) x4 -> 75% mismatch; the
+ * readbacks are the mirror image). Advance both
+ * registers; an explicit re-set simply overrides.
*/
+ {
+ u64 adv = (lm->type == 1) ? lm->bytes :
+ (u64)lm->elem * lm->count;
+
+ st.offset_out += adv;
+ if (lm->type == 1)
+ st.offset_in += adv;
+ }
if (svc.opadd_log < 2048) {
svc.opadd_log++;
pr_info("sema-opadd: h=0x%x type=%u dst=0x%llx src=0x%llx bytes=%llu elem=%u count=%u ap=%u src_ap=%u phys=%u src_phys=%u\n",