83 Commits
Author SHA1 Message Date
AdriàandClaude Sonnet 5.5 149ec09adf fix(libkernel): give the descriptor checks C linkage so libkernel_sys can import them
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-28 08:43:15 +01:00
AdriàandClaude Sonnet 5.5 f87b6289ac fix(libkernel): export the kqueue descriptor check to libkernel_sys
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-28 08:43:15 +01:00
Adrià a40ad89e2c Merge pull request #11236 from orezraey/fix/libkernel-kqueue-timer-readd-measured-ps5
fix(libkernel): accept EVFILT_TIMER re-adds with a time unit or on a disabled timer as measured on a PS5
2026-10-27 14:28:05 +01:00
Adrià 62b3ba2522 Merge pull request #11125 from MarcZX10/marc/fix-equeue-close-during-measure
fix(libkernel): wait for an in-flight file measurement before closing a watched descriptor
2026-10-27 13:30:54 +01:00
MarcZX10 9b9f9b4af8 fix(libkernel): retire an in-flight file measurement on every exit with a guard
MeasureFiles registered the descriptors it measures in m_measuring and removed them only on the normal path, so an exception between unlocking and relocking left them there and every later RemoveDescriptorEvents for one of them waited forever. Both vectors are reserved before anything is registered, and a guard owns the registration: on every exit it relocks if needed, removes the entries and notifies.
2026-10-27 04:46:00 +00:00
MarcZX10 de2b96d8bd fix(libkernel): wait for an in-flight file measurement before closing a watched descriptor 2026-10-27 04:46:00 +00:00
Evrim Cicek 3f67bbcd4e Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into fix/recvmsg-after-shut-rd
# Conflicts:
#	core/libs/prx/libkernel/Socket/src/Udp.cpp
#	docs/dev/debt/libkernel.md
2026-10-27 01:04:45 +03:00
Dean ade9b32167 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
2026-10-27 05:38:39 +13:00
orezraeyandClaude Opus 5.5 4c9e31f18c Merge main into fix/libkernel-kqueue-timer-readd-measured-ps5
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 12:13:12 -03:00
Dean f92497d1e5 Merge pull request #9780 from Retr0G28/fix/kevent-rotate-reported-knotes
fix(libkernel): move every knote kevent reports behind the waiting ones
2026-10-26 14:12:10 +13:00
orezraeyandClaude Opus 5.5 c7392b3fca fix(libkernel): accept EVFILT_TIMER re-adds with a time unit or on a disabled timer as measured on a PS5
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 19:21:25 -03:00
Evrim Cicek 1c5e876164 fix(libkernel): report EV_EOF and wake read waiters when a socket is shut for reading 2026-10-26 01:09:17 +03:00
orezraeyandClaude Opus 5.5 2d339842eb fix(libkernel): add 0x80020000 to any event fflags in sceKernelGetEventError as measured on a PS5
On PS5 firmware 13.60 sceKernelGetEventError returns 0x80020000 plus the
event's fflags in 32 bits for every non-zero fflags, including values
above 0xFFFF, where it used to throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 11:25:04 -03:00
Adrià c2e087b2a6 Merge pull request #7049 from blawesom/followup/6510
fix(libkernel): retire an EV_ONESHOT note through its delete callback and follow Windows $Deleted paths
2026-10-25 12:38:21 +01:00
boykopovar 53a65ec210 fix(sdk): sync declarations with latest main 2026-10-24 23:17:48 +03:00
boykopovar f38d29fd08 refactor(sdk): add canonical headers for remaining libraries 2026-10-24 23:17:42 +03:00
Dean d003e64fcf Merge pull request #9099 from aarushkha/feat/libkernel-equeue-regular-file-events-v2
feat(libkernel): answer sceKernelAddReadEvent and sceKernelAddWriteEvent on regular files
2026-10-25 06:33:30 +13:00
Dean ce16645691 Merge pull request #9127 from Retr0G28/fix/equeue-rotate-level-events
fix(libkernel): move events reported by sceKernelWaitEqueue behind the waiting ones
2026-10-25 04:17:49 +13:00
blawesom 681cfa1170 fix(libkernel): refuse a timer modify with fflags and pin the disabled timer's enable re-arm
- a timer change with EV_ADD unset and data 0 keeps the period; one that set
  fflags was silently ignored, where FreeBSD 11's kqueue_register copies it
  onto the note: it now throws with the other re-adds, waiting for the
  measured rules
- EV_ENABLE on a disabled timer reports the expiries missed while disabled in
  one step and keeps the note's phase, as FreeBSD 11's filt_timerexpire counts
  a disabled note and keeps its p_nexttime; TimerDisableEnableRearm pins it
  (5 serial runs and 3 rounds of 8 parallel copies pass)
