Commit Graph
231 Commits
Author SHA1 Message Date
Henrik Rydgård 41144e3b35 Give the memory partitions the caller's privilege, not the syscall's
PPSSPP decided whether a caller was privileged with hleIsKernelMode(), which reports whether the
syscall being executed is itself a kernel-only export. That's a different question from the one
the hardware answers: on a PSP the privilege belongs to the calling module, and a kernel module
reaches sceKernelCreateTlspl through the ordinary ThreadManForUser NID like anything else. So a
kernel module asking for partition 1, 3 or 4 got ILLEGAL_PERM where a real PSP hands it over,
which the new threads/tls/kernel/partition test shows directly.

BlockAllocatorFromID now also accepts a caller whose thread belongs to a kernel module, via a new
__KernelCurThreadIsKernelMode(). It checks the thread's own attribute first and then the owning
module, because a kernel module's main thread isn't necessarily flagged kernel - the attribute
comes from PSP_MAIN_THREAD_ATTR, which needn't set it. That mirrors how sceKernelCreateThread
already works out allowKernel.

This only ever widens access, and only for threads belonging to kernel modules, so games are
unaffected - they run in user modules and see exactly what they saw before.
2026-09-08 15:18:02 -06:00
Henrik Rydgård a676eecba7 Tlspl partitions: 1-6 in both privilege levels, and document kernel-mode tests
threads/tls/kernel/partition now records the sweep from a kernel module, which settles the range
question the user-mode recording couldn't: privilege changes the permission check, not the range.
Partitions 1, 3 and 4 are ILLEGAL_PERM from user mode and fine from kernel mode, while 7 and up
are ILLEGAL_ARGUMENT either way. So the check goes back to a plain 1-6 for both, and the
kernel-mode carve-out from the last commit - which would have let 8 and 9 through - is gone.

The hardware doc gains a section on kernel-mode tests: what COMMON_KERNEL does, why the stock
crt0 makes a kernel PRX unloadable, which libraries can't be imported, and how much room there
actually is in the kernel partition.
2026-09-08 15:18:02 -06:00
Henrik Rydgård 705ea7eb02 Keep the SHA-1 context in game memory too, and scope the Tlspl partition range to user mode
sceKernelUtilsSha1Block* had the same single global context that MD5 did, so it gets the same
treatment: state, counters and block buffer now live at ctxAddr in the layout hash/sha1ctx
records off hardware. Unlike MD5, SHA-1 does not stream whole blocks through buf, which happens
to be what our sha1_update already does - so no fill-in step is needed there.

The Tlspl partition range from the last commit was too broad a cut. Hardware says only 1-6 exist,
but that recording is from user mode, and BlockAllocatorFromID deliberately maps 8 and 10 to the
user partition for a kernel-mode caller - rejecting them outright would have taken that away.
The tightened range now applies to user mode only and kernel mode keeps what it had.
threads/tls/partition also shows the answer doesn't depend on the compiled SDK version, checked
across 1.00 through 6.06, and that partition 5 is accepted - which no test had covered.
2026-09-08 15:18:02 -06:00
Henrik Rydgård 8a02d1ee0f Keep the MD5 context in game memory, and make MT19937 actually be MT19937
Three fixes, all of them things the new hardware tests turned up.

sceMd5Block* and sceKernelUtilsMd5Block* shared one static md5_context and ignored the context
pointer the caller passed in, with a TODO saying it would do "unless games do several MD5
concurrently". hash/md5ctx shows a real PSP keeps everything in the caller's 96 bytes and happily
runs two digests at once, so do that instead: the state, the counters and the block buffer now
live at ctxAddr in the game's own memory, in the layout the test pins down. Two interleaved
digests come out right, and a context that gets copied mid-digest carries on correctly. As a
side effect the state is now covered by savestates, which a file-static never was.

MersenneTwister masked both halves with 0x80000000 where the low half needs 0x7FFFFFFF, so
sceMt19937UInt and sceKernelUtilsMt19937UInt were returning a sequence that isn't MT19937 at
all - every number differed from hardware from the first draw. hash/mt19937ctx computes the
reference sequence itself and confirms the PSP is plain MT19937; with the mask fixed we match it
for both seeds tested. Init also twists the array immediately, as hardware does, so a context
that has been seeded but not drawn from now holds what a real one would.

sceKernelCreateTlspl accepted partitions up to 9 before falling through to the permission check.
Hardware draws the line at 6 - threads/tls/create records 7, 8, 9 and 10 all returning
ILLEGAL_ARGUMENT - so 8 and 9 were coming back ILLEGAL_PERM. Note this is genuinely different
from sceKernelCreateVpl right above it, which does let 8 and 9 through to ILLEGAL_PERM; the two
had been sharing a check that was only ever right for Vpl.

Risk worth naming: the MT19937 change alters the numbers any game gets from these calls. That's
the point - they were wrong - but a savestate taken mid-sequence will resume with a generator
that behaves differently from the one that made it.
2026-09-08 15:18:01 -06:00
Henrik Rydgård 61cb592b36 sceKernelMemory: Check the aligned pool size for overflow
sceKernelCreateFpl and sceKernelCreateTlspl validate blockSize * count with the
formula from hardware, but that works in 4 byte alignment while the actual
allocation uses the alignment from the options struct, which the caller picks.
A large alignment inflates each block enough that the aligned total can wrap:
we'd then allocate a small block but keep the full block count, and
sceKernelAllocateTlspl / the Fpl allocate paths hand out
address + block * alignedSize well outside the allocation.

Also give PartitionMemoryBlock::address a default. Only the savestate
constructor leaves it unset, and DoState returns early when the section is
missing, which left the destructor freeing an uninitialized address.
2026-09-04 18:10:10 -06:00
Henrik Rydgård c4160b4eed HLE: Small kernel cleanups
Initialize the wokeThreads locals that were passed by reference uninitialized in
the event flag, VPL and semaphore timeout handlers. Harmless today since the
callee only ever assigns to them, but every other use in the same files starts
at false.

Do the semaphore overflow check in 64-bit, so a large signal value can't wrap
past it into currentCount.
2026-09-04 18:10:10 -06:00
Henrik Rydgård 0f94e01241 HLE: Clamp the wait timeout remaining time to zero
CoreTiming::UnscheduleEvent returns the scheduled time minus the current time,
which is negative when the event is overdue but hasn't been processed yet - the
exact situation when a wait is satisfied right around its own timeout. Only the
semaphore clamped it; everywhere else we wrote (u32)cyclesToUs(negative) into
the game's timeout variable, i.e. a huge bogus "remaining time".

Pulled the shared shape into HLEKernel::WriteRemainingTimeout so it can't drift
apart again - event flags, mbx, fpl, vpl, msgpipe, mutex, lwmutex and semaphore
all go through it now. The two thread-end sites keep their own copy since they
unschedule even when the game passed no timeout pointer, and sceUsb just gets
the clamp.
2026-09-04 18:10:10 -06:00
Henrik Rydgård 11b4509158 Apply proper names to some more HLE functions 2026-08-24 17:37:39 +02:00
Henrik Rydgård 9205eb642a UWP buildfix, tweaks and de-clauding 2026-08-24 12:15:31 +02:00
Henrik Rydgård 75bd16d0f4 Apply two hacks to scePaf memory-arena hack
For some reason, a pointer used to allocate the heap for scePaf is not
initialized. This hacks aroung that.

Additionally zero out the specific 4-byte "category 1 alarm count" address in vsh_module.

This gets us much further.
2026-08-24 10:58:35 +02:00
Henrik RydgårdandClaude Opus 5 4c72c13a0d Module loader: clean up properly on the two failure paths that didn't
__KernelLoadELFFromPtr creates its PSPModule and inserts it into loadedModules
before it knows whether the file is loadable, so every failure exit has to
delete the decrypt buffer, Cleanup() the module and Destroy() it. Five of the
seven did. The "unreasonable decrypted size" exit and the decompression-failure
exit just returned - leaking the buffer, and leaving a live kernel object with
its UID stuck in loadedModules for the rest of the session.

While tracing that: the fake-module path frees newptr and then runs for another
sixty lines with ptr still pointing into it. Nothing reads it today - the exits
below use head, which points into the original input rather than the copy - so
there's no use-after-free and no double free, but that's a property of the
current code rather than anything enforced. Both pointers are nulled after the
delete so a future mistake there crashes instead of reading freed heap.

And the function read the magic, and in the ~SCE branch a second word after it,
before anything established the input was that big. The non-PBP caller
guarantees it, but the PBP path computes elfSize from two offsets in the file
and passes whatever comes out, including zero. Checked at the top, before the
module object exists, so that exit needs no cleanup of its own.

