From 73e5f13d35f19ab46afed45e6274fa95222732bc Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 19 Feb 2023 00:51:44 +0200 Subject: [PATCH] Signal all cores to stop on exception --- .../amd64/cpu/InterruptDescriptorTable.cpp | 2 +- Core/Crash/CrashHandler.cpp | 38 +++++++++++++++++-- include/cpu.hpp | 2 +- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp index e14f2ab..737d261 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp @@ -284,7 +284,7 @@ namespace InterruptDescriptorTable INTERRUPT_HANDLER(0x3a) INTERRUPT_HANDLER(0x3b) INTERRUPT_HANDLER(0x3c) - INTERRUPT_HANDLER(0x3d) + EXCEPTION_HANDLER(0x3d) /* Free */ diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index d07c247..20298df 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -15,8 +15,10 @@ #if defined(__amd64__) #include "../../Architecture/amd64/cpu/gdt.hpp" +#include "../Architecture/amd64/cpu/apic.hpp" #elif defined(__i386__) #include "../../Architecture/i686/cpu/gdt.hpp" +#include "../Architecture/i686/cpu/apic.hpp" #elif defined(__aarch64__) #endif @@ -719,18 +721,43 @@ namespace CrashHandler Display->SetBuffer(SBIdx); } + SafeFunction void StopAllCores() + { +#if defined(__amd64__) || defined(__i386__) + if (SMP::CPUCores > 1) + { + CPU::Interrupts(CPU::Enable); + for (int i = 1; i < SMP::CPUCores; i++) + { + locked_debug("Sending IPI to CPU %d", i); + APIC::InterruptCommandRegisterLow icr; + icr.Vector = CPU::x64::IRQ29; + icr.Level = APIC::APICLevel::Assert; + ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); + __sync; + } + CPU::Interrupts(CPU::Disable); + } +#elif defined(__aarch64__) +#endif + } + SafeFunction void Handle(void *Data) { // TODO: SUPPORT SMP CPU::Interrupts(CPU::Disable); - error("An exception occurred!"); - for (size_t i = 0; i < INT_FRAMES_MAX; i++) - EHIntFrames[i] = Interrupts::InterruptFrames[i]; - SBIdx = 255; CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data; #if defined(__amd64__) + if (Frame->InterruptNumber == CPU::x64::IRQ29) + { + locked_error("CPU %d halted.", GetCurrentCPU()->ID); + CPU::Stop(); + } + error("An exception occurred!"); error("Exception: %#llx", Frame->InterruptNumber); + for (size_t i = 0; i < INT_FRAMES_MAX; i++) + EHIntFrames[i] = Interrupts::InterruptFrames[i]; PageFaultAddress = CPU::x64::readcr2().PFLA; if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) @@ -740,6 +767,7 @@ namespace CrashHandler TaskManager->Panic(); ForceUnlock = true; Display->CreateBuffer(0, 0, SBIdx); + StopAllCores(); } else { @@ -749,6 +777,7 @@ namespace CrashHandler { ForceUnlock = true; Display->CreateBuffer(0, 0, SBIdx); + StopAllCores(); EHPrint("\eFF0000Cannot get CPU data! This results in a kernel crash!"); error("Cannot get CPU data! This results in a kernel crash!"); error("This should never happen!"); @@ -763,6 +792,7 @@ namespace CrashHandler TaskManager->Panic(); ForceUnlock = true; Display->CreateBuffer(0, 0, SBIdx); + StopAllCores(); } else { diff --git a/include/cpu.hpp b/include/cpu.hpp index 0d75723..5805121 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -2661,7 +2661,7 @@ namespace CPU IRQ26 = 0x3a, IRQ27 = 0x3b, IRQ28 = 0x3c, - IRQ29 = 0x3d, + IRQ29 = 0x3d, // Reserved for icr stop core /* Free */