Commit Graph

16 Commits

Author SHA1 Message Date
JJenkx f7fd7569fa fix(agc): retire fully unmapped multisample targets 2026-10-13 10:37:07 -04:00
Mouad-Scriptz-0 df3d027ebe perf(libkernel): find guest allocations and direct mappings by address
sceKernelVirtualQuery, sceKernelMunmap, sceKernelReleaseDirectMemory and the
reservation paths walked a copy of the whole allocation registry or of every
direct mapping under one lock on each call. The registry now answers lookups
from its ordered map, applies range replacements as patches instead of
rebuilding the map, and direct mappings carry an index by physical offset so a
release finds only the mappings it covers. Minecraft (PPSA17221) holds about
7,000 direct mappings and spent its world generation in these walks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-13 23:11:32 +13:00
Nesyth 78f8df053f perf(libc): share one snapshot of the registered guest ranges between leases until the registry changes 2026-10-12 21:07:13 +02:00
raghav314 be1f501525 fix(agc): import GPU-mapped guest memory when it is mapped
The registry calls an observer on the mapping thread, after the registry
lock is released, with the ranges a kernel mapping gave GPU access:
direct and flexible maps with it, and fixed remaps with it over a
registered range (a reservation). The mutation looks them up while it
still holds the lock and hands them over weakly, with the registry
generation it ended at, so the observer does not keep a range alive.
The driver imports those ranges on its current device, so an
address-based build finds the import instead of pinning the memory on
the queue that first uses it. A range that gains GPU access through
sceKernelMprotect, and AnyPS5's own libc heap, are still imported on
first use.

The import at map does not reconcile the other imports with the
registry, so its cost does not grow with the number of imports. It skips
a range that is gone, and any range when the imports were reconciled
with a newer registry since; the next lookup imports those as before.
It installs the pin waiter as the other import paths do, so unmapping a
range imported at map retires its import. The live import bytes are kept as a
running total instead of being summed over every import. Once the import
table belongs to the current device the import takes only the table's
lock; the first import on a device (which runs the write-watch probe)
and a device that was just replaced go through the GPU lock. Clearing
the observer waits for calls already running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:23:23 +02:00
raghav314 c11a9cb59f fix(agc): address-based builds map only memory mapped for the GPU
The registry records whether a range was mapped or protected with GPU
access (0x10/0x20), and an address-based build leaves out ranges without
it, as the console's GPU page tables do. The main image is registered
without GPU access; the title's own mprotect with GPU bits adds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:34:34 +05:30
Lexroid 57c179c74d fix(libkernel): unregister guest module images when they are unloaded
A .guest.prx image registered by sceKernelMprotect stayed in the guest
allocation registry after dlclose freed it, so its dead ranges blocked
later mappings at that address and could reach GPU builds.

