diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 01:00:25 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 01:00:25 -0500 |
| commit | b9213c57222026eacc41dbcec079190c27f7e111 (patch) | |
| tree | 6706ad6b99e9d5827aeaea9795f7c4cbce5f5397 /kernel | |
| parent | 770d6b4af7f44acc104c6149b9c473de1db607e7 (diff) | |
| download | open-iov-b9213c57222026eacc41dbcec079190c27f7e111.tar.gz open-iov-b9213c57222026eacc41dbcec079190c27f7e111.zip | |
vgsp: refuse DDX-family garbage USERD candidates (get>put) and bound the speculative CONFIRM jump
Wall (a) garbage-admission fix, validated c190-c194 (rich args + tick):
- svc_gr_ram_userd_scan and the FB shape scan (svc_chan_userd) now refuse
get > put for the DDX family (svc_userd_ddx_family), dropping the
entries>1024 exemption that admitted c181's 'put=1 get=288190567' block;
bounded refusal logs ('RAM scan REFUSES ...', 'userdp ... REFUSES fb ...
(DDX get>put; c181 garbage class)').
- The pump's speculative CONFIRM bounds a non-wrap DDX (non-kick) forward PUT
jump to gpfifo_entries/2 (mirrors the wrap bound); a runaway jump like
c181's 'put 1 -> 1170688059' now falls to the DEFERRED/REJECT ladder
('forward PUT jump REFUSED ...'). Kick any-step and wrap paths unchanged;
SYS/CE/UVM untouched.
Receipts (5 cycles): 146 refusal lines (80 RAM, 66 FB), ZERO huge-jump
confirms (all 16 confirms are real small steps), real blocks serving 25+24
submissions from pristine fb 0x8f0000 and RAM 0x11ae6e000. Residual wall
(a): a same-pass re-probe switch to a frozen lookalike (c190) and a late
'Failed to idle DMA' at 60-130 s of X life; gl_frames still reads black
(px0=0, ~12 s/frame) in the windows it ran (c193/c194).
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 96 |
1 files changed, 88 insertions, 8 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 6f4e387..9e0f3f4 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -27027,6 +27027,18 @@ static bool svc_ce_declared_userd(struct nv_vgpu_device *vgpu, */ static u32 svc_foreign_userd_skip_log; +/* + * CONT.466 (wall (a) clause 1/2): bounded refusal witnesses for the + * DDX-family garbage class. c181 admitted a SYS block put=1 get=288190567 + * (the entries>1024 exemption let get>put through) and the pump then + * CONFIRMED a block whose PUT jumped 1 -> 1170688059. The RAM scan, the FB + * shape scan and the pump's jump judge each log the first refusals so the + * next cycle's receipts name the gate that held. + */ +static u32 svc_userd_ddx_ramget_log; +static u32 svc_userd_ddx_fbget_log; +static u32 svc_userd_ddx_jump_log; + static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, u64 ring_pa, int ring_ap, u32 *put, u32 *get, int rrc) { @@ -27591,12 +27603,31 @@ ce_fb_scan: * CE control pages also carry a GPU-owned GET, * but bound it to one ring so a garbage pair * (r1660: put=2880 get=188746560) cannot pass. */ - if (!hp || hp > ch->gpfifo_entries || - (hg > hp && - (ch->engine_type ? - hg > hp + ch->gpfifo_entries : - ch->gpfifo_entries <= 1024))) + if (!hp || hp > ch->gpfifo_entries) + continue; + /* + * CONT.466 (wall (a) clause 1): the DDX family + * must satisfy get <= put. The entries>1024 + * exemption exists for large kernel rings whose + * GPU-owned GP_GET is uninitialised, but it also + * admitted garbage (c171: fb 0x960000 put=1 + * get=917535) that the pump then confirmed. + */ + if (hg > hp && + (ch->engine_type ? + hg > hp + ch->gpfifo_entries : + (svc_userd_ddx_family(ch) || + ch->gpfifo_entries <= 1024))) { + if (!ch->engine_type && + svc_userd_ddx_family(ch) && + svc_userd_ddx_fbget_log < 16) { + svc_userd_ddx_fbget_log++; + pr_info("sema-chan: userdp h=0x%x REFUSES fb 0x%llx put=%u get=%u (DDX get>put; c181 garbage class)\n", + ch->h_object, off, hp, + hg); + } continue; + } gate_n++; /* * CONT.438: the page-ownership gate. A block @@ -31073,9 +31104,30 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu, * pump's confirm/reject) carry the ownership proof. */ if (!hp || - hp > (kick || entries > 1024 ? 0x100000 : 8) || - (hg > hp && entries <= 1024)) + hp > (kick || entries > 1024 ? 0x100000 : 8)) continue; + /* + * CONT.466 (wall (a) clause 1): the DDX family must + * satisfy get <= put like every small ring. The + * entries>1024 exemption (large kernel rings with an + * uninitialised GPU-owned GP_GET) admitted garbage + * here (c181: pa=0x1020f8600 put=1 get=288190567 on + * entries=8192) which the pump then confirmed; the + * DDX tracker wait timed out and Xorg died on + * RM-local 0x51. The kick watch loop already refuses + * hg > hp, so this only aligns the content scan. + */ + if (hg > hp && + (entries <= 1024 || svc_userd_ddx_family(ch))) { + if (svc_userd_ddx_family(ch) && + svc_userd_ddx_ramget_log < 16) { + svc_userd_ddx_ramget_log++; + pr_info("sema-chan: GR USERD h=0x%x rank=%u RAM scan REFUSES pa=0x%llx put=%u get=%u (DDX get>put; c181 garbage class)\n", + ch->h_object, ch->gr_index, + gpa + o, hp, hg); + } + continue; + } { u32 z = 0, zi; @@ -44945,10 +44997,38 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * h=0x1000013 legitimately wrapped 65536 -> 12 and * the raw compare rejected the live block; see * svc_userd_put_wrap(). + * + * CONT.466 (wall (a) clause 2): a forward jump is + * progress only within half the ring. c181's garbage + * block read put=1 at adoption and put=1170688059 at + * the next pass; "any forward movement" confirmed it + * and the DDX tracker timed out on RM-local 0x51. + * Bound the raw step for the DDX family (the kick + * lane's free-running counter keeps the any-step + * rule): a jump past entries/2 is not a step, it + * falls through to the reprobe/defer/reject ladder + * so the scan re-adopts. */ stepped = wrap ? (wstep && wstep <= ch->gpfifo_entries / 2) : - put > ch->gr_ram_userd_latch_put; + (put > ch->gr_ram_userd_latch_put && + (!(svc_userd_ddx_family(ch) && !kfam) || + (ch->gpfifo_entries >= 2 && + put - ch->gr_ram_userd_latch_put <= + ch->gpfifo_entries / 2))); + if (!stepped && !wrap && !kfam && + svc_userd_ddx_family(ch) && + ch->gpfifo_entries >= 2 && + put > ch->gr_ram_userd_latch_put && + put - ch->gr_ram_userd_latch_put > + ch->gpfifo_entries / 2 && + svc_userd_ddx_jump_log < 16) { + svc_userd_ddx_jump_log++; + pr_info("sema-chan: GR USERD h=0x%x pa=0x%llx forward PUT jump REFUSED (put %u -> %u ent %u > half ring; c181 garbage class)\n", + ch->h_object, ch->userd_pa, + ch->gr_ram_userd_latch_put, put, + ch->gpfifo_entries); + } if (stepped) { ch->gr_ram_userd_confirmed = true; ch->gr_ram_userd_defers = 0; |
