A protect below the main thread's stack mapping mapped only the
protected pages. Linux keeps a growing stack one guard gap (1 MiB by
default) above a readable mapping, so after a read-only protect, or a
protect later restored to read/write, at the bottom of the reported
stack the stack could no longer grow into the megabyte above it and a
deep enough call faulted where the console has stack pages. The pages
between the protect and the top of the stack are now mapped as well,
so the stack never has to grow past them.
The entry now sits with the other sceKernelMprotect entries for
DirectMemory.cpp, before the Windows guest module image protection one,
instead of after the setcontext entry, where #5918 adds its own.
HotSpot makes its stack guard zones with an RW protect of the lowest
pages of the thread's stack, then PROT_NONE, as it commits them on
native Windows (os::pd_create_stack_guard_pages, then os::guard_memory).
Below a host stack's guard page such a protect was only recorded, so the
pages stayed reserved: they could not be written after the RW protect,
and the zones never held.
A protect of reserved pages that starts at the bottom of the reserve and
stops short of the guard page now commits and protects them. The guard
page and the reserve above the range stay as they are, so the stack still
grows through the guard down to it, and the stack limit in the TEB still
follows the committed stack.
Windows moves the guard down by committing the pages below it as
read/write guard pages, committed or not. The zones therefore hold until
the stack is within one guard region of them (three pages on GitHub's
runners), and the pages the guard reaches then come in read/write. The
test checks both, and the debt entry says so.
Committing the reserved pages of a host thread's stack before protecting
it, as the stack branch did for a range the arena doesn't own, also
cleared the guard page's PAGE_GUARD. The thread was left with no guard
and no reserve: an overflow ran into whatever lay below the stack instead
of raising a stack overflow, and the stack limit in the thread's TEB,
which Windows moves only when the guard page is hit, stopped following
the stack. A range that began inside the reserve also left the reserved
pages below it with no guard above them, so the stack could no longer
grow into them.
The stack branch now leaves the guard page and the reserved pages below
it as they are, and commits and protects only what lies above them;
reserved pages above the guard are still committed first. The protection
is recorded for the whole range, and a range of only reserved and guard
pages changes nothing on the host. The test protects the main thread's
whole stack and a reserved thread's whole stack and upper part, then
checks that the guard page is still there and that the stack grows
through it, also after a PROT_NONE protect of its lowest page. The debt
file records that those pages come in read/write as the stack grows.
Git for Windows 2.56 (runner image 20261002) moved from mingw64 to ucrt64,
so the fixed SSL_CERT_FILE path no longer exists and the WinLibs CMake
fails the FFmpeg download with status 60 on every Windows build. Take the
bundle from whichever of ucrt64 and mingw64 exists.
Co-Authored-By: Claude <noreply@anthropic.com>
A multisampled depth target is created as, or already is, the native depth owner, and a target whose HTILE overlaps a resident depth guard aliases one. Neither may have its HTILE read or rewritten by the generic store-back: the expanded words would be a guest write over the owner's range. DepthSurfaceView decides this before the store-back, which still runs before GpuMutex() and the surfaces mutex are taken. NativeMultisampleDepth binds the owner and a single-sample alias of its HTILE and checks the words stay untouched.
A fill or clear the driver recognizes over an HTILE drops the range's last-read generation, so the
next bind reads the words and stores them back even when the write tracker did not see the fill's
stores. A depth view of slice 1 or later reads the HTILE at its own address
(DB_HTILE_DATA_BASE + slice * HtileMetadataBytes); the HTILE word layout is only modelled for slice 0,
so such a slice takes the clear and the store-back only when all its words are equal and keeps its
fill-time fast clears otherwise. DepthTarget::slice carries DB_DEPTH_VIEW SLICE_START.
agc_driver_depth_fast_clear_submit: an unrecognized kernel clears the HTILE on two frames in a row and
both clears are taken; slice 1 with words that are not all equal is refused and stored back untouched;
slice 1 with equal words takes the clear. agc_driver_graphics checks the decoded slice.
The bind-time HTILE read covered one word per 8x8 tile from DB_HTILE_DATA_BASE, but main models the
HTILE as the pipe-aligned SW_64KB_Z_X metadata (HtileMetadataBytes, the extent HtileFillCovers takes):
at 1920x1080, 1856 of the 32400 tile words lie past the first tiles*4 bytes, so they kept ZMask 0
after a store-back. The read and the store-back now cover the whole metadata and run before the
surfaces mutex is taken, since both wait for recorded work over the range. The tests' HTILE arrays
hold the whole metadata.
PPSA25344 (Unreal Engine 5) decodes its depth through HTILE in its Nanite depth export after the
depth prepass and takes ZMask 0 as a tile holding the clear value; the new
agc_driver_depth_fast_clear_submit case checks that a draw after a fast clear leaves every word
expanded.
A sampler voice set up with an all-zero format has no channels. Adding no
waveform blocks to it, or setting a matrix with no levels, threw
std::invalid_argument, which ends the title.
Accept both on such a voice: the empty add only applies RESET and the
CONTINUE state, and the empty matrix clears that matrix, which rendering
already treats as unset. Blocks with data, APPEND, and an empty matrix on
a voice with a format are still refused.
Steins;Gate Re:Boot (PPSA36591) clears a voice this way when a button is
pressed at its title screen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>