From fa985e759707ce011bd238bbbb73bc422fccb90f Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 12 Nov 2026 01:29:13 -0500 Subject: vgsp: resolve GSP-client USERD from hUserdMemory and skip foreign USERD pages GSP-client kernel channels carry their USERD as hUserdMemory[subdev] (NV_CHANNEL_ALLOC_PARAMS @32) plus userdOffset[subdev] (@64), leaving the userdMem memdesc (@168) zero. The service therefore adopted another live channel's USERD page (c23: h=0x1000013 took the RC watchdog h=0x31415900's block at fb 0x8f0000 every pass) and the Xorg PB progress wait never advanced. Remember client memory-object ALLOCs (class 0x3e sysmem, 0x40 vidmem; 0x70/0x50a0 are virtual ranges and are refused) in a bounded (hClient,hObject) table, alias them on DUP_OBJECT and retire them on FREE. At channel registration, if the wire userdMem base is zero, resolve hUserdMemory+userdOffset through that table and set userd_pa/userd_as only when the base is nonzero, page-aligned and in bounds; otherwise fail closed with a rate-limited reason. Also skip FB-sweep USERD candidates on a page already owned by another live channel. Validation pending a fresh V30 cycle: glxinfo -B exit 0, Xorg WAIT count 0, chan_dump h=0x1000013 userd!=0 ok=1 get advancing, sema-push have_rel=1, glxgears FPS unchanged, GZDoom -glversion 4.0 past V_Init. Evidence: handoff-meta-plan.md CONT.438; c23 X/GLX logs; ABI gsp_abi_check.c:1764, nvos.h:1631-1668, cl003e.h/cl0040.h. --- kernel/gsp_rm_emulation.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'kernel/gsp_rm_emulation.h') diff --git a/kernel/gsp_rm_emulation.h b/kernel/gsp_rm_emulation.h index 82ae493..17154b7 100644 --- a/kernel/gsp_rm_emulation.h +++ b/kernel/gsp_rm_emulation.h @@ -50,6 +50,35 @@ struct gsp_emu_context; #define GSPRM_RPC_FUNC_UPDATE_BAR_PDE 70 #define GSPRM_RPC_EVENT_POST_EVENT 0x1003 #define GSPRM_MAX_EVENTS 128 +/* + * CONT.438: bounded client memory-object table. GSP-client kernel channels + * pass a client-allocated USERD as hUserdMemory[subdev] (NV_CHANNEL_ALLOC_PARAMS + * @32), not as the userdMem memdesc (@168), so the channel alloc alone cannot + * name the USERD PA. Remember the memory-object ALLOCs by (hClient, hObject) + * and resolve the channel's handle later. Sized well above the handful of + * USERD objects live at once; retired slots are reused. + */ +#define GSPRM_MAX_MEM_OBJECTS 128 + +/* Address-space tag for a remembered memory object (NV_ADDR_* values). */ +enum gsp_rm_mem_as { + GSPRM_MEM_AS_UNKNOWN = 0, + GSPRM_MEM_AS_SYSMEM = 1, /* NV_ADDR_SYSMEM: base is a guest PA */ + GSPRM_MEM_AS_VIDMEM = 2, /* NV_ADDR_FBMEM: base is an FB offset */ + GSPRM_MEM_AS_VIRTUAL = 3, /* VA range only; never a physical base */ +}; + +struct gsp_rm_mem_object { + u32 h_object; + u32 h_client; + u32 h_parent; + u32 class_id; + u64 base; /* PA (sysmem), FB offset (vidmem), or VA */ + u64 size; + u8 address_space; /* enum gsp_rm_mem_as */ + bool valid; +}; + /* Max event records written between two replies (status-ring safety). */ #define GSPRM_EVENT_BURST_MAX 24 #define GSPRM_RPC_EVENT_GSP_INIT_DONE 0x1001 @@ -211,6 +240,18 @@ struct gsp_rm_emu { u64 events_dropped; u32 event_burst; /* event records written in the current window */ unsigned long event_burst_at; /* m171: burst window start (time-based reset) */ + + /* + * CONT.438: client memory objects observed through GSP_RM_ALLOC, + * keyed by (hClient, hObject), used to turn a channel's + * hUserdMemory[subdev] into a physical USERD base. All alloc/free + * handling is serialized on the emulation thread, so no lock. + */ + struct gsp_rm_mem_object mem_objects[GSPRM_MAX_MEM_OBJECTS]; + u32 mem_objects_n; + u32 mem_objects_next; /* eviction cursor when full */ + u32 mem_object_logs; /* bounded mem-object witness budget */ + u32 mem_object_evictions; /* bounded diagnostic counter */ }; /* -- cgit v1.2.3