mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[panic] Have panics stop all cores
Kernel panics previously only stopped the calling core. This commit re-implements the panic system to allow us to stop all cores on a panic. Changes include: - panic now sends an NMI to all cores. This means we can't control the contents of their registers, so panic information has been moved to a global struct, and the panicking cpu sets the pointer to that data in its cpu_data. - the panic_handler is now set up with mutexes to print appropriately and only initialize objects once. - copying _current_gsbase into the panic handler, and #including the cpprt.cpp file (so that we can define NDEBUG and not have it try to link the assert code back in) - making the symbol data pointer in kargs an actual pointer again, not an address - and carrying that through to the panic handler - the number of cpus is now saved globally in the kernel as g_num_cpus
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
|
||||
namespace panic {
|
||||
|
||||
constexpr uint32_t send_nmi_command =
|
||||
(4 << 8) | // Delivery mode NMI
|
||||
(1 << 14) | // assert level high
|
||||
(1 << 18); // destination self
|
||||
(2 << 18); // destination all
|
||||
|
||||
extern uint32_t *apic_icr;
|
||||
extern uintptr_t symbol_table;
|
||||
extern void const *symbol_table;
|
||||
|
||||
__attribute__ ((always_inline))
|
||||
inline void panic(
|
||||
@@ -19,19 +20,23 @@ inline void panic(
|
||||
const char *file = __builtin_FILE(),
|
||||
uint64_t line = __builtin_LINE())
|
||||
{
|
||||
register uintptr_t syms asm("rdi");
|
||||
register const char *m asm("rsi");
|
||||
register const char *fn asm("rdx");
|
||||
register const char *fi asm("rcx");
|
||||
register uint64_t l asm("r8");
|
||||
cpu_data &cpu = current_cpu();
|
||||
|
||||
asm volatile ("mov %1, %0" : "=r"(syms) : "r"(symbol_table));
|
||||
asm volatile ("mov %1, %0" : "=r"(m) : "r"(message));
|
||||
asm volatile ("mov %1, %0" : "=r"(fn) : "r"(function));
|
||||
asm volatile ("mov %1, %0" : "=r"(fi) : "r"(file));
|
||||
asm volatile ("mov %1, %0" : "=r"(l) : "r"(line));
|
||||
// Grab the global panic block for ourselves
|
||||
cpu.panic = __atomic_exchange_n(&g_panic_data_p, nullptr, __ATOMIC_ACQ_REL);
|
||||
|
||||
// If we aren't the first CPU to panic, cpu.panic will be null
|
||||
if (cpu.panic) {
|
||||
cpu.panic->symbol_data = symbol_table;
|
||||
cpu.panic->message = message;
|
||||
cpu.panic->function = function;
|
||||
cpu.panic->file = file;
|
||||
cpu.panic->line = line;
|
||||
cpu.panic->cpus = g_num_cpus;
|
||||
|
||||
*apic_icr = send_nmi_command;
|
||||
}
|
||||
|
||||
*apic_icr = send_nmi_command;
|
||||
while (1) asm ("hlt");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user