[Cpu] Stop guest threads at their next import once the host shuts down
Host shutdown only kept guest threads from starting another slice; a thread already inside guest code kept calling HLE while the services behind it were torn down. Superliminal's job threads then got a null command buffer from the GPU library, wrote through it, and the process died with SIGSEGV on its way out. After shutdown is requested an import now returns to the host entry stub instead of running, ending that thread's slice; the scheduler already refuses to enter guest code again. (cherry picked from commit 9e0e8ec0aa8b0bfaa030e5e97d51dbc0223f93e1)
This commit is contained in:
parent
5ac730ca05
commit
70d1d2f443
|
|
@ -340,6 +340,14 @@ public sealed partial class DirectExecutionBackend
|
|||
Console.Error.WriteLine(
|
||||
$"[LOADER][TRACE] bootstrap_call#{num}: op=0x{value:X16} sym_ptr=0x{value2:X16} sym='{symbolText}' out_ptr=0x{num3:X16} ret=0x{num7:X16}");
|
||||
}
|
||||
// Once the host is shutting down, a guest thread still running reaches no more HLE: the
|
||||
// services behind the imports are being torn down, and a title that sees them fail (a null
|
||||
// command buffer from the GPU library, say) crashes the process on its way out.
|
||||
if (_forcedGuestExit && !ActiveForcedGuestExit && TryEndGuestSliceForShutdown(argPackPtr))
|
||||
{
|
||||
cpuContext[CpuRegister.Rax] = 1uL;
|
||||
return 1uL;
|
||||
}
|
||||
if (!isGuestWorker &&
|
||||
!ActiveForcedGuestExit &&
|
||||
ShouldForceGuestExitOnImportLoop(in importStubEntry, num7, num, value, value2))
|
||||
|
|
@ -1794,6 +1802,20 @@ public sealed partial class DirectExecutionBackend
|
|||
}
|
||||
}
|
||||
|
||||
// Returns the import straight to the host entry stub, which ends this guest slice.
|
||||
private unsafe bool TryEndGuestSliceForShutdown(nint argPackPtr)
|
||||
{
|
||||
ulong sentinel = ActiveEntryReturnSentinelRip;
|
||||
if (sentinel < 65536 || !TryPatchActiveGuestReturnSlot(sentinel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*(ulong*)(argPackPtr + 96) = sentinel;
|
||||
ActiveForcedGuestExit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private unsafe bool TryForceGuestExitToHostStub(nint argPackPtr, long dispatchIndex, ulong returnRip, string nid)
|
||||
{
|
||||
ulong num = ActiveEntryReturnSentinelRip;
|
||||
|
|
|
|||
Loading…
Reference in New Issue