summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-22 18:03:07 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-22 18:03:07 -0400
commit4d4bb3ca0f8c23b8a8bd9893a0f0b4ebbfddd7a8 (patch)
tree2705eaf22082a1115937e8553eb713d66072bde5
parent203d3ff5378d4825e039b7cbd9a15adca5aea867 (diff)
downloadopen-iov-4d4bb3ca0f8c23b8a8bd9893a0f0b4ebbfddd7a8.tar.gz
open-iov-4d4bb3ca0f8c23b8a8bd9893a0f0b4ebbfddd7a8.zip
r496e the X NOP push: all-zero accepted on content-scanned channels; no capture holds for their entries
The driver's __nvPushTestPushBuffer writes one zero dword (NVA06F_DMA_NOP) and waits for GP_GET to follow GP_PUT. The method-stream plausibility gate rejects an all-zero buffer (it parses as zero methods), so the entry fell into the unreadable/rescue path and the GR no-capture hold - the DMA sanity test could never pass. For channels whose ring was found by the RAM content scan (kernel-RM sysmem 3D channels), model them as consume-and-apply- releases: accept an all-zero NOP push, and skip the no-capture hold (these pushes are not compute launches; holding them 6 s per entry cannot help).
-rw-r--r--kernel/gsp_sema_service.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index c8987b7..d20ad92 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -441,6 +441,16 @@ struct svc_channel {
u8 gr_ram_passes; /* slices walked so far */
bool gr_ram_logged; /* one discovery line per channel */
/*
+ * r496e: true when the ring was found by the RAM content scan (a
+ * kernel-RM sysmem channel - the X/GL 3D channel). Such a channel's
+ * pushes are 2D/3D method streams the emulation does not execute;
+ * the correct model is consume-and-apply-releases: no QMD capture,
+ * no launch forward, no no-capture hold. Also allows an all-zero
+ * NOP push (the driver's pushbuffer sanity test writes exactly one
+ * zero dword) to be consumed as the no-op it is.
+ */
+ bool gr_ram_ring;
+ /*
* r496b: the FB-scan USERD (see svc_userd_fb_scan). Latched when the
* registered/ring-derived candidates all fail; the scan validates the
* hit against the ring entries the put claims, so a foreign channel's
@@ -14575,8 +14585,33 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
SVC_APERTURE_SYS);
}
ch->gr_ram_logged = true;
+ ch->gr_ram_ring = true;
set_bit(ch->gr_index, &svc_gr_ring_done);
svc_ring_n++;
+ /*
+ * Persist the latch immediately: a later stalled
+ * path in this pass may `continue` past the
+ * end-of-pass write-back, and the next pass's
+ * snapshot must carry gr_ram_ring (the zero-NOP
+ * exception and the no-capture-hold skip key on
+ * it).
+ */
+ {
+ unsigned long flags2;
+ int i2;
+
+ spin_lock_irqsave(&svc.chan_lock, flags2);
+ for (i2 = 0; i2 < SVC_MAX_CHANNELS; i2++)
+ if (svc.chan[i2].valid &&
+ svc.chan[i2].vgpu == vgpu &&
+ svc.chan[i2].h_object ==
+ ch->h_object) {
+ svc.chan[i2].gr_ram_ring = true;
+ svc.chan[i2].gr_ram_logged = true;
+ break;
+ }
+ spin_unlock_irqrestore(&svc.chan_lock, flags2);
+ }
pr_info("sema-chan: GR ring h=0x%x rank=%u found by RAM content scan va=0x%llx -> pa=0x%llx (allocation window pinned; entry/push reads resolve through it)\n",
ch->h_object, ch->gr_index, ch->gpfifo_va,
hit_pa);
@@ -21163,7 +21198,20 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
injected = (svc_ipin_lookup(va, &ipa,
&iap) == 0);
- if (!svc_method_stream_plausible(pb, len)) {
+ /*
+ * r496e: an all-zero push on a
+ * content-scanned-ring channel is the
+ * driver's NOP sanity push (one zero
+ * dword - NVA06F_DMA_NOP), not a bad
+ * translation: accept it and let the
+ * decode find no ops.
+ */
+ bool zero_nop = ch->gr_ram_ring &&
+ len >= 4 &&
+ !memchr_inv(pb, 0, len);
+
+ if (!svc_method_stream_plausible(pb, len) &&
+ !zero_nop) {
svc.false_trans++;
if (injected) {
u8 *fb = kmalloc(len,
@@ -21982,6 +22030,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
jiffies;
}
if (gsp_sema_gr_nocap_hold_ms &&
+ !ch->gr_ram_ring &&
time_before(jiffies,
ch->gr_nocap_since +
msecs_to_jiffies(
@@ -22731,6 +22780,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc.chan[k].gr_ram_cursor = ch->gr_ram_cursor;
svc.chan[k].gr_ram_passes = ch->gr_ram_passes;
svc.chan[k].gr_ram_logged = ch->gr_ram_logged;
+ svc.chan[k].gr_ram_ring = ch->gr_ram_ring;
svc.chan[k].userd_scans = ch->userd_scans;
svc.chan[k].logged = ch->logged;
svc.chan[k].logged_expected = ch->logged_expected;