diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 953d964399..f2ecd9b3e2 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -134,6 +134,13 @@ void ARM_Interface::Run() { } system.ExitDynarmicProfile(); + // Exception occurred, pass on to kernel to handle it. + if (exception_context != std::nullopt) { + const auto exception_context_ = *exception_context; + exception_context.reset(); + Kernel::Arch::Arm64::HandleException(system.Kernel(), exception_context_); + } + // Notify the debugger and go to sleep if a breakpoint was hit, // or if the thread is unable to continue for any reason. if (Has(hr, breakpoint) || Has(hr, no_execute)) { diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 7d62d030ee..c455e7208b 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -6,12 +6,14 @@ #include #include #include +#include #include #include "common/common_funcs.h" #include "common/common_types.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/arch/arm64/exception_handlers.h" namespace Common { struct PageTable; @@ -210,6 +212,7 @@ protected: System& system; const WatchpointArray* watchpoints; bool uses_wall_clock; + std::optional exception_context; static void SymbolicateBacktrace(Core::System& system, std::vector& out); const Kernel::DebugWatchpoint* MatchingWatchpoint( diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 4f5f8304c4..c7c14f5aaa 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -17,7 +17,6 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/debugger/debugger.h" -#include "core/hle/kernel/arch/arm64/exception_handlers.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" @@ -130,8 +129,8 @@ public: exception_context.psr = thread_context.cpsr; exception_context.tpidr = thread_context.tpidr; - // Kernel to handle exception - Kernel::Arch::Arm64::HandleException(parent.system.Kernel(), exception_context); + // Kernel to handle exception on exit + parent.exception_context = exception_context; } void CallSVC(u32 swi) override { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index b190c529c0..3cf180dddc 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -16,7 +16,6 @@ #include "core/core_timing.h" #include "core/debugger/debugger.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/arch/arm64/exception_handlers.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" @@ -171,8 +170,8 @@ public: exception_context.psr = thread_context.pstate; exception_context.tpidr = thread_context.tpidr; - // Kernel to handle exception - Kernel::Arch::Arm64::HandleException(parent.system.Kernel(), exception_context); + // Kernel to handle exception on exit + parent.exception_context = exception_context; } void CallSVC(u32 swi) override {