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)
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]>
An adopted thread (the main thread, or a host thread that calls
scePthreadSelf) reported its whole Windows stack reservation, and so
did sceKernelIsStack on a host thread before adoption. A relinked
executable reserves 0x210000 bytes for its main thread and commits the
top 0x200000, so the lowest 64 KiB of the reported stack hold only
reserved pages and Windows' guard pages. mprotect fails there, so
HotSpot in Java 25 LAN / DNS (PPSA99869) could not create the main
thread's stack guard pages ("Attempt to allocate stack guard pages
failed").
When everything above the bottom allocation granule is committed
read-write, the host stack is now reported from there, as created
guest threads report only their committed stack. Other host stacks
keep the whole range. The committed-pages walk is shared with
StartNativeThread and throws when VirtualQuery fails.
Return SCE_APP_CONTENT_ERROR_NOT_MOUNTED instead of throwing APS5_INVALID_ARG_EX when a mount point other than /download0 is passed to sceAppContentDownloadDataFormat or sceAppContentDownloadDataGetAvailableSpaceKb, aligning with sceAppContentTemporaryDataFormat. Check null mount_point in sceAppContentDownloadDataGetAvailableSpaceKb with SCE_APP_CONTENT_ERROR_PARAMETER.
Measured from a payload process on a PS5 (firmware 12.70), where
__inet_ntop/__inet_pton and the plain inet_ntop/inet_pton exports
resolve to the same functions:
- inet_ntop follows an AF_INET6 result with zero bytes up to size (sizes
4 to 65536 sampled) and never writes past size; AF_INET writes only the
text and its NUL.
- An unsupported family returns EAFNOSUPPORT first, even with null
pointers.
- A null source or text raises SIGSEGV during the call, before the size
is checked; here it throws instead of returning EFAULT.
- A null destination is reached only after the size check and the text
parse: ENOSPC for a size that is too small, 0 for text that does not
parse, and SIGSEGV (a throw here) otherwise.
The test pins the measured inet_pton and inet_ntop rows, including all
inputs the existing assertions use. The text-form debt entry is replaced
by one that records what a payload process measured (the text forms, the
order of the checks and the padding) and what is still assumed: the
sizes that were not sampled, sizes above 65536, and a title process.
inet_ntoa_r calls __inet_ntop, so a null inet_ntoa_r buffer with room
for the text now throws, and a null buffer that is too small sets ENOSPC
instead of EFAULT; the libSceLibcInternal debt entry says so.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The console's libSceLibcInternal.sprx (measured on firmware 12.70 in
#7549) prints %p as bare lowercase hex without a 0x prefix, prints 0 for
a null pointer, ignores #, + and the space flag, counts only the digits
towards the width, pads with spaces on the left (on the right for - and
with zeros for 0 when there is no precision), treats the precision as
the minimum number of digits, prints nothing for a null pointer under
%.0p, and accepts the l length. FormatPointer instead followed FreeBSD
and printed 0x..., which is what a title does not see on hardware.
FormatPointer now prints the digits alone, the narrow Windows formatter
accepts %lp, and Linux routes %p and %lp to the guest formatter instead
of glibc, which prints the FreeBSD form and (nil) for a null pointer.
The wide family still refuses %lp, because the console's swprintf was
not measured with it; it returns -1 as it does for any other conversion
the formatter rejects. The debt note records the pointer cases the
console was not measured with and what the Linux routing means for a
format that mixes %p with a refused conversion.
A store through a V# the shader computes (EmitBdaWrite) still emitted its
byte path inline: one get_bda_write_pointer lookup, a mapped check, a byte
store and a note_bda_write per byte, five write lookups per 32-bit store.
It now calls write_bda_bytes after the same overflow check, like stores
through bound V#s since 70a884408; the helper does the same lookup, store
and note per byte in order, so faults are recorded as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Since 6158444 trims zero raw data, the far-gap executable is the same size
with and without the sparse load image, so the size checks no longer fail
without the fix. The test now also checks the peak memory of the Windows
and macOS conversions where the resource module is available: 4.3 GB
without the fix, a few MB with it, against a 512 MiB limit.
Reported by simonbronk in the review.
scePadRead_nid_postfix and scePadReadState threw APS5_INVALID_ARG_EX (std::invalid_argument) when passed a null output buffer or a non-positive buffer count, terminating the guest process across the PRX ABI boundary.
Both functions now return PAD_ERROR_INVALID_ARG (-2137915391) on invalid arguments, matching the error return contract of all sibling libScePad APIs.
macOS does not support getsockopt with SO_ACCEPTCONN; it fails with
ENOPROTOOPT. So on macOS the guest's getsockopt of SO_ACCEPTCONN failed,
connect did not see that a stream socket was listening (an address of
another family failed with EAFNOSUPPORT instead of EOPNOTSUPP), and the
read event of a listening socket reported FIONREAD's 0 instead of the
waiting connection and did not ignore its low watermark.
On macOS the listening state is read from the SO_ACCEPTCONN flag of the
socket options that proc_pidfdinfo reports, and the three places that ask
go through NativeListening. Other hosts keep getsockopt.