diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 13:13:27 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 13:13:27 -0400 |
| commit | 8b1433c9efe91f75cfcbd91f4f9e52341c0bb17f (patch) | |
| tree | 68c4e8d78c29977df132c9a3137ef0eb1da3796d /kernel/gsp_rm_emulation.c | |
| parent | de8781e8d900cb99e296f53ff0407585c186f1eb (diff) | |
| download | open-iov-8b1433c9efe91f75cfcbd91f4f9e52341c0bb17f.tar.gz open-iov-8b1433c9efe91f75cfcbd91f4f9e52341c0bb17f.zip | |
gsp_rm: retire event records on FREE; guest-diag: bp999 dumps the RM error record
A freed client's notifier events (hSrcResource 0) stayed valid in the event
table, so the fallback wake-up nudge kept posting POST_EVENT records for a
(hClient, hEvent) pair the guest RM no longer knows; every one asserts in
CliGetEventInfo (kernel_gsp.c:466) and is dropped (171 failures in the
15:24 window of the last run, zero after this fix). FREE now retires the
matching event record (and a client's records when its root object is freed).
bp999.py now walks rdi -> ctx -> ctx[0x1291] -> +0x10 -> +0x10 and prints the
RM error notification record, and push_guest_tools.sh ships it to the guest.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 7300a8f..706bd81 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -2712,18 +2712,43 @@ static void gsp_rm_handle_free(struct gsp_emu_context *ctx, const u8 *elem, (const struct gsprm_rpc_header *)(elem + GSPRM_ELEM_HDR_SIZE); const u8 *req = elem + GSPRM_ELEM_HDR_SIZE + sizeof(*hdr); u8 params[16]; /* NVOS00_PARAMETERS: hRoot, hObjectParent, hObjectOld, status */ - u32 hObjOld = 0; + u32 hObjOld = 0, hRoot = 0; + u32 removed = 0, i; if (hdr->length >= sizeof(*hdr) + sizeof(params)) memcpy(params, req, sizeof(params)); else memset(params, 0, sizeof(params)); + memcpy(&hRoot, params + 0, 4); memcpy(&hObjOld, params + 8, 4); memset(params + 12, 0, 4); /* status = NV_OK */ gsp_sema_service_channel_del(hObjOld); + /* + * Retire event records that refer to the object being freed. Posting an + * event for a freed (hClient, hEvent) pair makes the guest RM assert in + * CliGetEventInfo (kernel_gsp.c:466) and drop the record; a freed + * client's notifier events (hSrcResource 0) linger across runs and the + * fallback wake-up nudge would hit them. Also retire a client's events + * when its root object is freed (hObjOld == hRoot). + */ + for (i = 0; i < rm->events_n; i++) { + if (!rm->events[i].valid) + continue; + if (rm->events[i].h_event == hObjOld || + (hObjOld && hObjOld == hRoot && + rm->events[i].h_client == hRoot)) { + rm->events[i].valid = false; + removed++; + } + } + if (removed) + nv_vgpu_info(ctx->vgpu, + "GSPRM: retired %u event record(s) on FREE hObjOld=0x%x hRoot=0x%x", + removed, hObjOld, hRoot); + nv_vgpu_info(ctx->vgpu, "GSPRM: FREE hObjOld=0x%x seq=%u cmd_read=%u stat_write=%u", hObjOld, sequence, rm->cmd_read, rm->stat_write); |