- the next-wait abort from the review round was observed before main's
  5cbc46029b wait refactor and does not reproduce
2026-10-24 11:13:43 +02:00
Nawasfadili 29a6fc7169 fix(libkernel): retire an EV_ONESHOT note through its delete callback and follow Windows $Deleted paths
Carries the additive pieces of #6510 onto main after its feature was
superseded by #5847: the deleteEventFunc invocation when an EV_ONESHOT
note retires in CollectTriggered, the Windows $Deleted path detection
in FileEvent (IsDeleted transitions), the relaxed timer-modify and
SetVnodeNotes guards, and the compatible kevent tests.
2026-10-24 11:13:43 +02:00
ionut27001 27e37024a8 fix(libkernel): handle kevent timer re-adds and the AIO, LIO, SENDFILE and PROCDESC filters as measured on a PS5
In payload processes on a PS5 (firmware 12.70), re-adding an existing
periodic EVFILT_TIMER with EV_ADD, fflags 0 and a positive period kept
the armed expiry and the expirations already counted, and applied the
new period after that expiry, as FreeBSD 11.0 does. EV_ONESHOT in the
re-add left the timer periodic. Here such a re-add threw; it now does
the same. Re-adding a one-shot or disabled timer, a re-add with nonzero
fflags, a period of 0 or less, a period that overflows the armed expiry
or flags other than EV_ONESHOT, and the other changes to an existing
timer except EV_DELETE still throw.

There, EV_ADD failed with EPERM for EVFILT_AIO, EVFILT_LIO and
EVFILT_SENDFILE at every ident and flag set tried, and EV_DELETE and
EV_ENABLE of them without EV_ADD failed with ENOENT. EVFILT_PROCDESC
failed with EBADF on a descriptor that is not open and with EINVAL on
every kind of open descriptor tried, and EV_DELETE of it on a socket
failed with ENOENT. These filters threw here; they now answer the same
way. EV_ADD of EVFILT_PROCDESC fails with EINVAL on the kinds of
descriptor tried and on shared memory, and throws on other kinds and on
descriptors 0 to 2 that are not sockets or kqueues; a change without
EV_ADD fails with ENOENT, after the descriptor check for
EVFILT_PROCDESC.

A new kevent measurements debt entry, which the kqueue and kevent entry
points to, records these measurements and the answers for NOTE_LOWAT
marks and EVFILT_READ on another kqueue, which still throw here. The
kqueue and kevent entry also stops listing a NOTE_NSECONDS period above
one second with a fraction among the cases that throw, since d71a1c577
made it work.
2026-10-24 10:08:01 +02:00
Dean cd435c58f4 Merge pull request #9227 from MaxLikesCode/fix/kqueue-snapshot-path-before-state
fix(libkernel): read a watched file's path before its state on Windows
2026-10-23 13:05:09 +13:00
Retr0 3383d303a7 fix(libkernel): move every knote kevent reports behind the waiting ones
FreeBSD 11.4 kqueue_scan (sys/kern/kern_event.c) puts a reported level
knote back at the tail of the queue and takes an EV_CLEAR or EV_DISPATCH
knote off it, and knote_enqueue queues that one at the tail when it fires
again. kevent moved a reported knote to the tail only while it stayed
triggered, so a level socket or pipe knote and a re-fired EV_CLEAR or
EV_DISPATCH knote kept their place and could starve later knotes when
nevents is smaller than the number of ready ones. Now every reported
knote that is not deleted moves to the tail.
2026-10-22 20:01:03 +03:00
frankea 41d551eb60 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into ps5-measured-1340
# Conflicts:
#	core/libs/prx/libSceSystemService/Export.cpp
2026-10-21 17:37:31 -04:00
aarushkha def751a787 fix(libkernel): reapply regular-file read events on top of watched equeues
Merge the file repoll into GatherInterests through WaitSet, so a wait on a
queue that watches another queue still polls regular-file events every
millisecond.
2026-10-21 23:46:39 +05:30
aarushkha feb03f696c fix(libkernel): reapply regular-file event fields on top of watched equeues 2026-10-21 23:46:37 +05:30
MaxandClaude Opus 5.5 e5569a8e35 fix(libkernel): read a watched file's path before its state on Windows
TakeSnapshot read the file information and then the path. A delete
between the two left a snapshot whose path was already under
\$Extend\$Deleted\ but whose link count and delete flag were not, so
IsDeleted was false and the watch thread asked for a parent watch of
\$Extend\$Deleted\. FindFirstChangeNotification refuses it with
ERROR_ACCESS_DENIED, and the exception on the detached watch thread
ended the process. guest_kqueue hit this when FileWatch removed its
file while a watch thread was still polling.

