Repository navigation
Conversation
On Windows, a host import of shared guest memory goes through a read-write alias from WindowsMappings::MapAlias. The alias was a single MapViewOfFile3 of one section, so MapAlias threw when the views of the range were not one contiguous run of that section. One sceKernelMapDirectMemory over two adjacent direct memory allocations gives such a range, as each allocation has its own section, and so do pages remapped in place to another physical order. Such ranges are now aliased run by run: a placeholder reservation is split at each run of consecutive pages of one section, and each run maps that section at its offset. UnmapAlias unmaps every run and forgets the alias even when one unmap fails. A contiguous range keeps the single view, and a range with a page that is not a shared view is still refused. guest_memory maps two adjacent direct memory allocations of two pages and one page with one call, and two pages in reverse physical order. It reads and writes every page through the alias. The first test also checks that the alias has one view per run and that unmapping it frees its pages. A range whose second page is flexible memory is still refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Can you run this revision on Poppy Playtime: Chapter 4 (PPSA25063) on main, without the local multi-range import change, and post the abort log from main and the result with this PR? The only title run so far used the one-view-per-page revision plus other local work, so it doesn't show that main reaches this path or that this fixes it. |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
|
Ran it on main faf6a11 with nothing local: 4 runs of Poppy Playtime: Chapter 4 (PPSA25063), alternating main and main with this PR merged (same relinked executable; the PR only changes libc), with
All 4 runs stop 6-14 s in, after that image is created, on an unrelated shader: So this only matters once a Windows import spans registered ranges, which main doesn't do. Closing it; it can come back with such a change, which needs it. |
What
On Windows, a host import of shared guest memory goes through a read-write alias from
WindowsMappings::MapAlias. The alias was a singleMapViewOfFile3of one section, soMapAliasthrew when the views of the range were not one contiguous run of that section or spanned several sections:importAllocationdoes not catch it, so the title aborts. Two layouts give such ranges:sceKernelMapDirectMemoryover two adjacent direct memory allocations: each allocation has its own section (CreateDirectMemoryBacking),AddMappingmaps each one, and the mapping is one registered range;MAP_FIXED) to physical pages in another order. Each remap leaves its own registered range, andimportAllocationimports one registered range at a time, so no host import onmainasks for this alias yet.fpPS4's PS4 kernel reimplementation (branch
kern) accepts a direct memory mapping whose physical range is allocated without gaps and with onem_acl(_dmem_map_test, L930-L984), and merges neighbouring allocations with equal attributes (dmem_map_simplify_entry, L1198-L1235). shadPS4'sMapMemoryalso walks several direct memory areas in one call. Neither is a hardware measurement, and this is not verified on PS5.Such ranges are now aliased run by run: a placeholder reservation is split at each run of consecutive pages of one section, and each run maps that section at its offset with
MEM_REPLACE_PLACEHOLDER, the mechanismMapuses for guest pages. Two adjacent allocations give two views.UnmapAliasunmaps every run and forgets the alias even when one unmap fails. A contiguous range keeps the single view.Left as before:
importAllocationstill imports one registered range at a time; imports of views spanning several registered ranges are not added here.Tested
Windows 11 Pro, Intel Core i7-12700K, NVIDIA GeForce RTX 4070, 32 GB, MinGW-w64 GCC 15.2.0.
guest_memory(core/libs/tests/GuestMemory.cpp; the three new checks are Windows only):CheckAliasAcrossDirectAllocations: allocations of 32 KiB and 16 KiB, adjacent and mapped with one call. The alias has one view per allocation, reads and writes all three pages, and unmapping it frees them;CheckAliasOfReorderedSharedPages: two pages remapped in reverse physical order. The alias reads and writes both;CheckAliasRefusesPagesThatAreNotSharedViews: a range whose second page is flexible memory is still refused.On
main, each of the first two fails with the message above (address aside); the third passes on both.agc_driver_dcc_keys_first_write(also maps an alias),agc_write_watch_coverage,agc_driver_typed_heaps,guest_heap_rounding_overflowandapplication_heap_*pass.tools/check_conventions.py --base origin/mainpasses.Poppy Playtime: Chapter 4 (PPSA25063) aborted once with this error in a presentation compute shader (
0x3008540000+0x400000), in a local build that also imports buffer views spanning several registered ranges, which this PR does not add. The log does not show whether that range was one registered range or several. With an earlier revision of this change (one view per page) in that build, the title reaches gameplay and the error did not recur in 12 later runs. The error was rare, and the logs do not show whether an alias of several views was created, so this does not show that the change prevents it.Not tested:
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)