diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-18 14:53:33 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-18 14:53:45 -0400 |
| commit | 577fd4124a2de645613976246444c3bd0bb1a699 (patch) | |
| tree | 6472cf20135a2b3f28109895b6037302e30f6a67 /kernel | |
| parent | 11c141c446bae4ba2a193cd6a709819ec125b78c (diff) | |
| download | open-iov-577fd4124a2de645613976246444c3bd0bb1a699.tar.gz open-iov-577fd4124a2de645613976246444c3bd0bb1a699.zip | |
vgsp: fail4 r227 - INPUT-ALIAS-WIT rec census + RETIRE-WIT rec-array witness
r227 verdict inputs: GRID-WIT == the guest's own geometry for every kernel
(gemm_nn w12=0x10 w13=0x4, gemm_nt w12=0x4, softmax w12=0x40, block dims in
w18/w19) - no QMD geometry emission bug; the old consecutive-pair IN-ALIAS
stayed silent.
Two new witnesses for the next capture:
- INPUT-ALIAS-WIT: per-launch census of the copy-in recs (the exact
VA -> HPA -> content triples the engine reads, inputs included; the fill
already covers them as recs). Every non-zero rec is compared against the
last 64: distinct VA -> same HPA is the resolver-aliasing smoking gun;
distinct HPA with equal content is the upstream-write-clone class. Zero
pages excluded on both sides. Replaces the consecutive-only check.
- RETIRE-WIT: one line per launch at the retirement wait with n_data,
n_tracked and the first/last recs' va/reloc_va/bi. r227's numbers are
impossible under this source (retire n_tracked 4/4/4/1/1/16/16 vs
copy-in/copy-out 1482/1418/1354/913/864/882/1290 recs for the same
launch), so either the rec array genuinely aliases reloc VAs at run time
or the deployed module differs from this tree; RETIRE-WIT shows which in
one line (sequential in-region rels + n_data=1482 with n_tracked=4 would
prove the former).
Logging-only; no behaviour change; greens safe. Build green.
(cherry picked from commit 1dbde7967bda4ba51dadf8a96e8aeaacc44c5575)
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index e336247..d32d588 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -165,7 +165,6 @@ static u64 gsp_phys_gr_outwit_va[GSP_PHYS_GR_OUTWIT_SLOTS]; 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_in_alias_log; bool gsp_phys_boot_enabled(void) { @@ -17660,6 +17659,23 @@ gsp_phys_gr_output_retire_wait(const struct gsp_phys_gr_submit *req, if (!req->n_data) return 0; n_all = gsp_phys_gr_scan_pages(req, csum_in, n_tracked, NULL); + /* + * RETIRE-WIT (r227): the r227 capture shows n_tracked far below the + * copy-in/copy-out rec counts for the same launch (4 tracked vs 1482 + * written back) - either the rec array genuinely aliases reloc VAs + * mid-launch or the observed kernel differs from this source. One + * line per launch proves which: n_data, the unique-bi count, and the + * first/last recs' va/reloc_va/bi must be sequential and in-region + * for a healthy launch. + */ + if (gsp_phys_gr_copywit_enabled()) + pr_info_ratelimited("vgsp-gr: RETIRE-WIT n_data=%u n_tracked=%u first_va=0x%llx first_rel=0x%llx first_bi=%u last_va=0x%llx last_rel=0x%llx last_bi=%u\n", + req->n_data, n_tracked ? *n_tracked : 0, + req->data[0].va, req->data[0].reloc_va, + gsp_phys_gr_data_bi(req->data[0].reloc_va), + req->data[req->n_data - 1].va, + req->data[req->n_data - 1].reloc_va, + gsp_phys_gr_data_bi(req->data[req->n_data - 1].reloc_va)); if (!n_all) return 0; for (iter = 0; iter < 300u; iter++) { @@ -17757,6 +17773,24 @@ static inline bool gsp_phys_gr_page_all_zero(u32 csum, const u8 *p) } /* + * COPYWIT r22x INPUT-ALIAS-WIT: per-launch census of the copy-in recs (the + * exact VA -> HPA -> content triples the engine will read for this launch, + * inputs included). Each new non-zero rec is compared against the last + * GSP_PHYS_GR_IN_CENSUS recs: + * - distinct VA resolving to the SAME host page (hpa collision) is the + * resolver-aliasing smoking gun: several guest pages served by one host + * page would replicate those rows through every consumer (the observed + * band-replication signature); + * - distinct HPA with identical content is the upstream-write-clone class + * (an H2D that landed on one page, or guest pages that genuinely hold + * the same bytes). + * Zero pages are excluded on both sides (fresh-client zero runs are not + * aliasing evidence). Bounded boot-wide; same single-inflight discipline. + */ +#define GSP_PHYS_GR_IN_CENSUS 64u +static u32 gsp_phys_gr_in_census_log; + +/* * m153: fill the bounce window from the request's guest pages and capture a * per-page checksum baseline. Used before the first publish and again before * every outcome retry (a mis-executing first attempt can leave stale or @@ -17767,9 +17801,13 @@ static u32 gsp_phys_gr_fill_bounce(const struct gsp_phys_gr_submit *req, u32 *csum_in) { struct gsp_phys_boot_chunk *dchunk = gsp_phys_gr_data_chunk(); + struct { + u64 va; + u64 hpa; + u32 csum; + } census[GSP_PHYS_GR_IN_CENSUS]; + u32 n_census = 0; u32 di, copied = 0; - u64 prev_va = 0, prev_hpa = 0; - u32 prev_csum = 0; for (di = 0; di < req->n_data; di++) { u32 bi = gsp_phys_gr_data_bi(req->data[di].reloc_va); @@ -17791,33 +17829,38 @@ static u32 gsp_phys_gr_fill_bounce(const struct gsp_phys_gr_submit *req, csum += get_unaligned_le32(dst + ci); csum_in[bi] = csum; zero = gsp_phys_gr_page_all_zero(csum, dst); - /* - * IN-ALIAS-WIT (COPYWIT r224 follow-up): two consecutive tracked - * recs whose guest content is identical prove a replicated INPUT - * region (one page served for many VAs). The HPAs tell the two - * classes apart: equal hpa = the resolver served ONE page for - * several VAs (resolution aliasing); different hpa = the guest - * pages genuinely hold the same bytes (upstream write aliasing, - * e.g. an H2D that landed on one page). Bounded boot-wide; all- - * zero pages are excluded on both sides (r226: a fresh client's - * zero runs are not aliasing evidence). - */ - if (prev_va && !zero && csum == prev_csum && - gsp_phys_gr_copywit_enabled() && - gsp_phys_gr_in_alias_log < 12) { - gsp_phys_gr_in_alias_log++; - pr_info_ratelimited("vgsp-gr: IN-ALIAS-WIT va=0x%llx hpa=0x%llx prev_va=0x%llx prev_hpa=0x%llx csum=0x%08x (%s)\n", - req->data[di].va, - req->data[di].hpa, prev_va, - prev_hpa, csum, - prev_hpa == req->data[di].hpa ? - "resolver served one page for many VAs" : - "distinct pages, identical contents"); - } - if (!zero) { - prev_va = req->data[di].va; - prev_hpa = req->data[di].hpa; - prev_csum = csum; + if (!zero && gsp_phys_gr_copywit_enabled()) { + u32 j; + + for (j = 0; j < n_census; j++) { + if (census[j].hpa == req->data[di].hpa && + census[j].va != req->data[di].va) { + if (gsp_phys_gr_in_census_log < 24) { + gsp_phys_gr_in_census_log++; + pr_info("vgsp-gr: INPUT-ALIAS-WIT kind=hpa-collision va=0x%llx hpa=0x%llx prev_va=0x%llx (two guest pages served by one host page)\n", + req->data[di].va, + req->data[di].hpa, + census[j].va); + } + } else if (census[j].csum == csum && + census[j].hpa != req->data[di].hpa) { + if (gsp_phys_gr_in_census_log < 24) { + gsp_phys_gr_in_census_log++; + pr_info("vgsp-gr: INPUT-ALIAS-WIT kind=content-clone va=0x%llx hpa=0x%llx prev_va=0x%llx prev_hpa=0x%llx csum=0x%08x\n", + req->data[di].va, + req->data[di].hpa, + census[j].va, + census[j].hpa, + csum); + } + } + } + if (n_census < GSP_PHYS_GR_IN_CENSUS) { + census[n_census].va = req->data[di].va; + census[n_census].hpa = req->data[di].hpa; + census[n_census].csum = csum; + n_census++; + } } copied++; } |
