Commit Graph

530 Commits

Author SHA1 Message Date
MarcZX100 046680da48 fix(libkernel): reject empty mkdir paths 2026-10-10 16:06:21 +00:00
MarcZX100 5837210c9f fix(libkernel): preserve mkdir error handling for trailing paths 2026-10-10 16:06:21 +00:00
Achraf Reyani 3779ffa375 fix(libkernel): accept a trailing slash in sceKernelMkdir
sceKernelMkdir checked that the parent of the resolved path exists, but
for "dir/" std::filesystem::path reports "dir" itself as the parent, so
the call failed with ENOENT and created nothing, while FreeBSD's mkdir
(and the POSIX mkdir export) accept it. Strip trailing separators first,
and report ENOTDIR when the parent exists but is not a directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5f74ddba8b346e6c552cf02554d47382708206f3)
2026-10-10 16:06:21 +00:00
Dean b5f5362d3d
Merge pull request #2647 from oneandonlydean/fix/guest-stack-host-margin
fix(libkernel): keep host stack room below guest thread stacks
2026-10-10 23:59:23 +13:00
Dean b0cccf20a0
Merge pull request #861 from jeffrey12cali/fix/linux-guest-arena
fix(guest-arena): place guest address space in the PS5 window on Linux
2026-10-10 23:55:28 +13:00
Dean Galvin 766370108d fix(libkernel): read random devices in the Windows sceKernelPread
The Windows sceKernelPread stopped going through pread when it learned to
return errors, and with it lost the random device read, so a pread on
/dev/urandom reached ReadFile on a handle that is not a disk and failed
with ESPIPE. Read random devices first, as the Linux path does.

A pread into a read-only guest mapping now returns EFAULT instead of
throwing, matching Linux and the AIO read beside it, so the Windows
guest memory test checks for that return.
2026-10-10 23:26:37 +13:00
Dean Galvin d9f8400351 fix(libkernel): answer munlock from the guest mapping state on Linux
An unmapped range inside the guest arena stays a PROT_NONE host
reservation, so host munlock succeeds on it. Check the guest mapping
state first, as msync does, and return ENOMEM for ranges the guest
has not mapped or reserved.
2026-10-10 22:56:07 +13:00
jeffrey12cali e4e0702946 fix(guest-arena): place guest address space in the PS5 window on Linux
The arena constructor was Windows-only, so on Linux Available() was false: the guest heap fell back to the host allocator and direct memory landed wherever the kernel pleased. Titles that require a low virtual address rejected the mapping and re-issued the identical request, which surfaced as a start-up assert inside their own allocator.

Seed the window from the mappings that already exist instead of reserving it up front, because a PROT_NONE reservation of the whole range starves the kernel's own top-down mmap, which picks addresses just below the stack inside that range. Commit, reset and set-protection become portable so the arena owns its used ranges on both platforms, and fixed mappings are checked against the arena's used ranges rather than against EEXIST from a reservation.

The window-placement and no-overwrite checks in guest_memory were compiled only for Windows; they now run on Linux too, and the window check fails without this change.

