Skip to content

fix(libkernel): unmap direct memory views when the memory is released - #2236

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
mrk1987:fix/release-direct-memory-unmaps-views
Oct 10, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
mrk1987:fix/release-direct-memory-unmaps-views

Conversation

@mrk1987

@mrk1987 mrk1987 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

What

sceKernelReleaseDirectMemory and sceKernelCheckedReleaseDirectMemory free the physical pages and forget their direct mappings, but the virtual ranges that mapped them stay registered as guest allocations. A later sceKernelVirtualQuery then reports those ranges as committed flexible memory at offset 0.

A title that frees GPU memory by walking a virtual range with FIND_NEXT and releasing offset + (start - info.start) for each region it finds then frees physical offset 0. That stops with direct memory range 0x0+0x200000 references unallocated physical page 0x0.

With this change, releasing direct memory also unmaps every virtual view of the released pages, aliases included, so the range is free afterwards. The views are collected before the pages are freed and unmapped through the existing UnmapRegistered path. The checked variant unmaps only when the release succeeds.

This follows shadPS4's MemoryManager::Free, which releases "any dmem mappings that reference this physical block": https://github.com/shadps4-emu/shadPS4/blob/main/src/core/memory.cpp

CheckReleaseDirectMemoryClearsMappings asserted the old behaviour, where a fully released mapping still answered queries. It now checks that both the mapping and a second alias stop answering queries, and that FIND_NEXT from them does not return them. It no longer depends on how a hole inside an allocation is reported, which #1731 changes.

Tested

Windows 11, MinGW-w64 GCC (project toolchain), Release/Ninja on upstream main d70b8998.

  • guest_memory passes with the change. On unchanged production code the updated test fails at the released-mapping query (GuestMemory.cpp:288).
  • tools/check_conventions.py and git diff --check pass.
  • A retail Unreal Engine title previously stopped on the release of physical page 0 described above. With this change (plus unrelated local work) it reaches its first presented frames. Gameplay is not verified.

Checklist

  • Based on current main; no other open PR implements the same functions (fix(libkernel): query current guest mapping extents #1731 changes sceKernelVirtualQuery range selection and explicitly excludes memory release; the two are independent)
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw; no silent stubs added
  • No notes, investigation files or images added to the repository
  • New third-party code is a submodule built from source (none added)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes. The investigation, code, tests and this description were written by Claude (Claude Code), reviewed and run on my machine.

🤖 Generated with Claude Code

Releasing direct memory left the virtual ranges that mapped it registered,
so sceKernelVirtualQuery reported them as flexible memory at offset 0 and
titles walking a range with FIND_NEXT released physical page 0.

Collect every view of the released pages before freeing them and unmap
them through UnmapRegistered, as shadPS4's MemoryManager::Free does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kikoarl

Kikoarl commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Linux run: Linux 7.2 (x86_64), GCC 16.2.1, Release, -DBUILD_TESTING=ON, #2236 (24474e3d) tested on current main (d70b8998).

  • tests/guest_memory_tests (ctest -R "^guest_memory"): passes cleanly.
  • tools/check_conventions.py: passes cleanly.
  • Confirmed the mutation on main: on unpatched main the updated test fails at GuestMemory.cpp:288 (released-mapping query); with fix(libkernel): unmap direct memory views when the memory is released #2236 applied, it passes.
  • No regressions observed in guest_allocations / guest_addresses.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
#2421 core/libs/prx/libkernel/DirectMemory/Export.cpp L218-219

oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
@oneandonlydean
oneandonlydean merged commit 698254f into boykopovar:main Oct 10, 2026
9 of 10 checks passed
SleglJan pushed a commit to SleglJan/AnyPS5 that referenced this pull request Oct 10, 2026
…mory-unmaps-views

fix(libkernel): unmap direct memory views when the memory is released
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants