Merge pull request #11029 from orezraey/fix/libkernel-event-error-measured-ps5

fix(libkernel): add 0x80020000 to any event fflags in sceKernelGetEventError as measured on a PS5
This commit is contained in:
Dean authored and GitHub committed 2026-10-27 05:38:39 +13:00
commit ade9b32167
3 files changed
+10 -16

No files matched your search

@@ -25,10 +25,7 @@ int APS5_VABI sceKernelGetEventError(const KernelEvent* ev) {
if (event.fflags == 0) {
return 0;
}
if (event.fflags > 0xFFFFu) {
throw std::runtime_error(std::string(__func__) + ": fflags " + std::to_string(event.fflags) + " above 0xFFFF");
}
return static_cast<int>(0x80020000u | event.fflags);
return static_cast<int>(0x80020000u + static_cast<std::uint32_t>(event.fflags));
}
intptr_t APS5_VABI sceKernelGetEventFflags(const KernelEvent* ev) {
+9 -11
View File
@@ -23,16 +23,6 @@ static bool RejectsNull(TResult (APS5_VABI *accessor)(const KernelEvent*)) {
return false;
}
static bool RejectsWideFflags(const KernelEvent* ev) {
try {
sceKernelGetEventError(ev);
} catch (const std::runtime_error&) {
return true;
}
return false;
}
static void SleepAtLeast(std::chrono::steady_clock::duration duration) {
const auto start = std::chrono::steady_clock::now();
while (std::chrono::steady_clock::now() - start < duration) {
@@ -327,7 +317,15 @@ int main() {
Require(sceKernelGetEventFflags(&rawEvent) == static_cast<intptr_t>(0x80000001LL));
Require(sceKernelGetEventData(&rawEvent) == -5);
Require(sceKernelGetEventUserData(&rawEvent) == nullptr);
Require(RejectsWideFflags(&rawEvent));
Require(sceKernelGetEventError(&rawEvent) == static_cast<int>(0x00020001));
const std::uint32_t wide[][2] = {
{0x00010000u, 0x80030000u}, {0x00020000u, 0x80040000u}, {0x7fff0001u, 0x00010001u},
{0x80020005u, 0x00040005u}, {0x8000ffffu, 0x0002ffffu}, {0xffffffffu, 0x8001ffffu},
};
for (const auto& [fflags, error] : wide) {
rawEvent.fflags = fflags;
Require(sceKernelGetEventError(&rawEvent) == static_cast<int>(error));
}
rawEvent.fflags = 0;
rawEvent.flags = EV_ERROR;
rawEvent.data = 22;
-1
View File
@@ -283,7 +283,6 @@
- [pthread_mutexattr_setkind_np](../../../core/libs/prx/libkernel/Pthread/Posix/Mutex.cpp) (libkernel) throws for a kind outside 1 to 4. FreeBSD 11.4's [`_pthread_mutexattr_setkind_np`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libthr/thread/thr_mutexattr.c#L108-L120) stores any kind and [`mutex_check_attr`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libthr/thread/thr_mutex.c#L207-L218) then makes `pthread_mutex_init` fail with `EINVAL`, but `pthread_mutex_init` here does not check the type
- [pthread_cond_signalto_np, scePthreadCondSignalto](../../../core/libs/prx/libkernel/Pthread/src/Cond.cpp) (libkernel) wake every waiter of the condition variable, not only the given thread, and do not check the thread; the other waiters see a spurious wakeup. Which waiters the console wakes, and its result for a thread that is not waiting, are unverified
- [pthread_rwlockattr_gettype_np, scePthreadRwlockattrGettype](../../../core/libs/prx/libkernel/Pthread/Posix/Rwlock.cpp) (libkernel) report the type stored by `scePthreadRwlockattrSettype`, which accepts any value and which read-write locks do not apply; the console's valid types and their effect are unverified. A null or uninitialized attribute throws, as for `pthread_rwlockattr_getpshared`
- [sceKernelGetEventError](../../../core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp) (libkernel) throws for `fflags` above 0xFFFF, where OR and addition of 0x80020000 differ and the console was not measured. Otherwise it returns 0 for `fflags` 0 and `0x80020000 | fflags`, whatever `flags` and `data` hold, as [fpPS4](https://github.com/red-prig/fpPS4/blob/04cefd43e6fddd1ab033e7980cd356d14c964905/kernel/ps4_queue.pas#L643) does and a PS5 (firmware 13.40, measured 2026-10-19 in a payload process) answered: `{flags 0x4000, fflags 0, data 22}`, `{0x4000, 0, -1}`, `{0x4000, 0, 0x80020016}` and `{0, 0, 0}` gave 0, `{0x4000, 5, 0}` and `{0x4000, 5, 22}` 0x80020005, `{0, 7, 22}` 0x80020007, `{0x8000, 3, 9}` 0x80020003. Video-out events carry their count in `fflags`, so they get 0x80020001 and up; only events built by the caller were measured. Closes when: `fflags` above 0xFFFF is measured
- [pthread_cond_reltimedwait_np](../../../core/libs/prx/libkernel/Pthread/Posix/Cond.cpp) (libkernel) takes `(cond, mutex, usec)`, a relative timeout in microseconds, and is `scePthreadCondTimedwait` with POSIX error numbers. FreeBSD 11.4 has no such function; the signature comes only from shadPS4, which registers one function for this NID and for `scePthreadCondTimedwait` ([`condvar.cpp`](https://github.com/shadps4-emu/shadPS4/blob/3a9f57265d28975658f1ca941daa5c879c7a74bd/src/core/libraries/kernel/threads/condvar.cpp#L229-L234)). shadPS4 reads a 64-bit count; here it is the 32-bit `SceKernelUseconds` of the SCE twin, as for `sem_reltimedwait_np`. Unverified on the console
- [pthread_mutex_reltimedlock_np](../../../core/libs/prx/libkernel/Pthread/Posix/Mutex.cpp) (libkernel) takes `(mutex, usec)`, a relative timeout in microseconds, and is `scePthreadMutexTimedlock` with POSIX error numbers. FreeBSD 11.4 has no such function; the signature comes only from shadPS4, which registers one function for this NID and for `scePthreadMutexTimedlock` ([`mutex.cpp`](https://github.com/shadps4-emu/shadPS4/blob/7c960eae136b956cf4c1d72aacd2426b650330df/src/core/libraries/kernel/threads/mutex.cpp#L284-L287)). shadPS4 reads a 64-bit count; here it is the 32-bit `SceKernelUseconds` of the SCE twin, as for `pthread_cond_reltimedwait_np`, so a count of 2^32 microseconds or more would be truncated if the console reads 64 bits. Unverified on the console
- [sysctl kern.arandom](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) serves FreeBSD 11's MIB {1, 37} (CTL_KERN, KERN_ARANDOM) and the "kern.arandom" sysctlbyname lookup through std::random_device, returning min(*oldLength, 256) random bytes. Following FreeBSD's sysctl_kern_arnd, a null buffer reports min(*oldLength, 256) without writing, a null length returns 0 without writing, and requests with a new value return EPERM (1) as the node is read-only. Cryptographic quality depends on the host's random device implementation.