The path is now read first. A path under \$Extend\$Deleted\ is only
returned after the delete, so the information read after it reports
the delete and the parent watch is skipped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 17:24:48 +02:00
Retr0 41709ae50e fix(libkernel): move events reported by sceKernelWaitEqueue behind the waiting ones
FreeBSD 11 kqueue_scan (sys/kern/kern_event.c) re-inserts a reported
knote without EV_CLEAR or EV_DISPATCH at the tail of kq_head, and
knote_enqueue puts a knote that fires again at the tail as well, so the
next scan starts with the events that were not reported yet.
sceKernelWaitEqueue scanned the event list in place, so with num smaller
than the number of ready events the first ones were reported on every
call and the later ones starved. Each reported event that stays
registered now moves to the end of the list, in the order reported.
2026-10-21 15:41:06 +03:00
Federico Marras cc7b9a7652 Merge remote-tracking branch 'upstream/main' into feat/kqueue-read-on-kqueue
# Conflicts:
#	docs/dev/debt/libkernel.md
2026-10-21 13:17:12 +02:00
frankea 78926e215c Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into ps5-measured-1340
# Conflicts:
#	docs/dev/debt/libSceVideoOut.md
2026-10-20 22:01:26 -04:00
Dean c70524a3db Merge pull request #8596 from ebarr24/ws/libkernel-kevent-note-lowat-above-1-on-e
fix(libkernel): fire EVFILT_WRITE on a socket once free send space reaches NOTE_LOWAT
2026-10-21 08:27:05 +13:00
Adrià FranchandClaude Sonnet 5.5 c420b8d53d fix(main): skip the parent watch of a vnode already deleted at registration
Culprit: none in 892a4f1328..b85d972f42; race in the Windows vnode watch (50b06110b guarded only the loop). Run 39473930499, guest_kqueue: a watched file deleted before registration is snapshotted under $Extend\$Deleted, WatchParent got ERROR_ACCESS_DENIED and threw.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 20:49:45 +02:00
frankea 39e467915e Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into ps5-measured-1340
# Conflicts:
#	core/libs/prx/libScePad/Export.cpp
#	core/libs/prx/libScePad/src/PadState.cpp
#	core/libs/prx/libSceVideoOut/src/PadInput.cpp
#	core/libs/tests/GuestPad.cpp
2026-10-20 13:34:08 -04:00
Ethan Barr 084dcf8736 fix(libkernel): fire EVFILT_WRITE on a socket once free send space reaches NOTE_LOWAT
kevent threw NotImplemented for EVFILT_WRITE with NOTE_LOWAT above 1 on a socket, although the socket readiness check already reports free send-buffer space (SO_SNDBUF less SIOCOUTQ on Linux). The write event now fires once that space reaches the mark, as FreeBSD 11's filt_sowrite compares sbspace with kn_sdata, and stays silent while the space is below it. The debt entry no longer says a write mark is limited to 1. Reference: https://github.com/freebsd/freebsd-src/blob/release/11.0.0/sys/kern/uipc_socket.c
2026-10-20 13:32:17 -04:00
Federico Marras 5f6c30547e Merge remote-tracking branch 'upstream/main' into feat/kqueue-read-on-kqueue
# Conflicts:
#	docs/dev/debt/libkernel.md
2026-10-20 17:18:22 +02:00
Federico Marras 6ead14f9e8 feat(libkernel): watch a kqueue with EVFILT_READ 2026-10-20 16:56:06 +02:00
frankea 73bc20e93d Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into ps5-measured-1340
# Conflicts:
#	docs/dev/debt/libSceAgcDriver.md
2026-10-20 09:21:31 -04:00
Alexej Szpevák bd8ee518c4 feat(libkernel): support EVFILT_WRITE on the write end of a pipe
kevent threw for EVFILT_WRITE on any descriptor that is not a socket. On the write end of a pipe it now follows FreeBSD 11's filt_pipewrite: data is the free buffer space, and once the read end is closed the event reports EV_EOF with data 0. Adding the event after the read end is closed fails with EPIPE, as in pipe_kqfilter. EVFILT_WRITE on the read end still throws, because FreeBSD's pipe ends are bidirectional and host pipes are not.
2026-10-20 13:34:50 +02:00
Adam Franke 9a027c0c0d Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into ps5-measured-1340
# Conflicts:
#	docs/dev/debt/shader.md
2026-10-20 00:03:49 -04:00
Claude 5c6f6da7dc feat(libkernel): accept pipe read ends in sceKernelAddReadEvent
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-19 18:30:55 +00:00
Adam Franke f6b6d79aa8 fix(libkernel): return 0x80020000 | fflags from sceKernelGetEventError as a PS5 does
On a PS5 (firmware 13.40) sceKernelGetEventError returned 0 for fflags 0 and 0x80020000 | fflags otherwise, whatever flags and data held: {0x4000, 0, 22} -> 0, {0x4000, 5, 0} -> 0x80020005, {0x4000, 5, 22} -> 0x80020005, {0, 7, 22} -> 0x80020007, {0x8000, 3, 9} -> 0x80020003. fflags above 0xFFFF were not measured and throw.
2026-10-19 12:14:56 -04:00
Alexej Szpevák cb9a4c7417 feat(libkernel): support EV_CLEAR on sockets and pipes in kevent on Linux
kevent threw for EV_CLEAR on a socket or the read end of a pipe; Boost.Asio's kqueue reactor, among others, registers every socket that way. On Linux such a knote now watches its host descriptor through an edge watch. It is armed when added, on every later EV_ADD or EV_ENABLE while enabled, and by each host wakeup; when armed it is checked with the level-triggered readiness test and reported with the current data and EV_EOF, or disarmed if no longer ready, as kqueue_scan re-runs the filter; reporting it disarms it until the next edge. Waits block on the watch's epoll descriptor, so a socket that stays readable does not wake them. Windows and macOS still throw. GuestSockets::NativeDescriptor exposes the host socket behind a guest one for the watch.
2026-10-19 15:05:28 +02:00
Alexej Szpevák 7e67261d5f feat(libkernel): add an epoll edge watch over a host descriptor
FreeBSD activates an EV_CLEAR knote on each state change the object reports through KNOTE (sorwakeup, sowwakeup, pipeselwakeup), not on its level, so polling the level cannot tell an EV_CLEAR knote when to fire again. EdgeWatch::Watch registers the host descriptor with a private epoll instance in edge-triggered mode: every wakeup of the descriptor with a matching mask (data arriving, buffer space freed, a hang-up) queues one edge, which TakeEdge consumes, and the epoll descriptor itself is readable while an edge is pending, so a wait can block on it. Off Linux opening a watch throws.
2026-10-19 15:05:11 +02:00
Alexej Szpevák 5cbc46029b refactor(libkernel): let an equeue filter name the descriptor its waits block on
WaitForDescriptors always handed the knote's own descriptor to the host wait. A filter that tracks readiness through a descriptor of its own, such as an edge watch, needs the wait to block on that descriptor instead, or a descriptor that stays ready keeps waking the wait. KernelFilter gets a waitDescriptor, and the filter's owner is held for the length of the wait so the descriptor cannot be closed under it.
2026-10-19 15:05:10 +02:00
Adrià 9d4966c265 Merge pull request #6343 from klosixgaming-arch/feat/kevent-standard-input
feat(libkernel): accept a kevent read event on descriptor 0
2026-10-19 01:46:19 +02:00
HQasperandClaude Opus 5.5 6d4c7c3150 fix(libkernel): select on kqueues as kqueue_poll answers
A kqueue descriptor is readable while one of its events is triggered and
is never writable or exceptional, as FreeBSD's kqueue_poll answers, on
both hosts. On Windows select threw for it, and on Linux its /dev/null
placeholder was reported readable and writable.

