From a62ba6f234bad3264f71a77b833d9b22f0210c54 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sun, 18 Oct 2026 15:48:50 -0400 Subject: vgsp: fail4 r234 - A-TRACE end-to-end 64KB copy trace + RDW rec-dump arming line r233: the probe ran (attempt-1 completes now) with the same deterministic foreign readback, while REC-DUMP/READ-DIVERGE-WIT/READ-ORDER-WIT/ledger DIVERGE were all absent from the capture. The r231/r233 rings only cover the transformer_mt window (6-7 GRID-WITs, 15 sema-bigcopy lines, all of the transformer); the probe's launches are outside the saved ring, so the witness absence is not yet attributable to the code. Two additions make the next capture self-contained: - RDW nrecs= launch_va=: one arming line per forwarded launch (budget 256) - a capture can never confuse 'witness did not run' with 'no recs'; probe-class launches must show nrecs>0. - A-TRACE, four labeled points for every 64 KB copy and every small launch (budgets 128/128): pt=P1 H2D source read (src_int4 as ints; expect 0 1 2 3) pt=P2 H2D destination right after the copy (dst_int4_after) pt=P3 engine-read point: for <=64-rec launches, the first recs' source-page content the copy-in stages (w0..15 per rec) pt=P4 D2H source read (the engine-authored page as ints) pt=P4R D2H host-side readback after the copy The probe A buffer is ints 0..16383; the first point where the pattern breaks is the bug site. Stats check for the elision class: r231's probe-window stats show copy_skipped=0 copy_soft=0 copy_fail=0 and no device-dst guard lines, so no forwarded/skip elision is in play in that window; the trace decides where the read/write split actually occurs. Build green. (cherry picked from commit 98bfc75410b214f7de3dfc6ef80bff76118ff14d) --- kernel/gsp_phys_booter.c | 40 ++++++++++++++++++++++++++++++++++++++++ kernel/gsp_sema_service.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 430b518..7766cb5 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -166,6 +166,8 @@ static u32 gsp_phys_gr_outwit_bi[GSP_PHYS_GR_OUTWIT_SLOTS]; static u32 gsp_phys_gr_outwit_n; static u32 gsp_phys_gr_alias_log; /* boot-wide alias-line budget */ static u32 gsp_phys_gr_recdump_budget; /* r233 REC-DUMP boot budget */ +static u32 gsp_phys_gr_rdw_budget; /* r234 RDW arming-line budget */ +static u32 gsp_phys_gr_atrace_budget; /* r234 A-TRACE boot budget */ bool gsp_phys_boot_enabled(void) { @@ -18727,6 +18729,18 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, qmd[4], qmd[5], qmd[8], qmd[12], qmd[13], qmd[14], qmd[15], qmd[17], qmd[18], qmd[19]); + /* + * r234 RDW arming witness: one line per launch with the rec count, + * so a capture missing REC-DUMP lines can never be confused with + * "the witness did not run" - probe-class launches must show + * nrecs>0 here. + */ + if (req->n_data && gsp_phys_gr_rdw_budget < 256u) { + gsp_phys_gr_rdw_budget++; + pr_info("vgsp-gr: RDW nrecs=%u launch_va=0x%llx\n", + req->n_data, req->push_va); + } + /* * REC-DUMP (r229): the probe-class launches (small data sets) get * their full rec table logged - every (va, hpa, reloc_va) the engine @@ -19561,6 +19575,32 @@ gr_page_unmapped: dcopied = gsp_phys_gr_fill_bounce(req, bounce_csum_in); pr_info("vgsp-gr: bounce copy-in: %u pages, %u skipped (pre-publish)\n", dcopied, dfailed); + /* + * r234 A-TRACE pt=P3 (engine-read point): small launches get + * the source-page content of their first recs - the exact + * bytes the copy-in stages and the engine will read. The probe + * A buffer is 16 pages of ints 0..16383 (w0=0 w1=1 w2=2 ...); + * any point in the pipeline where that pattern breaks names + * the bug site. + */ + if (req->n_data <= 64u && gsp_phys_gr_atrace_budget < 128u) { + u32 d; + + for (d = 0; d < req->n_data && d < 16u; d++) { + const u32 *pp = + (const u32 *)__va(req->data[d].hpa); + + if (!pp || gsp_phys_gr_atrace_budget >= 128u) + break; + gsp_phys_gr_atrace_budget++; + pr_info("vgsp: A-TRACE pt=P3 va=0x%llx hpa=0x%llx w0..15=%08x %08x %08x %08x %08x %08x %08x %08x | %08x %08x %08x %08x %08x %08x %08x %08x\n", + req->data[d].va, req->data[d].hpa, + pp[0], pp[1], pp[2], pp[3], pp[4], + pp[5], pp[6], pp[7], pp[8], pp[9], + pp[10], pp[11], pp[12], pp[13], + pp[14], pp[15]); + } + } if ((u64)req->n_data << 12 >= GSP_PHYS_GR_AUDIT_MIN) pr_info("vgsp: COPYAUDIT path=gr-bounce-copy-in va=0x%llx len=0x%llx done=0x%llx\n", req->data[0].va, (u64)req->n_data << 12, diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index d9f5895..b7290d4 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3136,6 +3136,7 @@ static void svc_pool_boot_store(u64 va, u64 pa, int ap); /* m168 */ static bool svc_dst_guard_hold(u64 va); /* m169b */ static bool svc_dst_guard_pending(u64 va); /* r231 */ static u32 svc_read_order_log; /* r231 budget */ +static u32 svc_atrace_log; /* r234 A-TRACE budget */ static int svc_pool_pa_lookup(u64 va, u64 *pa, int *ap) { @@ -5368,6 +5369,31 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total, total); pr_info("sema-bigcopy: src16=%16phN dst16_before=%16phN\n", sb, db); + /* + * r234 A-TRACE: one labeled line per 64 KB copy so the probe A + * upload/readback is greppable end-to-end. pt=P1 = H2D source + * read (the uploaded bytes as ints), pt=P4 = D2H source read + * (the engine-authored page as ints). The expected content is + * ints 0,1,2,3,... for the probe A buffer. + */ + if (total == 65536u && svc_atrace_log < 128u) { + u32 i0, i1, i2, i3, j0 = 0, j1 = 0, j2 = 0, j3 = 0; + + svc_atrace_log++; + memcpy(&i0, sb, 4); + memcpy(&i1, sb + 4, 4); + memcpy(&i2, sb + 8, 4); + memcpy(&i3, sb + 12, 4); + memcpy(&j0, db, 4); + memcpy(&j1, db + 4, 4); + memcpy(&j2, db + 8, 4); + memcpy(&j3, db + 12, 4); + pr_info("vgsp: A-TRACE pt=%s dst_va=0x%llx dst_pa=0x%llx dst_prov=%u | src_va=0x%llx src_pa=0x%llx src_prov=%u | src_int4=%d %d %d %d dst_int4_before=%d %d %d %d\n", + dst_shadow || dst_aperture == CE_APERTURE_VID ? + "P1" : "P4", + dst_orig, dst, dst_prov, src_orig, src, + src_prov, i0, i1, i2, i3, j0, j1, j2, j3); + } } /* @@ -5738,6 +5764,24 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total, } pr_info("sema-bigcopy: dst16_after=%16phN (dst_va=0x%llx pa=0x%llx)\n", da, dst_orig, dst); + /* + * r234 A-TRACE pt=P2/P4R: the destination content right after + * the copy - for H2D this is the landed upload (P2), for D2H + * the host-side readback result (P4R). + */ + if (total == 65536u && svc_atrace_log < 128u) { + u32 i0, i1, i2, i3; + + svc_atrace_log++; + memcpy(&i0, da, 4); + memcpy(&i1, da + 4, 4); + memcpy(&i2, da + 8, 4); + memcpy(&i3, da + 12, 4); + pr_info("vgsp: A-TRACE pt=%s dst_va=0x%llx dst_pa=0x%llx dst_int4_after=%d %d %d %d\n", + dst_shadow || dst_aperture == CE_APERTURE_VID ? + "P2" : "P4R", + dst_orig, dst, i0, i1, i2, i3); + } } if (gsp_sema_dbg && !src_shadow && !dst_shadow && -- cgit v1.2.3