[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:
Justin C. Miller
2022-01-08 01:00:43 -08:00
parent a3fff889d1
commit eeef23c2b7
12 changed files with 134 additions and 30 deletions

View File

@@ -7,6 +7,8 @@
namespace panicking {
const char *clear = "\e[0m\n";
void
print_header(
serial_port &out,
@@ -15,7 +17,8 @@ print_header(
const char *file,
uint64_t line)
{
out.write("\n\n\e[5;31m PANIC:\e[0;1;31m ");
out.write(clear);
out.write("\n\e[5;31m PANIC:\e[0;1;31m ");
if (message) {
out.write(message);
out.write("\n ");
@@ -28,8 +31,16 @@ print_header(
char linestr[6];
snprintf(linestr, sizeof(linestr), "%ld", line);
out.write(linestr);
}
out.write("\n \e[0;31m===================================================================================\n");
void
print_cpu(serial_port &out, cpu_data &cpu)
{
out.write("\n \e[0;31m==[ CPU: ");
char cpuid[7];
snprintf(cpuid, sizeof(cpuid), "%4x", cpu.id);
out.write(cpuid);
out.write(" ]====================================================================\n");
}
void
@@ -64,7 +75,7 @@ print_reg(serial_port &out, const char *name, uint64_t val, const char *color)
void
print_cpu_state(serial_port &out, const cpu_state &regs)
{
out.write("\e[0m\n");
out.write(clear);
// Row 1
print_reg(out, "rsp", regs.rsp, "1;34");
@@ -99,7 +110,7 @@ print_cpu_state(serial_port &out, const cpu_state &regs)
print_reg(out, "ss", regs.ss, "1;33");
print_reg(out, "cs", regs.cs, "1;33");
print_reg(out, "flg", regs.rflags, "0;37");
out.write("\e[0m\n");
out.write(clear);
}
} // namespace panicking