Commit Graph

6 Commits

Author SHA1 Message Date
fdfawef324 81364388a0 fix(libSceFiber): run fibers on host stacks on Windows
#4265 gives each fiber an mmap'd host stack on Linux and leaves Windows
as it was: there a fiber still runs host calls inside the context the
title passed to sceFiberInitialize. Demon's Souls packs its 16 KiB job
fiber contexts back to back. A job that calls
sceAgcCreateInterpolantMapping reaches shader preparation on the fiber
(Driver::ResolveShaderAbi, PrepareRegistered, the RDNA decoder,
BuildShaderStageInputInfo), goes more than 16 KiB deep and overwrites
the frames at the top of the context below it. On the loading screen
after the opening cinematic the fiber that owns that context then
failed the title's stack check, or returned to 0x7fffffff.

On Windows each fiber now gets a host stack from VirtualAlloc, the
context size plus 1 MiB, committed like the 1 MiB host margin of guest
threads, with a PAGE_NOACCESS page at the bottom. While the fiber runs,
the TIB stack base and limit and the deallocation stack describe that
host stack, as Windows does for its own fibers, so stack probes and
GetCurrentThreadStackLimits see the stack the fiber runs on. A host
stack that cannot be allocated, protected or released throws instead
of falling back to the context.

agc_driver_gpu_map_on_fiber: GetCurrentThreadStackLimits on a fiber now
returns its host stack, which has room for the import, so on Windows a
GPU mapping made on a fiber imports on the fiber's stack instead of a
host thread. The fiber's context is still not written.

Test: on Windows, fiber checks that the TIB stack bounds inside a fiber
cover its host stack, at least the context plus 256 KiB. With #4265
alone it fails at "the thread's stack bounds are the fiber's host
stack", and without that check at "a host call from a 16 KiB fiber
writes nothing below its context"; with this change fiber and
agc_driver_gpu_map_on_fiber pass (Windows Server 2025, RTX 3060,
WinLibs GCC 15.2.0, Release).

Demon's Souls (PPSA01342) on that host: at the loading screen the two
16 KiB job fibers above the overwritten one now use 17,592 and 16,936
bytes of their host stacks, the title's stack check no longer fails
there, and the load goes on until a separate Vulkan allocation failure
(vkAllocateMemory of a 4 MiB host-visible buffer, out of device memory).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:37:23 +02:00
Joey Fisher 794714983c fix(libSceFiber): run fibers on host stacks with room for host calls
Host code that a guest fiber calls runs on the fiber's stack. Demon's
Souls (PPSA01341) gives its job fibers 16 KiB contexts packed next to each
other, and a fiber that reaches shader preparation through
Driver::ResolveGraphicsStagesAbi goes about 21 KiB deep when SPIRV-Tools
validates the module. That overwrites the saved frame of the fiber below,
and the next switch to that fiber pops garbage into rbp, rbx, r12-r15 and
rip (a jump to 0x1a in the observed crash).

Fibers now run on an mmap'd host stack of the context size plus 1 MiB,
with a guard page at the bottom, the same margin guest threads get since
#2647. The guest context is no longer written. Context size checks fill
and scan the top context-size bytes of the host stack, so
size_context_margin keeps its meaning. If the mapping fails the fiber
runs in its context as before. Windows is unchanged: it pins and
publishes the guest context as the stack, and that path is not covered
here.

The fiber test now runs a 256 KiB host call from a 16 KiB fiber placed at
the top of a guard-filled area and checks nothing below the context was
written. It fails on main.
2026-10-13 15:37:23 +02:00
Semir Kabir 5f123fd1b2 feat(libSceFiber): add the underscore thread frame pointer export 2026-10-11 09:30:02 -07:00
fma-rc ab0babdc9b
fix(libs): bind the system libraries eagerly on Linux
A title calls our exports on stacks it sized for the console. With lazy
binding the first call through a PLT slot runs the dynamic linker's symbol
lookup on that stack: on the 2 KiB fiber context Astro's Playroom uses it
wrote below the context into the neighbouring heap chunks.
2026-10-11 03:31:37 +02:00
Adrià Franch 62530c9d5c feat(libSceFiber): implement context size checking and the thread frame pointer
sceFiberStartContextSizeCheck and sceFiberStopContextSizeCheck toggle a
mode in which new fibers get their context filled with a pattern, so
sceFiberGetInfo can report the unused stack margin.
sceFiberGetThreadFramePointerAddress returns the frame pointer of the
thread that called sceFiberRun.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 19:27:24 +02:00
Dean Galvin ba9201874f feat(fiber): implement fibers on linux
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 19:46:38 +13:00