A descriptor that stops being a socket, a kqueue or a pipe during the
wait now fails the call with EBADF when it was closed and is selected
again with the rest of the timeout when its number was reused, as
FreeBSD's kern_select looks every descriptor up again in each pass,
instead of throwing. On Windows a host descriptor that is not a pipe
throws when select starts, before waiting.

Depends on #7139.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 00:45:57 +02:00
klosixgaming-arch ce5b0c395b feat(libkernel): accept a kevent read event on descriptor 0
PPSA34015 (EA SPORTS FC 27) registers EVFILT_READ for descriptor 0 in a
new kqueue at start-up, ignores the result, and stopped with "kevent:
EVFILT_READ on a non-socket descriptor not implemented". A read event on
the host stream on descriptor 0 is now accepted and never triggers, as
select never reports descriptor 0 readable.
2026-10-17 21:34:51 +00:00
Dean d8f36fd749 Merge pull request #7206 from MarcZX100/codex/kevent-nanosecond-period
fix(libkernel): accept fractional nanosecond kevent periods
2026-10-18 10:01:02 +13:00
MarcZX100 d71a1c5775 fix(libkernel): accept fractional nanosecond kevent periods 2026-10-17 16:28:55 +00:00
milescovielloandClaude Opus 5.5 91fbafd94a fix(libkernel): keep refusing a read low-water mark above 1 on non-stream sockets
On Linux, FIONREAD on a datagram socket reports the next datagram only,
where FreeBSD's sbavail counts every queued byte, so a read mark above 1
there could never fire. kevent now throws for it as before; stream
sockets and marks of 1 are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 11:20:03 +00:00