fix: reliability improvements in WinServer/IPC subsystems

This commit is contained in:
2026-05-14 15:31:28 +02:00
parent eac8feb62c
commit 1561ee1160
3 changed files with 15 additions and 19 deletions
+10 -15
View File
@@ -1806,7 +1806,8 @@ namespace Ipc {
return 0;
}
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext, uint64_t& outVa) {
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext,
uint64_t& outVa, bool reserveGrowthRange) {
if (surface == nullptr) return -1;
int slot = SlotForPid(pid);
@@ -1862,20 +1863,14 @@ namespace Ipc {
g_surfaceMaps[slot][mapIdx].numPages = numPages;
surface->refs++; // inlined RetainRawObject — we already hold surface->lock
// Reserve the full surface address-range cap, not just the currently
// mapped pages. ResizeSurface can grow this surface up to
// MaxSurfacePages, and its grow path extends the existing VA range
// in-place by mapping new pages at baseVa + p*0x1000 for p beyond the
// original size. If we only bumped heapNext by numPages*0x1000, any
// subsequent mapping (another surface, heap allocation, etc.) would
// sit at baseVa + numPages*0x1000 -- and a later grow would silently
// overwrite its PTEs. Reserving MaxSurfacePages*0x1000 (32 MiB) of
// VA per mapping is cheap: 47-bit user VA gives 128 TiB of headroom,
// and at most MaxSurfaceMapsPerProcess (64) mappings per process
// means at most 2 GiB of reserved VA per process. Page tables are
// only populated for pages actually mapped; unused VA in the
// reservation costs nothing beyond the address-space slot.
heapNext += (uint64_t)MaxSurfacePages * 0x1000ULL;
// Generic IPC surfaces can grow in place through ResizeSurface(), so
// their mapping must reserve the maximum VA range that a later grow
// can populate. Window-server surfaces are replaced rather than grown
// in place, so callers can opt out and avoid burning 32 MiB of process
// VA on every window map/remap during a long desktop session.
uint32_t reservedPages = reserveGrowthRange ? MaxSurfacePages : numPages;
if (reservedPages < numPages) reservedPages = numPages;
heapNext += (uint64_t)reservedPages * 0x1000ULL;
outVa = baseVa;
surface->lock.Release();
return 0;
+2 -1
View File
@@ -135,7 +135,8 @@ namespace Ipc {
uint32_t fillPixel);
uint64_t MapSurfaceHandle(int handle);
int ResizeSurfaceHandle(int handle, uint64_t newSize);
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext, uint64_t& outVa);
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext,
uint64_t& outVa, bool reserveGrowthRange = true);
int UnmapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys);
ProcessObject* GetProcessObject(int pid);