Address review: check the msghdr, iovec array, iovec bases and name
are mapped before MessageLength or the receive loop touches them,
pairing the HostWrite guard with committed-range validation. Add
regression tests for forged iovec-array and output pointers.
recvmsg_nid_postfix wrote the msghdr, every iovec base and the sender
address with only null checks, unlike recv_nid_postfix and the
sceNetRecvfrom sender outputs which all gate on GuestArena::HostWrite.
Validate the message, each iovec base and the name buffer the same way
so a forged pointer fails with EFAULT instead of writing received bytes
to an arbitrary host address.
Add sceSysmoduleUnloadModuleInternalWithArg to match the existing
sceSysmoduleLoadModuleInternalWithArg export. Decrement the module load
count on valid internal IDs, check module existence in kModuleTable,
and set the return pointer when provided.
Add unit test coverage in GuestSysmodule for invalid values, unloaded
modules, successful argument unload, and unknown IDs. Update technical
debt documentation.
A guest buffer region that is copied rather than imported gets a buffer
with storage (and, when addressable, device-address) usage only. Host
imports, sparse imports and chunk imports carry VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
so a buffer view of imported guest memory can be read back with
vkCmdCopyBuffer, but not one of a copied region. agc_sparse_run_import_copied
does that readback, and the Khronos validation layer reports
VUID-vkCmdCopyBuffer-srcBuffer-00118 for it.
Copied regions now carry transfer-source usage too. The sparse buffer
hole tests seed the buffer pool with the usage a copied region asks for,
so their seed buffer gets transfer-source usage as well.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Adds what testers reported in the Q&A thread and what our own runs
showed: confirming the GPU and the cache state, AC power and refresh
rate, the Windows exit code of an uncaught exception, Windows session
and scheduled-task start, Unity module placement and the MinGW DLLs,
a section on measuring performance, and the report fields.
Drops APS5_NO_MOUSE_CAPTURE, which main no longer has.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BywPXoZACVi8ALV4JKvuPZ
A report names the GPU as the log's `Selected GPU name=` line shows it, since AnyPS5 can fall back to llvmpipe without presentation support or pick another adapter on Windows (suggested by odntht on #6627).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BywPXoZACVi8ALV4JKvuPZ
Draft guide for running a title on AnyPS5: the build and conversion steps,
the environment variables to set for each run, what to read in the log and
the exit code, how to tell a stall from a crash, Windows-specific notes, and
what to include when reporting a result. Maintainers are asked what they need
from it in the Q&A discussion linked from the page.
Co-Authored-By: Claude Haiku 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BywPXoZACVi8ALV4JKvuPZ
Off Windows, the GPU fill case now runs with host imports kept watched, so it
always checks the absorbed clear, and a new case runs it with imports left
unwatched, which must be refused. On Windows a settled import is watched again
when its settle is polled, possibly before the draw takes the fill, so an
unwatched fill may be either refused or drawn, and a drawn one is checked.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
When a fill of the metadata could not be taken because one of its ranges was
no longer watched, the check reached a watched range that the fill had
changed first and reported the write instead of the unwatched range.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A multisampled DCC color target imports its uniform DCC fast clear on
first use and then refuses any later change to its color, DCC or CMASK
memory. Titles built on the PS5 Mesa stack fast-clear such a target
every frame with two buffer fills, the CMASK to 0xcc (FMASK cleared,
color expanded) and the DCC to a uniform clear key, so the second
frame stopped on "writes to a resident multisampled DCC target or its
metadata are not implemented".
The fills of a resident DCC target's metadata are now noted. When a
fill covered the whole DCC range since the last use and the range holds
its key once pending writes land (LandedUniformMetadataByte, which
reads the bytes directly rather than through the resident read guard),
the next use clears every sample to that key's color, as the import
does, and takes the new DCC and CMASK generations. A CMASK written
since must have been filled whole too. Partial fills, other keys,
CMASK-only writes and any write to the color memory are still refused.
Fills of a DCC target's CMASK no longer go to the CMASK-only fast-clear
tracker, which refused the expanded code 0xcc.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
An indirect draw drained queue 0's draw pipeline on entry and recorded every
record on the worker, so titles that draw mostly through DRAW_INDIRECT,
DRAW_INDEX_INDIRECT and DRAW_INDEX_INDIRECT_MULTI got no overlap between the
worker's capture of one draw and the committer's recording of the previous.
The draw now drains only when its records or its count overlap a write still
queued on the pipeline. Records drawn inline drain first, so they stay in
order, and the last drawn record is queued like a direct draw, carrying its
write ranges. APS5_NO_PIPELINED_INDIRECT=1 restores the drain on every
indirect draw.
agc_driver_pipelined_indirect_draw holds the committer with a blocking item and
checks that two indirect draws queue behind it and draw what a direct draw
does, and that a draw whose record a queued label writes waits for it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PPSA26578 (issue #7624) imports tgammaf (NID B2ZbqV9geCM) from libc,
and its bundled libc.prx does not export it, causing the process to
exit with 0xC0000139 (GetLastError: 127).
Export tgammaf_nid_postfix in core/libs/prx/libc/src/Math.cpp delegating
to std::tgamma(float), and add unit test coverage in GuestMath
verifying factorials, half-integers, poles, and negative values.
The saver thread took the snapshot lock with a blocking exclusive lock. Behind
a pipeline creation that runs for minutes (an NVIDIA compile of a 1.5M-word
compute pipeline), the queued writer made the shared_mutex hold every later
pipeline creation on every queue until the compile ended. The periodic save now
tries the lock and waits for the next interval when it is busy; SaveNow and the
teardown save still wait.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PPSA26578 (issue #7624) imports nextafter (NID h+J60RRlfnk) from libc,
and its bundled libc.prx does not export it, causing the process to
exit with 0xC0000139 (GetLastError: 127).
Export nextafter_nid_postfix in core/libs/prx/libc/src/Math.cpp delegating
to std::nextafter(double, double), and add unit test coverage in
GuestMath verifying denormals, infinities, NaNs, and negative zero.
Kena's cached-space hits have no copied ranges, so the memo of their
committed pages saved nothing (imports pass 0 us per build with and
without it), and keeping it current needed a second commit-generation
bump in libc. The space is still stamped once per hit; the test that
commits pages between two hits stays.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The memo of a cached address space's committed pages is published
lock-free and rebuilt when the arena's commit generation moves, which a
commit now advances again when it ends. A trimmed space's last hit
moves back to its imports, and the space hit longest ago is trimmed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A hit in the read-only V# address-space cache described the committed
pages of every copied range again and stamped the space once per import.
The cached space now keeps its copied ranges' committed pages and is
stamped once per hit. APS5_NO_SPACE_COMMIT_MEMO=1 and
APS5_NO_SPACE_STAMP_ONCE=1 turn the two parts off.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PPSA26578 (issue #7624) imports _ZSt26_Throw_bad_optional_accessv (NID
KwzEip7m6TM) from libc, and its bundled libc.prx does not export it,
causing the process to exit with 0xC0000139 (GetLastError: 127).
Implement std::bad_optional_access type record and vtable deriving from
std::exception, thrown through ThrowPlain, with what() returning
"bad_optional_access", and add unit test coverage in ExceptionRuntime.
As for the f64 rounding test: on a device without f64 DenormPreserve, a
mismatch in the modes that keep f64 denormals is reported as skipped;
the modes that flush them are still checked everywhere.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
v_add_f64 and v_mul_f64 ignored the FLOAT_MODE f16/f64 denormal field.
On RDNA2 (gfx1031) bit 6 clear flushes both inputs to a zero of their
sign, and bit 7 clear flushes a sum below 2^-1022 and a product whose
exact value rounded to 53 significant bits with an unbounded exponent
is below 2^-1022. The product test scales one source by 2^64 and
compares the host product with 2^-958.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
In a payload process on a PS5 (firmware 12.70),
sysctlbyname("kern.rng_pseudo") answers a size query with 64 and gives
at most 64 bytes per call, up to a 65536-byte buffer. A buffer smaller
than 64 bytes gets as many bytes as its length and a null length gets
none, both with -1 and ENOMEM; a null buffer with a null length returns
0, and errno is kept when the call succeeds. Here the whole buffer was
filled, a size query threw and the length was never changed. The 64
random bytes are now drawn only for a read that passes both a buffer
and a length.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <[email protected]>