pspautotests 314/314 with --graphics=software, and an EBOOT.PBP still boots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-19 19:19:06 +02:00
Henrik Rydgård 5198317e24 Back out some excessive checking in the latest changes. Change TOOD: to TODO: . 2026-08-11 22:27:44 +02:00
Henrik Rydgård 0596ee97f6 More memory access cleanup 2026-08-11 20:14:01 +02:00
Henrik Rydgård 3bd41376da More memory cleanup 2026-08-11 20:12:10 +02:00
Henrik Rydgård abb57c620f Adjust some log levels 2026-08-09 22:10:54 +02:00
Henrik Rydgård 8cb1732564 Clean up the memory partition ID enum 2026-07-25 14:53:02 +02:00
Nemoumbra b0a9467699 Accepting raw block API names as real 2026-04-12 01:13:47 +03:00
Henrik Rydgård afb005e738 Add a sanity check in VPL 2026-02-26 10:37:12 +01:00
Henrik Rydgård 998f726a5c Reduce logspam in a few games 2026-02-10 09:11:56 +01:00
Henrik Rydgård 870a76328d ImDebugger: Add function to dump raw at3 frames from the atrac tool. 2025-04-02 13:30:34 +02:00
Henrik Rydgård 4a15ff950c ImDebugger: Add new Modules windows, turn the old Modules window into what will be a symbol browser 2025-04-02 10:09:19 +02:00
Henrik Rydgård 4e25f44eef Rename some module-related functions to include HLE where appropriate 2025-03-31 11:17:50 +02:00
Henrik Rydgård 8fe166e182 Expose VPL internals as well. 2025-03-31 10:32:01 +02:00
Henrik Rydgård 91809b8667 Expose FPL 2025-03-31 10:26:57 +02:00
Henrik Rydgård 644f5e4e6c Expose PSPModule (so the debugger can access it later) 2025-03-31 09:56:08 +02:00
Henrik Rydgård ee90d2acc1 PSP boot: Move more of the startup process into the loading thread. Simplifies the code a bit. 2025-03-30 11:22:16 +02:00
Henrik Rydgård 0f840e6240 Move JPEG error codes to the big enum, some include cleanup 2025-03-21 20:44:46 +01:00
Henrik Rydgård cb1df4056c Remove almost-empty files ThreadPools.cpp/h 2025-03-20 17:21:20 +01:00
Henrik Rydgård 0f9c97c2a0 Another big batch of logging cleanup 2025-03-05 17:02:46 +01:00
Henrik Rydgård ad2791a9cf More HLE logging cleanup 2025-03-05 17:02:46 +01:00
Henrik Rydgård 41e3591c8a Clean up logging in the FPL functions 2025-03-05 17:02:46 +01:00
Henrik Rydgård a18eb97be3 Consolidate more error codes into the big enum 2025-02-04 12:11:22 -06:00
Henrik Rydgård 28b2c7f540 HLE log rename part 1: Remove duplicate log functions. Return type should be determined by metadata. 2025-01-29 09:45:39 +01:00
Henrik Rydgård 2523690584 Flip around so sceDelayResult is always outermost. Start using HLECall. 2025-01-20 12:20:18 +01:00
Henrik Rydgård f962fb0386 Enable checking the format string, fix some issues 2025-01-19 16:51:05 +01:00
Henrik Rydgård 86b3eadc16 Warning fixes, maybe test fix 2025-01-19 16:33:40 +01:00
Henrik Rydgård bb914ca4bf More kernel logging cleanup 2025-01-19 15:36:59 +01:00
Herman Semenov 3c66f149d3 [Common/Core/Windows] Removed excess check pointer before delete or free() 2024-09-17 11:34:42 +02:00
Henrik Rydgård e01ca5b057 Logging API change (refactor) (#19324)
* Rename LogType to Log

* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.

* Mac/ARM64 buildfix

* Do the same with the hle result log macros

* Rename the log names to mixed case while at it.

* iOS buildfix

* Qt buildfix attempt, ARM32 buildfix
2024-07-14 14:42:59 +02:00
Henrik Rydgård 6cb2c0dc59 KERNELPRINTF->PRINTF, NOTICE->INFO 2023-09-08 08:40:54 +02:00
Nemoumbra 90cd9d4c68 New logging channel "KERNELPRINTF" for SceKernelPrintf 2023-09-08 00:34:26 +03:00
Unknown W. Brackets 32feb82d16 HLE: Capture better allocation names.
We know which FPL, so don't just say "FPL".
2023-09-02 22:55:45 -07:00
Nemoumbra 5bf22c15d0 sceKernelPrintf improvement, QOL adjustments 2023-04-11 15:47:50 +03:00
Unknown W. Brackets 88ba003f46 ThreadManager: Add a simple priority field.
Currently, not actually respected.
2023-02-02 17:08:24 -08:00
Unknown W. Brackets 0496ca32ff Global: Cleanup some minor includes and typos. 2022-12-27 08:33:07 -08:00
lainon 3cdf72b68b Better readability and optimization insertion into container by replacing 'insert' -> 'emplace', 'push_back' -> 'emplace_back' 2022-09-30 12:35:28 +03:00
Unknown W. Brackets 79c5c93d35 Kernel: Match index lookup behavior for tls.
It might be the uids it returns always follow this format.
This makes the test almost pass, outside psplink using more memory (test
should be adjusted to compensate.)
2022-09-20 19:25:32 -07:00
Unknown W. Brackets d665b2b6ca Kernel: Disallow partitions 8/10 to match tests.
I think these might be accessible only in kernel mode.
2022-09-20 10:46:43 -07:00
Unknown W. Brackets 251cc73afd Kernel: Allow volatile for MsgPipe buffers. 2022-09-20 09:20:05 -07:00
Unknown W. Brackets 56f2d7cdac Kernel: Allow volatile for Tlspl objects. 2022-09-20 09:05:39 -07:00