summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_rm_emulation.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-27 07:06:12 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-27 07:06:12 -0400
commit38ba1e2d7d579c2467dfa10daca16cdbd6579089 (patch)
tree260d5daf67386aeae61501c5e4690e918ee9e310 /kernel/gsp_rm_emulation.c
parent42c9626b19037f45d7be9e1c228ec4376b0f29cc (diff)
downloadopen-iov-38ba1e2d7d579c2467dfa10daca16cdbd6579089.tar.gz
open-iov-38ba1e2d7d579c2467dfa10daca16cdbd6579089.zip
vgsp: channel-scoped VA resolution via the channel's own VAS (r835)
Every RM client maps different objects at the same numeric VAs (all clients' windows sit at 0x1200xxxxx), so the global VA-keyed pin/lat/map layers conflate them across clients. Live walk_probe evidence (r834): the X server's ring VA 0x120090000 resolved through the GL client's page tables (vas h=0xcaf00005 -> a zero page) while the X client's own VAS (vas h=0x10005) holds the real page (pa=0x1294fa000). That conflation is what wedged the X server's readback wait and starved the RC watchdog's ring (its pushes decoded as empty). * Parse NV_CHANNEL_ALLOC_PARAMS.hVASpace (@28; layout confirmed by the struct's own known offsets) at channel registration and carry it on svc_channel. * svc_chanvas_lookup: resolve a VA through the serviced channel's own VAS page tables first (svc_cur_vas, refreshed per channel turn and in the decode path). The hook sits at the head of svc_lookup_trusted, so ring, push, release and notifier resolution all inherit it; a failed walk falls through to the old chain unchanged. Live r835: X's XShmGetImage readback, previously never completing, returned after its long wait and a frame reached the kvmfr BAR (first frame content still black and readback latency still ~87 s; the guest-side fbcopy_pub framebuffer reader tool is added for the direct-VRAM capture path, find/pub/test modes).
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
-rw-r--r--kernel/gsp_rm_emulation.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index fc08b9d..7b7e230 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -3120,6 +3120,20 @@ static void gsp_rm_register_channel(struct gsp_emu_context *ctx, u32 h_object,
*/
if (desc.engine_type >= 1 && desc.engine_type <= 8)
desc.engine_type = 0;
+ /*
+ * r835: the channel's own address space (NV_CHANNEL_ALLOC_PARAMS:
+ * hContextShare @24, hVASpace @28 - confirmed by this struct's own
+ * known offsets: engineType @128 = 32 + 8 handles + 8 subdevice
+ * handles + 8 u64 userd offsets). Two clients map different objects
+ * at overlapping VAs (everyone's RM window sits at 0x1200xxxxx), so
+ * the global VA-keyed translation maps conflate them: the X server's
+ * ring VA resolved through the GL client's page tables (walk-probe:
+ * vas h=0xcaf00005 answered 0x120090000 with a zero page) and its
+ * push stream decoded as empty, wedging X exactly like the RC
+ * watchdog's ring. The service resolves a channel's VAs through this
+ * VAS first.
+ */
+ memcpy(&desc.h_vaspace, params + 28, 4);
memcpy(&desc.cid, params + GSPRM_CHAN_CID, 4);
memcpy(&desc.instance_pa, params + GSPRM_CHAN_INSTANCE_MEM, 8);
memcpy(&desc.userd_pa, params + GSPRM_CHAN_USERD_MEM, 8);