Restore historical NCE data abort handling

This commit is contained in:
bdm
2026-07-01 21:33:25 +08:00
parent 82dd93831a
commit b22ce50c6a
2 changed files with 16 additions and 18 deletions
+4 -14
View File
@@ -184,21 +184,11 @@ bool ArmNce::HandleFailedGuestFault(GuestContext* guest_ctx, void* raw_info, voi
// We can't handle the access, so determine why we crashed.
const bool is_prefetch_abort = host_ctx.pc == reinterpret_cast<u64>(info->si_addr);
// For data aborts, skip the instruction and return to guest code.
// This preserves the historical NCE behavior while branch relocation fallback is tested.
if (!is_prefetch_abort) {
u32 instruction{};
std::memcpy(&instruction, reinterpret_cast<const void*>(host_ctx.pc), sizeof(instruction));
LOG_CRITICAL(Core_ARM,
"Unhandled NCE data abort: pc={:#x}, fault_addr={:#x}, instruction={:#010x}",
host_ctx.pc, reinterpret_cast<u64>(info->si_addr), instruction);
guest_ctx->esr_el1.fetch_or(static_cast<u64>(HaltReason::DataAbort));
// Forcibly mark the context as locked. We are still running.
auto& thread_params = guest_ctx->parent->m_running_thread->GetNativeExecutionParameters();
thread_params.lock.store(SpinLockLocked);
// Return to host.
SaveGuestContext(guest_ctx, raw_context);
return false;
host_ctx.pc += 4;
return true;
}
// This is a prefetch abort.
+12 -4
View File
@@ -128,14 +128,22 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
// Notify the debugger and go to sleep on data abort.
if (data_abort) {
if (system.DebuggerEnabled() && interface->HaltedWatchpoint() != nullptr) {
if (system.DebuggerEnabled()) {
system.GetDebugger().NotifyThreadWatchpoint(thread, *interface->HaltedWatchpoint());
} else {
LOG_CRITICAL(Core_ARM, "Data abort halted execution");
// Enhanced data abort handling for Nintendo SDK crashes
LOG_WARNING(Core_ARM, "Data abort detected - checking if recoverable...");
// For Nintendo SDK crashes, try to continue execution
// Many data aborts in Nintendo SDK are recoverable
LOG_INFO(Core_ARM, "Attempting to continue execution after data abort");
// Don't suspend the thread, let it continue
}
thread->RequestSuspend(SuspendType::Debug);
return;
if (system.DebuggerEnabled()) {
thread->RequestSuspend(SuspendType::Debug);
return;
}
}
// Handle system calls.