libkernel exported scePthreadAttrSetschedpolicy and
scePthreadAttrSetinheritsched but not the matching getters,
scePthreadAttrGetschedpolicy (NID NMyIQ9WgWbU) and
scePthreadAttrGetinheritsched (NID lpMP8HhkBbg), so a title that
imports either one stopped at startup on the unresolved import. Dragon
Ball Xenoverse 2 (PPSA08587) imports both.
Implement them as FreeBSD 11.4 libthr implements
pthread_attr_getschedpolicy and pthread_attr_getinheritsched
(lib/libthr/thread/thr_attr.c): a null or uninitialized attribute
returns EINVAL (0x80020016), as does a null output of
scePthreadAttrGetschedpolicy; otherwise the attribute's policy or
inheritance is stored and 0 is returned. libthr writes through a null
output of the inheritance getter unchecked, so that case throws, as
pthread_attr_getinheritsched and scePthreadAttrGetsolosched do.
Neither getter was measured on a console. The scePthreadAttr entry in
docs/dev/debt/libkernel.md, which describes the calls measured on a
PS5, now says so and records the throw.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The process_vm_readv probe answered a small read check before the page
table was looked at, so a page the table holds as inaccessible (as #6184
records them) read as accessible whenever the host page was readable. The
probe now runs only for ranges with no recorded page state.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On Linux kernels without PROCMAP_QUERY (before 6.11, which includes the
stock Ubuntu 24.04 kernel), every guest range check that misses the page
cache reads and parses /proc/self/maps up to the covering mapping. The
cache only covers the guest arena and the image, so ranges in the host
heap always miss. ASTRO BOT (PPSA21564) checks 96-byte shader headers
there from RegisteredHeader (through SameHeader) on every
sceAgcCreatePrimState and interpolant mapping, about 3,700 times per
second while it loads.
A read-only check of at most 4 KiB on such a kernel now first reads the
range into a scratch buffer with process_vm_readv on the own process.
If every byte is read, the range is readable. Anything else (a fault,
a partial read, a refused call, a write check or a larger range) takes
the path it took before, which also builds the failure message.
agc_driver_graphics runs a second time with APS5_NO_PROCMAP_QUERY=1, so
the fallback path is covered on kernels that have PROCMAP_QUERY too, and
LiveStack gains read-only checks: a readable range, and ranges that end
in a guard page.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceNetCtlRegisterCallback and sceNetCtlRegisterCallbackV6 stored only
the function and dropped its argument, and sceNetCtlCheckCallback
returned 0 without calling anything, so a title that polls
sceNetCtlCheckCallback until its callback reports IPOBTAINED never
got the event.
Each callback slot now keeps the function, its argument and the last
event it received; unregistration clears the slot. With no IPv4
callback registered, sceNetCtlCheckCallback returns 0 without querying
the host. Otherwise it takes the state from the same host-interface
predicate as sceNetCtlGetState, IPOBTAINED (3) or DISCONNECTED (1)
(shadPS4 src/core/libraries/network/net_ctl_codes.h L27-29
@15abf68c9b52), marks the IPv4 slots whose last event differs and
calls them on the calling thread with their argument after the lock is
released, so a callback can unregister itself. Delivery once per state
change and slot follows KytyPS5 src/libs/network.cpp @9e41d8320a27
(NetCtlCallbackSlot L3447-3451, NetCtlCheckCallback L3648-3661,
NetCtlRegisterCallback L3687-3707); shadPS4 net_ctl_obj.cpp L47-57
delivers on every check instead, and the debt entry records the
difference and that KytyPS5 calls the callbacks under its lock.
sceNetCtlTerm clears both tables, as KytyPS5 NetCtlTerm (L3625-3633)
does. V6 slots keep their argument but get no event, since no source
says which call delivers them.
NetCtlCallback is now an APS5_VABI pointer, so the Windows build calls
the guest function with the System V ABI.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Rosetta sets RDTSCP's ECX to its constant TSC_AUX, 0xAAAAAAAB, which is
not a processor index. --to-rosetta already makes RDPID return processor
0 for the same reason, so code reading the processor through RDTSCP saw
a different value from code reading it through RDPID.
--to-rosetta now moves RDTSCP into an optional stub that runs the
instruction unchanged and then loads 0 into ECX with a MOV, which
leaves the counter in EDX:EAX and the flags as they were. A site with no
movable instruction after it for the jump is kept, as for RDPID. The
Intel target and a plain relink are unchanged.
A glc or dlc buffer_store_dwordx2 is one 64-bit write on the GPU, so a
workgroup that polls a {flag, value} pair never sees the flag without
its value. It was emitted as two dword stores, and the coherent dwordx2
load was one 64-bit read only in programs with 64-bit buffer atomics,
the only ones that had the u64 storage-buffer view.
GTA V builds each BLAS with a single-pass decoupled look-back scan that
publishes its tiles' pairs with buffer_store_dwordx2 and has no 64-bit
atomics. A tile read an earlier tile's new flag with its old value 0,
the scan came out short, the BVH got overlapping nodes and the refit
kernel looped until the device was lost.
A program with a coherent raw two-dword buffer load or store now has
the u64 view whenever the device has shaderBufferInt64Atomics. Such a
store whose dwords are in bounds, adjacent and 8-byte aligned is one
device-scope OpAtomicStore. The load takes the same condition, which
now also checks the second dword's bounds and that the dwords are
adjacent. All other accesses keep the per-dword path.
LookBackScan also runs its kernel with the two buffer_atomic_swap_x2
replaced by glc buffer_store_dwordx2. Without this change that variant
fails its first whole scan.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The RDNA2 ISA (8.1.7) ignores the two low address bits of dword or wider
non-formatted accesses in alignment mode DWORD. MXGP 26 (PPSA30839) sets
bits with buffer_atomic_or at odd byte offsets, which recorded an
unaligned BDA fault and dropped the atomic. A 32-bit buffer atomic now
acts on the dword that holds its address; 64-bit atomics off an 8-byte
boundary still fault.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
10_11_11_UNORM (format 30) images are read and written through an
R32_UINT view, so the hardware sampler cannot filter them. image_sample
of a 2D or 2D array view now fetches the one or four texels at LOD 0,
decodes them and blends them in the shader, with bilinear weights on
the 8-bit grid, for point or bilinear filtering with wrap or
clamp-to-edge addressing.
A shader gets the converted sample mode only after a converted
descriptor reaches one of its sampled images: that capture throws
ConvertedSampleRequired and the driver prepares the program again
with GuestContext::convertedSamples.
The R10_G11_B11 float format is sampled natively since #7271 and keeps
its refusal on the converted path.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceSystemGestureUpdatePrimitiveTouchRecognizer reads the pad reports the title
passes in and tracks every touch as a primitive, so the primitive event queries
report begin, active and end events with their pressed and current positions,
delta vector, delta time and elapsed time instead of reporting that no touch
input exists. sceSystemGestureGetPrimitiveTouchEventByPrimitiveID no longer
throws for a tracked touch.
FreeBSD alarm() is setitimer(ITIMER_REAL), and setitimer fails with EINVAL
for it_value.tv_sec above INT32_MAX / 2, so alarm() returns -1 and leaves
the pending alarm alone. alarm(UINT_MAX) armed an alarm decades away and
returned the old remaining time instead.
(cherry picked from commit 2dea16d07d4e0b36e4a3d1eebe3b5c3ffb739807)
hardware_oracle_compare started compare_results.py in a new Python
process for every case, 77 interpreter starts. That takes 5-16 s
on the macOS relinker runners against the test's 20 s timeout, and the
x86_64 job timed out at 20.14 s in run 39103831688 on a pull request
that does not touch the oracle tools.
Call compare_results.main() in the test process with sys.argv patched
and stdout and stderr captured, and keep the identical and differing
cases as real subprocesses so the exit status of the script entry point
stays covered. The test drops to under 1 s.
A 64-lane program that doesn't stop invocations reads one dword per lane at
0xfff00 + low over a table whose first range is [0x100000, 0x100010): one
lane below the first range, one past its end, one at its last dword and the
others at its start. The unmapped lanes must read zero with the unmapped
fault recorded, the others their dword, and every read kind must match the
anchored program.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The lookups returned from each failed check. On NVIDIA 595.99 a subgroup
whose invocations left `get_bda_pointer` or `probe_bda_pointer` through three
different returns (one past a range's end, one below the first range and one
that found its range) never finished (Xid 109), which is how #5859's
anchor tests hang `agc_driver_bda_device`. Each check now branches to the end
of a single-pass loop, where a phi takes the result, and the function
returns once. The lookups stay DontInline.
Co-Authored-By: Claude Opus 5.5 <[email protected]>