From 741446b503f4948cac5c431398104e95eb20a937 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 22 Sep 2024 08:17:32 -0700 Subject: [PATCH] SignalDelegator: Let the frontend inform AVX support Since the frontend has changed to informing the backend if AVX is supported, there is no reason to feed that configuration back in to SignalDelegator from the backend. Instead inform the SignalDelegator directly in the frontend instead of this now weird round-about path. --- FEXCore/Source/Interface/Core/Core.cpp | 2 -- .../include/FEXCore/Core/SignalDelegator.h | 2 -- Source/Tools/FEXLoader/FEXLoader.cpp | 4 ++- .../LinuxSyscalls/SignalDelegator.cpp | 20 +++++------ .../LinuxSyscalls/SignalDelegator.h | 6 ++-- .../SignalDelegator/GuestFramesManagement.cpp | 34 +++++++------------ 6 files changed, 29 insertions(+), 39 deletions(-) diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 46cedca69b..8844cf5935 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -321,8 +321,6 @@ bool ContextImpl::InitCore() { // Set up the SignalDelegator config since core is initialized. FEXCore::SignalDelegator::SignalDelegatorConfig SignalConfig { - .SupportsAVX = HostFeatures.SupportsAVX, - .DispatcherBegin = Dispatcher->Start, .DispatcherEnd = Dispatcher->End, diff --git a/FEXCore/include/FEXCore/Core/SignalDelegator.h b/FEXCore/include/FEXCore/Core/SignalDelegator.h index f33d1dd423..315da6a9e6 100644 --- a/FEXCore/include/FEXCore/Core/SignalDelegator.h +++ b/FEXCore/include/FEXCore/Core/SignalDelegator.h @@ -40,8 +40,6 @@ class SignalDelegator { virtual ~SignalDelegator() = default; struct SignalDelegatorConfig { - bool SupportsAVX {}; - // Dispatcher information uint64_t DispatcherBegin; uint64_t DispatcherEnd; diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index 8a0b45b6a0..2c590aa1c4 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -498,16 +498,18 @@ int main(int argc, char** argv, char** const envp) { // System allocator is now system allocator or FEX FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); + bool SupportsAVX {}; fextl::unique_ptr CTX; { auto HostFeatures = FEX::FetchHostFeatures(); CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures); + SupportsAVX = HostFeatures.SupportsAVX; } // Setup TSO hardware emulation immediately after initializing the context. FEX::TSO::SetupTSOEmulation(CTX.get()); - auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName); + auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName, SupportsAVX); auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get()) : FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), std::move(Allocator)); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp index 6863034127..a19e07d58e 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp @@ -118,7 +118,7 @@ void SignalDelegator::SpillSRA(FEXCore::Core::InternalThreadState* Thread, void* Thread->CurrentFrame->State.gregs[i] = ArchHelpers::Context::GetArmReg(ucontext, SRAIdxMap); } - if (Config.SupportsAVX) { + if (SupportsAVX) { // TODO: This doesn't save the upper 128-bits of the 256-bit registers. // This needs to be implemented still. for (size_t i = 0; i < Config.SRAFPRCount; i++) { @@ -178,8 +178,6 @@ ArchHelpers::Context::ContextBackup* SignalDelegator::StoreThreadState(FEXCore:: } void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thread, void* ucontext, RestoreType Type) { - const bool IsAVXEnabled = Config.SupportsAVX; - uint64_t OldSP {}; if (Type == RestoreType::TYPE_PAUSE) [[unlikely]] { OldSP = ArchHelpers::Context::GetSp(ucontext); @@ -203,7 +201,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(siginfo_t); GuestSP = FEXCore::AlignUp(GuestSP, alignof(siginfo_t)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86_64::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86_64::xstate)); } else { @@ -221,7 +219,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(SigFrame_i32) - 8; GuestSP = FEXCore::AlignUp(GuestSP, alignof(SigFrame_i32)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -238,7 +236,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(RTSigFrame_i32) - 4; GuestSP = FEXCore::AlignUp(GuestSP, alignof(RTSigFrame_i32)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -833,9 +831,10 @@ void SignalDelegator::QueueSignal(pid_t tgid, pid_t tid, int Signal, siginfo_t* } } -SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName) +SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX) : CTX {_CTX} - , ApplicationName {ApplicationName} { + , ApplicationName {ApplicationName} + , SupportsAVX {SupportsAVX} { // Signal zero isn't real HostHandlers[0].Installed = true; @@ -1295,7 +1294,8 @@ uint64_t SignalDelegator::GuestSignalFD(int fd, const uint64_t* set, size_t sigs return Result == -1 ? -errno : Result; } -fextl::unique_ptr CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName) { - return fextl::make_unique(CTX, ApplicationName); +fextl::unique_ptr +CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX) { + return fextl::make_unique(CTX, ApplicationName, SupportsAVX); } } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h index ac6cd02429..8541b789a7 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h @@ -50,7 +50,7 @@ class SignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::A // Returns true if the host handled the signal // Arguments are the same as sigaction handler - SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName); + SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX); ~SignalDelegator() override; // Called from the signal trampoline function. @@ -274,7 +274,9 @@ class SignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::A std::mutex HostDelegatorMutex; std::mutex GuestDelegatorMutex; + bool SupportsAVX; }; -fextl::unique_ptr CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName); +fextl::unique_ptr +CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX); } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp index 3b32cd5cfe..01cd8a68a6 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp @@ -110,8 +110,6 @@ static void SetXStateInfo(T* xstate, bool is_avx_enabled) { void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - auto* guest_uctx = reinterpret_cast(Context->UContextLocation); [[maybe_unused]] auto* guest_siginfo = reinterpret_cast(Context->SigInfoLocation); @@ -155,7 +153,7 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa // Copy float registers memcpy(Frame->State.mm, fpstate->_st, sizeof(Frame->State.mm)); - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -176,8 +174,6 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - SigFrame_i32* guest_uctx = reinterpret_cast(Context->UContextLocation); // If the guest modified the RIP then we need to take special precautions here if (Context->OriginalRIP != guest_uctx->sc.ip || Context->FaultToTopAndGeneratedException) { @@ -228,7 +224,7 @@ void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thre } // Extended XMM state - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -249,8 +245,6 @@ void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thre void SignalDelegator::RestoreRTFrame_ia32(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - RTSigFrame_i32* guest_uctx = reinterpret_cast(Context->UContextLocation); // If the guest modified the RIP then we need to take special precautions here if (Context->OriginalRIP != guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_EIP] || Context->FaultToTopAndGeneratedException) { @@ -302,7 +296,7 @@ void SignalDelegator::RestoreRTFrame_ia32(FEXCore::Core::InternalThreadState* Th } // Extended XMM state - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -329,8 +323,6 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // 32-bit doesn't have a redzone NewGuestSP -= 128; - const bool IsAVXEnabled = Config.SupportsAVX; - // On 64-bit the kernel sets up the siginfo_t and ucontext_t regardless of SA_SIGINFO set. // This allows the application to /always/ get the siginfo and ucontext even if it didn't set this flag. // @@ -345,7 +337,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86_64::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86_64::xstate)); } else { @@ -378,7 +370,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // Pointer to where the fpreg memory is guest_uctx->uc_mcontext.fpregs = reinterpret_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_RIP] = ContextBackup->OriginalRIP; guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_EFL] = eflags; @@ -427,7 +419,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // Copy float registers memcpy(fpstate->_st, Frame->State.mm, sizeof(Frame->State.mm)); - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr); @@ -472,7 +464,6 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th FEXCore::Core::CpuStateFrame* Frame, int Signal, siginfo_t* HostSigInfo, void* ucontext, GuestSigAction* GuestAction, stack_t* GuestStack, uint64_t NewGuestSP, const uint32_t eflags) { - const bool IsAVXEnabled = Config.SupportsAVX; const uint64_t SignalReturn = reinterpret_cast(VDSOPointers.VDSO_kernel_sigreturn); NewGuestSP -= sizeof(uint64_t); @@ -480,7 +471,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -505,7 +496,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th // Pointer to where the fpreg memory is guest_uctx->sc.fpstate = static_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->sc.cs = Frame->State.cs_idx; guest_uctx->sc.ds = Frame->State.ds_idx; @@ -549,7 +540,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th // Extended XMM state fpstate->status = FEXCore::x86::fpstate_magic::MAGIC_XFPSTATE; - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr); @@ -601,7 +592,6 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* FEXCore::Core::CpuStateFrame* Frame, int Signal, siginfo_t* HostSigInfo, void* ucontext, GuestSigAction* GuestAction, stack_t* GuestStack, uint64_t NewGuestSP, const uint32_t eflags) { - const bool IsAVXEnabled = Config.SupportsAVX; const uint64_t SignalReturn = reinterpret_cast(VDSOPointers.VDSO_kernel_rt_sigreturn); NewGuestSP -= sizeof(uint64_t); @@ -609,7 +599,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -638,7 +628,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* // Pointer to where the fpreg memory is guest_uctx->uc.uc_mcontext.fpregs = static_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_CS] = Frame->State.cs_idx; guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_DS] = Frame->State.ds_idx; @@ -684,7 +674,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* // Extended XMM state fpstate->status = FEXCore::x86::fpstate_magic::MAGIC_XFPSTATE; - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr);