summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 17:04:20 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 17:04:20 -0400
commit7132b6041ad7817fe3a9b49e7b43e94486eebf8c (patch)
treeaa0293fa45d7c64ee4dccbf3f4ed072c63233f6a
parentbd5b4290716765c46f50970dafe6b546c1f9d86f (diff)
parenta766cc1beff625c5577f2d70630a17e2e229d02a (diff)
downloadopen-iov-7132b6041ad7817fe3a9b49e7b43e94486eebf8c.tar.gz
open-iov-7132b6041ad7817fe3a9b49e7b43e94486eebf8c.zip
vgsp: restore reproducible green CUDA (ISSUE-0001) - BAR1 exposure, walk-pin and publish fixes
- Revert m143's BAR1 exposure: report the physical aperture size (256MB) again. Every post-m143 build reported BAR1=512MB and stalled the guest in its first cudaMalloc; the m140 green reference reported 256MB. barprobe-r2 (this tree) is green: VADD n=32768 bad=0, STATUS OK ~10s. - Revert the FORENSICS-grv6-ring walk-authoritative GR ring pin (fix A): it gated the guest's GR pushes on every boot since (no-push class). - Restore the end-of-pass GR counter publish with the pass-computed put (m140 behavior); the H3-only early publish read put=0 from the USERD. Probe branch: probe/no-walkpin (b1694f6a, 82404ad9, a766cc1b).
-rw-r--r--kernel/bar_init.c23
-rw-r--r--kernel/gsp_sema_service.c77
2 files changed, 32 insertions, 68 deletions
diff --git a/kernel/bar_init.c b/kernel/bar_init.c
index b5703d8..6515613 100644
--- a/kernel/bar_init.c
+++ b/kernel/bar_init.c
@@ -57,15 +57,22 @@ int nv_vgpu_bar_init(struct nv_vgpu_device *vgpu)
if (bar_addr && bar_size) {
vgpu->bars[1].gpa = bar_addr;
/*
- * m143 (1.0 VRAM sizes): expose the EMULATED framebuffer size as
- * BAR1's size, not the physical aperture. The guest derives its
- * BAR1 from the VFIO region info (config-space BAR writes are
- * ignored) and every GSCI/PFB report already carries
- * fb_emul_size; leaving the physical 256 MB here made 1G/2G types
- * tell the guest one size and expose another (the shadow is
- * fb_emul_size, so vidmem bounds and mmap math must match it).
+ * PROBE (2026-10-08, ISSUE-0001): m143 exposed the emulated
+ * framebuffer size (512 MB for the turing type) as BAR1; every
+ * build since the green m140 reference reports BAR1=512MB to
+ * the guest and the client spins in its first cudaMalloc with
+ * both counter families written (guest RAM verified). The m140
+ * green run reported BAR1=256MB (physical aperture) with the
+ * same 512 MiB shadow and reached VADD. Restore the physical
+ * size here as a single-variable probe: if this goes green,
+ * m143's exposure is the stall trigger and the 1G/2G feature
+ * must make the guest work with the larger aperture instead of
+ * assuming it does. (m143: expose the EMULATED framebuffer size
+ * as BAR1's size, not the physical aperture - the guest derives
+ * its BAR1 from the VFIO region info and vidmem bounds/mmap
+ * math must match the shadow.)
*/
- vgpu->bars[1].size = nv_vgpu_fb_emul_size(vgpu);
+ vgpu->bars[1].size = bar_size;
/* Emulated vidmem: a dedicated host-RAM buffer backing the guest's
* VRAM aperture. Do NOT map the host GPU's real BAR1 - guest VRAM
* accesses must hit our own clean buffer, not the (broken) host
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index d3d88e0..7837d32 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -8013,7 +8013,6 @@ unsigned gsp_sema_ce_grace_ms = 25000;
unsigned gsp_sema_push_hold_ms = 2500;
static unsigned long svc_gr_ring_tried; /* ranks that got a diagnostic line */
-static unsigned long svc_gr_walk_dbg; /* ranks that got a walk-verdict line */
static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
struct svc_channel *ch)
@@ -8218,11 +8217,9 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
{
u64 wpa = 0;
int wap = SVC_APERTURE_SYS;
- int wrc;
- u8 wprobe[8];
- wrc = svc_lookup_trusted(vgpu, ch->gpfifo_va, &wpa, &wap);
- if (!wrc && svc_gr_ring_candidate(vgpu, ch, wpa, wap, &va, &len, &put,
+ if (!svc_lookup_trusted(vgpu, ch->gpfifo_va, &wpa, &wap) &&
+ svc_gr_ring_candidate(vgpu, ch, wpa, wap, &va, &len, &put,
&get)) {
svc_pin_store(ch->gpfifo_va, wpa, wap);
svc_lat_store(ch->gpfifo_va, wpa, wap);
@@ -8237,54 +8234,6 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
wpa, wap, va, len, put, get);
return;
}
- /*
- * FORENSICS-grv6-ring (SA-RING fix A): the trusted walk is
- * driver-published truth, but the candidate gate rejects it
- * while the ring page is still empty (grv6: entry0 e0/e1=0
- * and the USERD probe rc=-11, so the ring NEVER resolved and
- * no GR push was ever decoded). Latch the walked translation
- * when the page is at least READABLE, without marking the
- * ring done: the pump then has a real target, svc_chan_userd
- * can latch the USERD as soon as it shows activity, and the
- * next autopin pass upgrades to the full pin once entry0
- * lands. A bad aperture cannot be latched (readability gate);
- * ring_done stays unset so the content paths still run.
- */
- if (!wrc &&
- !svc_read_ap(vgpu, wpa, wap, wprobe, sizeof(wprobe))) {
- svc_pin_store(ch->gpfifo_va, wpa, wap);
- svc_lat_store(ch->gpfifo_va, wpa, wap);
- ch->userd_pa = wpa + SVC_GR_USERD_OFF;
- ch->userd_as = wap;
- if (gsp_sema_dbg &&
- !test_and_set_bit(ch->gr_index, &svc_gr_walk_dbg))
- pr_info("sema-chan: GR walk-pinned (await content) h=0x%x rank=%u va=0x%llx -> pa=0x%llx ap=%d\n",
- ch->h_object, ch->gr_index,
- ch->gpfifo_va, wpa, wap);
- }
- /*
- * FORENSICS-grv6 (SA-FORENSICS-2): the H1 branch used to log
- * only successes, so a walk miss and a candidate reject were
- * indistinguishable. One verdict line per rank (dbg-gated).
- */
- if (gsp_sema_dbg &&
- !test_and_set_bit(ch->gr_index, &svc_gr_walk_dbg)) {
- if (wrc) {
- pr_info("sema-chan: GR walk miss h=0x%x rank=%u va=0x%llx rc=%d\n",
- ch->h_object, ch->gr_index,
- ch->gpfifo_va, wrc);
- } else {
- u64 r0 = 0, r1 = 0;
-
- (void)svc_read_ap(vgpu, wpa, wap, &r0,
- sizeof(r0));
- (void)svc_read_ap(vgpu, wpa + 8, wap, &r1,
- sizeof(r1));
- pr_info("sema-chan: GR walk hit/reject h=0x%x rank=%u va=0x%llx pa=0x%llx ap=%d w0=0x%llx w1=0x%llx\n",
- ch->h_object, ch->gr_index,
- ch->gpfifo_va, wpa, wap, r0, r1);
- }
- }
}
if (!test_and_set_bit(ch->gr_index, &svc_gr_ring_tried)) {
@@ -12772,14 +12721,22 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
* re-register: once per pass is enough and the derivation is
* not free.
*
- * H3 (FORENSICS-v2): GR channels publish in the safety-net
- * block at the top of the pass - the early `continue`s above
- * make this call unreachable exactly when the ring or USERD
- * cannot be read, which is the case the publish must still
- * cover. Keep this site for the CE channels only, so a GR
- * pass does not publish twice.
+ * REGRESSION FIX (2026-10-08): this site published every
+ * channel in the m140 green design and GR clients advanced
+ * (green: counter publish val=put writes). The H3 change
+ * restricted it to CE and moved GR to the safety-net early
+ * call, which reads GP_PUT from the snapshot USERD and
+ * returned 0 on the GR channels while the pass's own put
+ * (probed/read below) was 1 - so GR never published, the
+ * client's tracker poll never advanced, and victory_mail spun
+ * at 100% CPU inside the first cudaMalloc (wchan=0). Publish
+ * GR here with the pass-computed put again; the early
+ * safety-net call stays as the fallback for passes that
+ * early-`continue` (H3's coverage), and both are monotonic
+ * (val <= counter_last -> return), so a pass that runs both
+ * does not write twice.
*/
- if (!held && ch->engine_type)
+ if (!held)
svc_counter_publish(vgpu, ch, put);
spin_lock_irqsave(&svc.chan_lock, flags);