The Windows module destructor now unregisters the image before
FreeLibrary. Unregistering waits for outstanding leases on the image like
unmap and protect do; if the wait fails the module stays loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:23:42 +02:00
Lexroid 9f1d7b0516 fix(libkernel): reprotect bundled guest module images on Windows
On Windows, sceKernelMprotect accepted only the executable's image and threw
"Memory protection of a foreign image is not supported" for every other
image. Bundled title modules are relinked into DLLs named <module>.guest.prx,
so a title that reprotects its own module pages failed. Dying Light 2's
bundled libNRD does this at start-up (#1794).

DoMprotect now also accepts images whose file name ends in .guest.prx, and
registers their committed pages like the executable's. Other images are
still refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:23:42 +02:00
MarcZX100 cf5c3ebef3 fix(agc): retire host imports before guest unmap
The pin waiter now receives the mutation range, drains GPU work and retires every overlapping host import before the unmap callback releases the pages. Deferred import retirement keeps only the device handle and the Vulkan destroy functions, so the static import registry no longer owns a Context or its BufferPool past the device.
2026-10-10 09:35:43 +02:00
MarcZX100 f7de40f9bb fix(libkernel): query non-readable live guest ranges 2026-10-09 22:10:33 +00:00
Chad e9c8664d43 fix(libkernel): refuse fixed no-overwrite mappings over live memory with ENOMEM
MAP_FIXED | MAP_NO_OVERWRITE over a range that already holds an
allocation fails with ENOMEM and leaves the mapping in place, as in
fpPS4's TVirtualManager.check_fixed. UFC 6 (PPSA23566) relies on it to
probe for a free address and aborted on the throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:04:06 -05:00
Michon 962fc34e5a fix(libkernel): unmap ranges that span several mappings
As on FreeBSD, a munmap range covering more than one registered allocation (or gaps between them)
is unmapped allocation by allocation instead of throwing "unmap crosses allocation boundaries".
GTA V unmaps such ranges in its Story Mode prologue.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 10:54:47 +02:00
devilismyfriend a503d0b617 Merge remote-tracking branch 'origin/main' into feat/demons-souls-boot
Brings in main up to 9958d26 (homebrew runtime, POSIX wrappers in
libkernel, sce_module guest modules and --skip-sce-module, the --to-intel
general pipeline, libSceRandom, libSceRtc, libScePosixForWebKit,
libRenoirCore, test wiring).

Resolutions where both sides implemented the same thing:
- libkernel pthread: main's structure (lazy static initialisation,
  destroyed markers, MutexOperations/CondOperations, mutex protocol and
  condattr clock) with this branch's TimedWait deadlines and condition
  (precise timed lock/wait on Windows), wait tracing, the adaptive mutex
  type 4, POSIX default ERRORCHECK mutexes, EDEADLK/EPERM results instead
  of throws, and condition clocks honoured for absolute timeouts.
- libc locale: the guest Dinkumware ABI (_Locimp, facet vtables, short
  ctype/case tables, locale ids, stream storage) is kept because guest code
  inlines those layouts; main's C character functions are kept on top.
- libc stdio/strings/math: main's stream functions (guest FILE status
  sync), strerror/perror, remove, formatting, string and math exports win
  over this branch's duplicates.
- libc paths: main's working directory with this branch's path aliases
  resolved on the normalised guest path.
- libkernel file: this branch's sceKernel* results as SCE errors, main's
  POSIX wrappers and both fstat helpers.
- relinker: this branch's stub lowering keeps its trampolines through the
  main executable path; guest modules refuse lowerings that need stubs.
- AGC driver: main's rendering wait is executed by this branch's workers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-27 10:52:21 -07:00
Pacuka b98257b75d fix(libc): register the main guest image on Linux
Guest mprotect calls on the executable's own segments failed with
"guest protection or unmap range is not registered" because only the
Windows build registered the main image. Register the PT_LOAD segments of
the main executable page by page, merging the protections of segments that
share a page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 11:15:16 +02:00
devilismyfriend f3ac61000d feat(runtime): guest arena, kernel thread/sync/file APIs, crash hooks
- libc: reserve guest memory in one arena below the PS5 map limit with
  MEM_WRITE_WATCH (GuestArena) and a caching guest heap; the allocation
  registry gains a generation counter, an invalidator callback for the
  driver's page cache and a pin waiter for leased ranges. This replaces
  the fault-based GuestMemoryTracking/GuestMemoryBacking layer, whose
  files are removed.
- libkernel: mmap/mprotect/munmap on the arena, flexible memory budget,
  real sceKernelVirtualQuery; POSIX pthread layer, rwlocks, timed locks,
  TSD, event flags; 0.5 ms scheduler tick and high-resolution sleeps;
  TSC/clock/time functions; file APIs return SCE errno codes; the APR
  file-streaming API.
- libc: vectored crash reporter with backtraces for fatal exceptions,
  SIGABRT, UCRT invalid parameters and process exit; SSE4a EXTRQ/INSERTQ
  emulation for Intel hosts; %ls/%lc/%S/%C with the guest's 16-bit
  wchar_t; hand-written setjmp/longjmp for the guest jmp_buf; a path
  alias table for short save-data mount points; more string, stdio and
  math exports.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-25 16:27:49 -07:00
boykopovar 2df58cf09c fix(kernel): support page-aligned mprotect for loaded images 2026-09-23 12:45:39 +03:00
boykopovar 3028c87491 feat(agc): add bda memory mapping and resource management (wip) 2026-09-21 18:54:06 +03:00