summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index bc0ca74..e336247 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -17737,6 +17737,26 @@ static void gsp_phys_gr_page_spot_check(const u8 *dst, const u8 *src,
}
/*
+ * COPYWIT r226 zero filter: an all-zero page is never a meaningful alias
+ * partner. A fresh client's fill stages long runs of zero pages
+ * (uninitialized cudaMalloc buffers), and consecutive zero pages produced
+ * the IN-ALIAS-WIT false positives of the r226a green run (csum=0x00000000
+ * sequences). A page counts as zero only when its csum is zero AND every
+ * word is zero (csum==0 alone can hide cancelling contents).
+ */
+static inline bool gsp_phys_gr_page_all_zero(u32 csum, const u8 *p)
+{
+ u32 i;
+
+ if (csum)
+ return false;
+ for (i = 0; i < GSP_PHYS_PAGE_SIZE; i += 4)
+ if (get_unaligned_le32(p + i))
+ return false;
+ return true;
+}
+
+/*
* 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
@@ -17748,7 +17768,7 @@ static u32 gsp_phys_gr_fill_bounce(const struct gsp_phys_gr_submit *req,
{
struct gsp_phys_boot_chunk *dchunk = gsp_phys_gr_data_chunk();
u32 di, copied = 0;
- u64 prev_va = 0;
+ u64 prev_va = 0, prev_hpa = 0;
u32 prev_csum = 0;
for (di = 0; di < req->n_data; di++) {
@@ -17756,6 +17776,7 @@ static u32 gsp_phys_gr_fill_bounce(const struct gsp_phys_gr_submit *req,
const u8 *src;
u8 *dst;
u32 ci, csum = 0;
+ bool zero;
if (bi == GSP_PHYS_GR_DATA_BI_NONE || !req->data[di].hpa)
continue;
@@ -17769,20 +17790,35 @@ static u32 gsp_phys_gr_fill_bounce(const struct gsp_phys_gr_submit *req,
for (ci = 0; ci < GSP_PHYS_PAGE_SIZE; ci += 4)
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). Logged with both VAs so
- * the source can be named; bounded boot-wide.
+ * 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 && csum == prev_csum && gsp_phys_gr_copywit_enabled() &&
+ 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 prev_va=0x%llx csum=0x%08x (identical guest page content)\n",
- req->data[di].va, prev_va, csum);
+ 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;
}
- prev_va = req->data[di].va;
- prev_csum = csum;
copied++;
}
dma_wmb();
@@ -18629,6 +18665,25 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
}
/*
+ * GRID-WIT (r226): the engine reads CTA geometry from this verbatim
+ * QMD copy, and the copy-out witnesses show the corruption of the
+ * failing clients starts exactly at a CTA-band boundary (rows >= 16
+ * replicate one tile). Dump the geometry-relevant words once per
+ * launch so the next capture proves what raster/thread dimensions the
+ * engine actually sees and lets them be compared against the client's
+ * own launch config: w12 = CTA_RASTER_WIDTH (gridDim.x),
+ * w13.lo = CTA_RASTER_HEIGHT (gridDim.y), w13.hi = DEPTH (z),
+ * w14/w15 = raster resume W/H, w18.hi = CTA_THREAD_DIMENSION0
+ * (blockDim.x), w19.lo/hi = DIM1/DIM2 (blockDim.y/z), w18.lo =
+ * QMD_VERSION/MAJOR nibbles. w4/w5/w8/w17: PCAS/cache-control,
+ * prefetch pair low word, shared-memory size.
+ */
+ if (gsp_phys_gr_copywit_enabled())
+ pr_info("vgsp-gr: GRID-WIT w4=%08x w5=%08x w8=%08x w12=%08x w13=%08x w14=%08x w15=%08x w17=%08x w18=%08x w19=%08x\n",
+ qmd[4], qmd[5], qmd[8], qmd[12], qmd[13], qmd[14],
+ qmd[15], qmd[17], qmd[18], qmd[19]);
+
+ /*
* Pages: Tier 1 maps the resolved HPA at the guest VA; a page without
* a usable Tier-1 mapping falls to Tier 2 when captured inline bytes
* cover it and a QMD pointer pair names it (the pair is rewritten to
@@ -20685,9 +20740,13 @@ gr_page_unmapped:
* OUT-ALIAS-WIT: identical first 8 bytes as
* an earlier changed page of this launch =
* the replicated-tile structure, with both
- * recs named.
+ * recs named. r226: all-zero pages are
+ * excluded on both sides (the fresh-client
+ * fill stages zero runs; they are not alias
+ * evidence).
*/
- if (gsp_phys_gr_copywit_enabled()) {
+ if (gsp_phys_gr_copywit_enabled() &&
+ !gsp_phys_gr_page_all_zero(csum, src)) {
u32 wi;
for (wi = 0; wi < gsp_phys_gr_outwit_n;