diff options
Diffstat (limited to 'src/core/arm/dynarmic')
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 49 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 20 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 5 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 5 |
4 files changed, 79 insertions, 0 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp new file mode 100644 index 000000000..e6e9fc45b --- /dev/null +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef __linux__ + +#include "common/signal_chain.h" + +#include "core/arm/dynarmic/arm_dynarmic.h" +#include "core/hle/kernel/k_process.h" +#include "core/memory.h" + +namespace Core { + +namespace { + +thread_local Core::Memory::Memory* g_current_memory{}; +std::once_flag g_registered{}; +struct sigaction g_old_segv {}; + +void HandleSigSegv(int sig, siginfo_t* info, void* ctx) { + if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) { + return; + } + + return g_old_segv.sa_sigaction(sig, info, ctx); +} + +} // namespace + +ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) { + g_current_memory = std::addressof(process->GetMemory()); +} + +ScopedJitExecution::~ScopedJitExecution() { + g_current_memory = nullptr; +} + +void ScopedJitExecution::RegisterHandler() { + std::call_once(g_registered, [] { + struct sigaction sa {}; + sa.sa_sigaction = &HandleSigSegv; + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv)); + }); +} + +} // namespace Core + +#endif diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index eef7c3116..53dd18815 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -26,4 +26,24 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) { return static_cast<HaltReason>(hr); } +#ifdef __linux__ + +class ScopedJitExecution { +public: + explicit ScopedJitExecution(Kernel::KProcess* process); + ~ScopedJitExecution(); + static void RegisterHandler(); +}; + +#else + +class ScopedJitExecution { +public: + explicit ScopedJitExecution(Kernel::KProcess* process) {} + ~ScopedJitExecution() {} + static void RegisterHandler() {} +}; + +#endif + } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index c78cfd528..36478f722 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -331,11 +331,15 @@ bool ArmDynarmic32::IsInThumbMode() const { } HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) { + ScopedJitExecution sj(thread->GetOwnerProcess()); + m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Run()); } HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) { + ScopedJitExecution sj(thread->GetOwnerProcess()); + m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Step()); } @@ -377,6 +381,7 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} { auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl(); m_jit = MakeJit(&page_table_impl); + ScopedJitExecution::RegisterHandler(); } ArmDynarmic32::~ArmDynarmic32() = default; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index f351b13d9..c811c8ad5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -362,11 +362,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa } HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) { + ScopedJitExecution sj(thread->GetOwnerProcess()); + m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Run()); } HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) { + ScopedJitExecution sj(thread->GetOwnerProcess()); + m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Step()); } @@ -406,6 +410,7 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc auto& page_table = process->GetPageTable().GetBasePageTable(); auto& page_table_impl = page_table.GetImpl(); m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth()); + ScopedJitExecution::RegisterHandler(); } ArmDynarmic64::~ArmDynarmic64() = default; |