Fixes #692
2026-10-10 22:56:07 +13:00
Dean Galvin 84d90152b4 fix(libkernel): keep host stack room below guest thread stacks
Since guest threads get exactly the stack size they request, host code
that a guest thread calls runs on that small stack too. sceAgcCreateShader
reaches Driver::RegisterShader, whose frame alone is about 50 KiB, so a
title whose job threads ask for 48 KiB overflows the stack (#2603).

Each guest thread now gets a fixed 1 MiB of host stack below the range it
asked for. The guest still sees the requested size and address range
through scePthreadAttrGet and sceKernelIsStack; only host calls made from
the thread use the extra room. Running the prepared-shader driver tests on
a limited main-thread stack needs between 128 and 192 KiB for shader
registration, Vulkan setup included, so 1 MiB leaves several times that.

Switching to a separate host stack at each HLE entry point would need a
trampoline on every export that may go deep, handling of stack-passed
arguments and unwinding across the switch, and a list of which exports
qualify. A margin below the guest range covers every host call with no
per-export list.

On Windows the committed size was the requested size, and the margin
below it depended on the executable's default stack reserve; requests at
or above that reserve had none. The commit now includes the same margin.
macOS does not run guest threads.

guest_pthread_stack now also calls host code that uses 256 KiB of stack
below each thread's guest range; without the margin it crashes on the
16 KiB thread.

Fixes #2603
2026-10-10 22:41:03 +13:00
Adrià be403084c6
Merge pull request #1141 from nicolasabosch/feat/kernel-pthread-cancel
feat(libkernel): implement thread cancellation
2026-10-10 11:40:09 +02:00
Adrià c84694adbb
Merge pull request #1905 from Raghav314/fix/agc-address-builds-gpu-access
fix(agc): address-based builds map only memory mapped for the GPU
2026-10-10 11:35:38 +02:00
Nicolas Abosch ef9d0dd7d2 chore(libkernel): drop the pthread_cancel comment 2026-10-10 11:32:09 +02:00
Nicolas Abosch 3acca27f27 feat(libkernel): implement thread cancellation
scePthreadCancel and pthread_cancel threw, scePthreadTestcancel did
nothing and the cleanup handler exports did not exist.

A cancel request is now recorded on the thread and acted on at
scePthreadTestcancel, the condition variable waits, scePthreadSem and
sem waits, scePthreadJoin and the sleeps, and under their POSIX names.
A thread blocked in one of the waits is woken; a condition wait takes
its mutex back before the thread exits. The thread exits with
PTHREAD_CANCELED through scePthreadExit, which now runs the handlers
of __pthread_cleanup_push_imp and __pthread_cleanup_pop_imp.
scePthreadSetcancelstate and scePthreadSetcanceltype reject unknown
values, and pthread_setcanceltype is added.

Constants, the handler node layout and the order of events follow
FreeBSD libthr. A sleep is not interrupted, file and socket calls are
not cancellation points and the asynchronous type acts like the
deferred one except at the two set calls (TechnicalDebt). New test:
guest_pthread_cancel.
2026-10-10 11:32:09 +02:00
Adrià 948a526c23
Merge pull request #407 from Pouare514/feat/deathloop-loading
feat(libs): Deathloop loading support (Ampr, NetCtlApDialog + stubs)
2026-10-10 11:29:40 +02:00
Adrià cb6870f965
Merge pull request #2538 from husseinkad/fix/windows-stat-file-identity
fix(libkernel): report a stable file identity from stat and fstat on Windows
2026-10-10 11:26:32 +02:00
Hussein Kadhim 9b5be73a99 fix(libkernel): keep stat working when a handle has no file identity
Leave the Windows identity fields at their stat values when
GetFileInformationByHandle fails on a handle whose basic information
could be read, instead of failing the whole call.
2026-10-10 11:08:10 +02:00
Hussein Kadhim 0b1941b313 fix(libkernel): report a stable file identity from stat and fstat on Windows
st_ino was always 0 and st_dev differed between stat (drive number) and
fstat (0), so the usual a.st_dev == b.st_dev && a.st_ino == b.st_ino
identity check gave wrong answers. Read the volume serial, the file index
and the link count from the file handle, which works the same for path and
descriptor lookups.

Fixes #2296
2026-10-10 11:08:09 +02:00
overlordxrz-source 9a70477170 feat(libkernel): implement kill
ProsperoStore (PPSA99000) imports kill from libkernel and stops at it on
current main. Its crash reporter resets a crash signal to SIG_DFL and
sends it again with kill(getpid(), signal).

kill follows FreeBSD's kern_kill and killpg1 for the only guest process:
EINVAL for signals outside 0 to 128, signal 0 only checks the target,
and the caller's own pid, 0 and minus its pid deliver through raise.
Any other pid, and -1, which skips the caller, report ESRCH.
2026-10-10 11:06:12 +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
Adrià 695e0b928a
Merge pull request #1551 from MarcZX100/fix/precise-subtick-polls
fix(windows): use precise waits in sub-millisecond polling loops
2026-10-10 10:52:48 +02:00
Adrià 4997f85ad3
Merge pull request #2620 from oneandonlydean/fix/carry-2423
fix(libkernel): return errors from file operation failures
2026-10-10 10:50:33 +02:00
Adrià 9d249f365e
Merge pull request #2613 from oneandonlydean/fix/carry-2564
fix(libkernel): return every command-line argument as UTF-8 from getargv on Windows
2026-10-10 10:49:51 +02:00
Adrià 8fded89e6b
Merge pull request #1803 from tv7/fix/mprotect-guest-module-images
fix(libkernel): reprotect bundled guest module images on Windows
2026-10-10 10:45:37 +02:00
Adrià 874c144712
Merge pull request #1909 from TheAggie/feat/libkernel-mmap-aligned-super
feat(libkernel): accept MAP_ALIGNED_SUPER in mmap
2026-10-10 10:44:57 +02:00
Adrià 919c49b964
Merge pull request #2612 from oneandonlydean/fix/carry-2579
fix(libc): end the process without detach routines in _Exit on Windows
2026-10-10 10:41:16 +02:00
MarcZX100 54a9018514 fix(windows): use precise sleeps for sub-millisecond polling
Co-authored-by: Shaan <shaansahai2007@gmail.com>
2026-10-10 08:30:28 +00:00
Adrià 6cc3358332
Merge pull request #2184 from EdouardSence/fix/libkernel-pthread-tid
fix(libkernel): start the pthread object with the thread id
2026-10-10 10:27:44 +02:00
Lexroid b1a14c6f36 fix(libkernel): unregister guest module images in dlclose and propagate failures
Move the image unregistration out of the Module destructor into
dlclose_nid_postfix. It runs while the handle is still registered, so a
failure (the image stays leased by GPU work) propagates to the caller and
leaves the module loaded and usable. Images shared by another open
handle stay registered until the last handle closes.

guest_memory now checks that dlclose under a held lease throws and keeps
the module, its symbols and its protection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:23:50 +02:00
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
Doston Abdullayev 1fd723f21f fix(libkernel): return errors from file operation failures
On Windows, sceKernelPread and sceKernelPwrite called the POSIX pread and
pwrite wrappers, which throw on every failure, so a bad descriptor, a
negative offset or a write to a read-only descriptor aborted the process
instead of returning an error as the Linux build does. ftruncate and
sceKernelFtruncate threw on any host failure on both platforms.

Give the Windows sceKernelPread and sceKernelPwrite the same checks and
SceErrorFromErrno returns as the Linux ones, and accept a zero-length
transfer with a null buffer. Report a positioned transfer on a handle
opened without the needed access as EBADF instead of EIO. Return EINVAL
from ftruncate for a negative length and for a descriptor opened without
write access, as FreeBSD does, and pass other host errors to the guest.

Fixes #2423
2026-10-10 21:23:30 +13:00
Doston Abdullayev 5cb7de6ba9 fix(libkernel): return every command-line argument as UTF-8 from getargv on Windows
On Windows, getargc and getargv reported only the executable path, read
with GetModuleFileNameA in the ANSI code page, and dropped every other
argument. Linux returns the whole command line from /proc/self/cmdline,
and the relinker's Windows entry stub already passes the guest entry all
arguments converted to UTF-8.

Parse GetCommandLineW with CommandLineToArgvW and convert each argument
to UTF-8 with WC_ERR_INVALID_CHARS, as the entry stub does, so getargv
matches the entry's argv and the Linux behaviour. The Linux path is
unchanged.
2026-10-10 21:20:29 +13:00
AlxcBTW bc8587a6fe fix(libc): end the process without detach routines in _Exit on Windows
On Windows std::_Exit ends in ExitProcess, which still runs every module's
DLL_PROCESS_DETACH and TLS callbacks after the other threads are gone. A
static destructor that joins a worker then waits forever: a title that calls
_Exit while libSceVideoOut's flip queue runs (ps5-opengl's retirement
fail-stop) stays alive in FlipQueue's destructor. _Exit and libkernel's _exit
now terminate the process with TerminateProcess, as _exit ends a POSIX
process: no atexit handlers, stream flushes or module destructors.
2026-10-10 21:20:29 +13:00
LuisBiceps 918bc0a49c feat(libkernel): report no child processes from waitpid
waitpid returns -1 with ECHILD, or EINVAL for an option FreeBSD does not know, and leaves the status unwritten: AnyPS5 runs the title as one process and exports nothing that creates a child. VLC PPSA85300 stops on main at this import.
2026-10-10 10:11:04 +02:00
Dean ac75a96dd7
Merge pull request #1908 from TheAggie/fix/libkernel-sched-other-priority
fix(libkernel): accept SCHED_OTHER in sched_get_priority_max/min
2026-10-10 21:05:56 +13:00
EdouardSence 94409c9f32 fix(libkernel): keep the thread id 64-bit on every host
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:58:05 +02:00
EdouardSence 9ba1b06a4e fix(libkernel): start the pthread object with the thread id
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:58:05 +02:00
QRMOE b8f04c6773 build(libkernel): register thread-name regression
AI-assisted: yes. Final code passed the complete Windows build, eight focused runtime tests and four deliberate-fault checks.
2026-10-10 09:54:11 +02:00
QRMOE 022e6be86a fix(libkernel): reject overlong POSIX thread names
AI-assisted: yes. Match the firmware 13.60 probe in PR #1798: names of 32 bytes or more return guest ENAMETOOLONG=63 and preserve the prior name. The complete final change passed a full Windows build and eight focused runtime tests.
2026-10-10 09:53:55 +02:00
Adrià 41e34915b8
Merge pull request #1777 from MathiasDevelopes/feat/libkernel-random-device
feat(libkernel): open /dev/random and /dev/urandom for reading
2026-10-10 09:27:46 +02:00
Adrià f9cd694c32
Merge pull request #1988 from NevesHenry/fix/libkernel-linux-thread-stack-size
fix(libkernel): give Linux guest threads the stack size they request
2026-10-10 09:16:35 +02:00
MathiasDevelopes 7810f8464e feat(libkernel): open /dev/random and /dev/urandom for reading
Neither existed under the guest root, so opening them failed and titles
that then read from the descriptor crashed. Opening either for reading
now returns a descriptor whose reads, positioned reads and vector reads
fill the buffer from the host's random device, as
sceRandomGetRandomNumber does. Opening them for writing throws.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 09:12:55 +02:00
Dean 01dc5c14a3
Merge pull request #1764 from Zurisen/fix/flock-nonblocking-contention
fix(libkernel): return EWOULDBLOCK from a contended LOCK_NB flock
2026-10-10 20:08:00 +13:00
Dean 50cea78f6b
Merge pull request #2291 from AchrafReyani/fix/libkernel-null-time-results
fix(libkernel): accept null results in gettimeofday and clock_getres
2026-10-10 20:07:40 +13:00
NevesHenry faf983ae01 fix(libkernel): give Linux guest threads the stack size they request
scePthreadCreate on Linux started guest threads with std::thread, so every
thread got the host default stack (RLIMIT_STACK, usually 8 MiB) whatever the
title asked for. A thread that asks for more than that and uses it crashes
with SIGSEGV. Once the thread ran, scePthreadAttrGet also reported the host
size instead of the requested one.

Create the thread with pthread_create and a stack of the requested size plus
what glibc keeps at its top (static TLS, the thread control block and the
start_thread frame). That reserve is measured once with a probe thread.
The thread reports [top - reserve - size, top - reserve) as its stack, as
Windows reports [top - size, top), and the creator waits until the range is
set, as on Windows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 08:57:00 +02:00
erick-dsnk ace167a578 fix(libkernel): preserve EINVAL in AIO completions 2026-10-10 08:42:19 +02:00
Adrià b58b1ccff4
Merge pull request #2421 from Pouare514/fix/direct-memory-release-validation
fix(libkernel): reject malformed ranges in sceKernelReleaseDirectMemory
2026-10-10 08:37:29 +02:00
Adrià 7d94990371
Merge pull request #2300 from AchrafReyani/fix/libkernel-stat-trailing-slash
fix(libkernel): report ENOTDIR from stat for a file with a trailing slash
2026-10-10 08:27:27 +02:00
Pouare514 03d975af3c fix(libkernel): reject malformed ranges in sceKernelReleaseDirectMemory
A zero, unaligned, overflowing or out-of-range length reached the physical pool, where a sub-page length silently freed a whole page and fragmented the block map, and an out-of-range length walked the page table past the backing store. Validate alignment and bounds up front and return EINVAL instead.
2026-10-10 08:22:59 +02:00
Adrià 40aeb97d57
Merge pull request #1152 from alfalfa-star/perf/linux-direct-memory-import-chunks
perf(agc): share one dma-buf import per 64 MiB of Linux direct memory
2026-10-10 08:14:40 +02:00