diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 46 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.c | 36 |
2 files changed, 79 insertions, 3 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index f083c99..72cda10 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -17302,6 +17302,17 @@ gr_page_unmapped: le64_to_cpu(pv[s + 2]), le64_to_cpu(pv[s + 3]), le64_to_cpu(pv[s + 4]), le64_to_cpu(pv[s + 5]), le64_to_cpu(pv[s + 6]), le64_to_cpu(pv[s + 7])); + /* m143b: the b (0x130..) and c (0x150..) relocated windows + * and the trailing data window, so an aliased/stale PTE + * that redirects an engine access into another window is + * visible in the same log. */ + for (s = 0x130; s < 0x180; s += 0x20) + pr_info("vgsp-gr: main PT[%03x..%03x]=%016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx\n", + s, s + 7, + le64_to_cpu(pv[s]), le64_to_cpu(pv[s + 1]), + le64_to_cpu(pv[s + 2]), le64_to_cpu(pv[s + 3]), + le64_to_cpu(pv[s + 4]), le64_to_cpu(pv[s + 5]), + le64_to_cpu(pv[s + 6]), le64_to_cpu(pv[s + 7])); for (s = 0x190; s < 0x1a0; s += 8) pr_info("vgsp-gr: main PT[%03x..%03x]=%016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx\n", s, s + 7, @@ -17909,6 +17920,36 @@ gr_page_unmapped: GSP_PHYS_PAGE_SIZE); wrote++; } + /* m143b: unconditional first words of the first page of each + * 32-page relocation window (a=0x110000, b=0x130000, c=0x150000) + * after the run, so the engine's read/write footprint per window + * is provable without relying on the changed-page counter. */ + { + u32 wi; + + for (wi = 0; wi + 1 < req->n_data; wi += 32) { + u32 bi = (u32)((req->data[wi].reloc_va - + GSP_PHYS_RMCALL_GR_BOUNCE_VA0) >> + 12); + const u8 *wp; + u32 wc = 0, k; + + if (bi >= GSP_PHYS_RMCALL_GR_MAIL_SLOT) + continue; + wp = gsp_phys_chunk_page_va( + &boot_stage.rmcall_gr_bounce, bi); + for (k = 0; k < GSP_PHYS_PAGE_SIZE; k += 4) + wc += get_unaligned_le32(wp + k); + pr_info("vgsp-gr: window[%u] reloc=0x%llx first=%08x %08x %08x %08x changed=%u\n", + bi, + req->data[wi].reloc_va, + get_unaligned_le32(wp), + get_unaligned_le32(wp + 4), + get_unaligned_le32(wp + 8), + get_unaligned_le32(wp + 12), + wc != bounce_csum_in[bi]); + } + } pr_info("vgsp-gr: bounce copy-out: %u pages written back, %u changed by engine (first bi: %u %u %u %u %u %u %u %u)\n", wrote, changed, chg[0], chg[1], chg[2], chg[3], chg[4], chg[5], chg[6], chg[7]); @@ -17932,8 +17973,9 @@ gr_page_unmapped: &boot_stage.rmcall_gr_qmdwin, 0); if (qw) - pr_info("vgsp-gr: post-OK qmdwin w48..51=%08x %08x %08x %08x\n", - qw[48], qw[49], qw[50], qw[51]); + pr_info("vgsp-gr: post-OK qmdwin w48..59=%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + qw[48], qw[49], qw[50], qw[51], qw[52], qw[53], + qw[54], qw[55], qw[56], qw[57], qw[58], qw[59]); } ret = 0; diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 3c47ed3..561ebf0 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -928,6 +928,34 @@ static int svc_write_ap(struct nv_vgpu_device *vgpu, u64 addr, u32 aperture, static bool svc_gr_content_rearm; /* + * m148 (second-client wedge): re-arm the per-rank one-shot ring/push-buffer + * latches for a (re-)registered channel. The guest driver rebuilds the GSP + * session for every client context and RM reuses the same object handles and + * channel ranks across sessions. The ISSUE-0002 session flush only runs on + * the last-channel-closed transition, so a second session that re-registers + * the same handles while the first session's entries are still present (or + * before the deferred flush executes) inherits the previous session's latch + * bits. The CE/GR ring autopin and the push-buffer pairing then never re-run, + * the new session's ring stays untranslated (svc_lookup fails for its GPFIFO + * VA), the pump counts the entries as nomap and the guest spins forever in + * uvm_tracker_wait_for_entry waiting for its channel-creation push release - + * the second-client wedge. Both autopin paths and the pairing are + * content-validated (entry0 must parse; a discovered base must carry this + * channel's slot), so re-arming is safe and idempotent within a session. + */ +static void svc_chan_rearm_rank(struct svc_channel *ch) +{ + if (!ch || !ch->valid) + return; + if (ch->engine_type) { + clear_bit(ch->ce_index, &svc_ring_done); + clear_bit(ch->ce_index, &svc_pb_done); + } else { + clear_bit(ch->gr_index, &svc_gr_ring_done); + } +} + +/* * Register a guest channel. Called from the GSP-RM emulation when the guest * driver allocates a channel (the allocation carries the GPFIFO GPU VA, its * entry count and the guest-physical USERD/instance blocks), and dropped when @@ -1050,6 +1078,13 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc) spin_unlock_irqrestore(&svc.chan_lock, flags); if (ch) { + /* + * m148: force the ring/push-buffer discovery latches for this + * rank to re-run for the (possibly new) session, so the new + * ring is translated from its own content instead of inheriting + * the previous session's one-shot state (second-client wedge). + */ + svc_chan_rearm_rank(ch); svc.last_chan_reg = jiffies; pr_info("sema-svc: channel 0x%x registered gpfifo=0x%llx entries=%u userd=0x%llx eng=%u cid=%u notif=0x%llx\n", desc->h_object, desc->gpfifo_va, desc->gpfifo_entries, @@ -1063,7 +1098,6 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc) /* P6b wave-1.5 hold state is defined with the forwarding section below. */ static void svc_fwd_hold_abort(u32 h_object); - /* * P6b wave-2 inline software fallback for a withheld (skipped) candidate; * defined with the forwarding section below. Service-thread only. |
