diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index bcd8ac3..ba9d3da 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -5997,14 +5997,18 @@ static void svc_copy_snap_free(u64 dst, u64 src, size_t total, } /* - * r444: drop every snapshot still owned by one entry. A snapshot that was - * not consumed by the entry's own copy execution (the copy ran via the - * forwarded hardware path, or a post-execution re-decode re-captured the - * unchanged staging) has no future consumer once the entry's release is - * delivered - leaving it behind let a LATER entry whose copy shares the - * (dst,src,total) triple execute from the stale bytes. - */ -static void svc_copy_snap_free_owner(u32 owner_ch, u32 owner_idx) + * r456/r457: the snapshot lifecycle is capture-once -> free on the copy's + * own successful consumption (svc_copy) -> free on ring-slot reuse with a + * new push hash (svc_copy_snap_capture) -> free when a re-decode skips an + * already-done op (svc_run_ops) -> TTL. The old per-entry owner free was + * removed from every opdef_clear caller: an entry whose release was + * delivered can still be REPLAYED (the pin-batch rewind) with its copy + * still owed, and freeing at that point let the replay re-capture the + * driver's refilled ping-pong staging (the r457 mode-C b1 H2D wrote b2's + * bytes into db1). A stale snapshot can only ever serve its own + * (ch, idx, hash) owner, so the r444 cross-entry poisoning stays closed. + */ +static void __maybe_unused svc_copy_snap_free_owner(u32 owner_ch, u32 owner_idx) { u32 i; @@ -15907,28 +15911,28 @@ static void svc_opdef_clear(struct svc_opdef_ent *e, u32 caller) e->n ? e->rel[0].payload : 0u); } /* - * r444: the entry is being consumed; no retry can need its - * staging snapshot any more (see svc_copy_snap_free_owner). - * - * r456: EXCEPT on the APPLY path. The apply runs at the head of a - * re-decode pass of an entry whose copy is still held for its - * operand pins; the pass's own op execution (which consumes the - * snapshot on success) follows the apply. Freeing here destroyed - * the pipeline-order snapshot before it could ever be read and - * the next pass's guard re-capture then read the driver's - * REFILLED ping-pong staging - the r455 operand-shift: the a1 H2D - * executed ~3 s after its push with a2's bytes (owner - * 0x5c00005c/0/6076682fa76b8792, snapshot first4 flipped from - * 00000000 3f000000... to 00000000 3e000000... across retries; - * dst16_after=000000000000003e0000803e0000c03e proves the a2 - * pattern landed in da1's page). The snapshot now survives the - * retries and is consumed (and freed) by the copy that finally - * executes; svc_copy_snap_free_owner still runs on every genuine - * consume path (FINISH/FLUSH/DROP/STALE/COUNTED/SWEEP/STOP) and - * the TTL covers the rest. + * r456/r457: the snapshot lifecycle is now "capture once, consume + * on the copy's success, evict on ring-slot reuse, TTL". Every + * opdef_clear caller can still re-decode the entry: + * - APPLY (0): the pass's own op execution (which consumes the + * snapshot on success) follows the apply; + * - FINISH (1): the entry can be REPLAYED after a consume (the + * pin-batch rewind replays entries while mappings stream in), + * and an owed copy still needs the pipeline-order bytes; + * - FLUSH (2): the op stays skipped this pass but a later replay + * may run it. + * The r457 mode-C evidence: the b1 H2D's snapshot was captured at + * 191607.816388 with b1's bytes (first4=00000000 3e800000 ...), + * FINISH freed it on the entry's consume, the rewind replay + * re-captured at 191608.798838 from the REFILLED staging + * (first4=00000000 3d800000 ... = b2) and the deferred execution + * wrote b2's bytes into db1 (dst16_after=000000000000803d...). + * The r444 leak the old free guarded against is already covered + * by the owner key (a stale snapshot can only ever serve its own + * (ch, idx, hash)), the slot-reuse eviction in + * svc_copy_snap_capture, the ops_done skip free in svc_run_ops + * and the 30 s TTL. */ - if (e->active && caller != SVC_OPDEF_CLR_APPLY) - svc_copy_snap_free_owner(e->h_object, e->entry_idx); memset(e, 0, sizeof(*e)); } |
