From da415c7f6d4ba3daa9243cb51fd99c30941640b9 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 9 Apr 2023 16:35:15 +0100 Subject: [PATCH] kernel: implement panic() --- arch/x86_64/include/socks/machine/panic.h | 9 ++ arch/x86_64/panic.c | 118 ++++++++++++++++++++++ include/socks/compiler.h | 11 +- include/socks/panic.h | 8 ++ kernel/panic.c | 42 ++++++++ 5 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 arch/x86_64/include/socks/machine/panic.h create mode 100644 arch/x86_64/panic.c create mode 100644 include/socks/panic.h create mode 100644 kernel/panic.c diff --git a/arch/x86_64/include/socks/machine/panic.h b/arch/x86_64/include/socks/machine/panic.h new file mode 100644 index 0000000..6441f3e --- /dev/null +++ b/arch/x86_64/include/socks/machine/panic.h @@ -0,0 +1,9 @@ +#ifndef SOCKS_X86_64_PANIC_H_ +#define SOCKS_X86_64_PANIC_H_ + +struct cpu_context; + +extern void ml_print_cpu_state(struct cpu_context *ctx); +extern void ml_print_stack_trace(struct cpu_context *ctx); + +#endif diff --git a/arch/x86_64/panic.c b/arch/x86_64/panic.c new file mode 100644 index 0000000..2b8086f --- /dev/null +++ b/arch/x86_64/panic.c @@ -0,0 +1,118 @@ +#include +#include +#include + +#define R_CF 0 +#define R_PF 2 +#define R_AF 4 +#define R_ZF 6 +#define R_SF 7 +#define R_TF 8 +#define R_IF 9 +#define R_DF 10 +#define R_OF 11 +#define R_NT 14 +#define R_VM 17 +#define R_AC 18 +#define R_VIF 19 +#define R_VIP 20 +#define R_ID 21 +#define R_MAX 21 + +const char *pf_rfl_name(int bit) +{ + switch (bit) { + case R_CF: + return "CF"; + case R_PF: + return "PF"; + case R_AF: + return "AF"; + case R_ZF: + return "ZF"; + case R_SF: + return "SF"; + case R_TF: + return "TF"; + case R_IF: + return "IF"; + case R_DF: + return "DF"; + case R_OF: + return "OF"; + case R_NT: + return "NT"; + case R_VM: + return "VM"; + case R_AC: + return "AC"; + case R_VIF: + return "VIF"; + case R_VIP: + return "VIP"; + case R_ID: + return "ID"; + default: + return NULL; + } +} + +int pf_rfl_iopl(uint64_t flags) +{ + int mask = 0x3000; + int val = flags & mask; + return val >> 12; +} + +static void print_rflags(uintptr_t rflags) +{ + char buf[128]; + size_t buf_i = 0; + + buf_i += snprintf(buf, sizeof(buf), " rfl %08lx [", rflags); + + for (int i = 0; i < R_MAX; i++) { + if (rflags & (1 << i)) { + const char *name = pf_rfl_name(i); + if (name) { + buf_i += snprintf(buf + buf_i, sizeof(buf) - buf_i, " %s", name); + } + } + } + + snprintf(buf + buf_i, sizeof(buf) - buf_i, " ]"); + printk(buf); +} + +void ml_print_cpu_state(struct cpu_context *ctx) +{ + printk("cpu state:"); + if (ctx) { + printk(" rax %016lx rbx %016lx rcx %016x", + ctx->rax, ctx->rbx, ctx->rcx); + printk(" rdx %016lx rsi %016lx rdi %016x", + ctx->rdx, ctx->rsi, ctx->rdi); + printk(" rsp %016lx rbp %016lx r8 %016x", + ctx->rsp, ctx->rbp, ctx->r8); + printk(" r9 %016lx r10 %016lx r11 %016x", + ctx->r9, ctx->r10, ctx->r11); + printk(" r12 %016lx r13 %016lx r14 %016x", + ctx->r12, ctx->r13, ctx->r14); + printk(" r15 %016lx rip %016lx cs %04x ss %04x", + ctx->r15, ctx->rip, ctx->cs, ctx->ss); + print_rflags(ctx->rflags); + } + + uintptr_t cr0 = 0, cr2 = 0, cr3 = 0, cr4 = 0; + asm volatile("mov %%cr0, %%rax" : "=a" (cr0)); + asm volatile("mov %%cr2, %%rax" : "=a" (cr2)); + asm volatile("mov %%cr3, %%rax" : "=a" (cr3)); + asm volatile("mov %%cr4, %%rax" : "=a" (cr4)); + printk(" cr0 %016x cr2 %016x", cr0, cr2); + printk(" cr3 %016x cr4 %016x", cr3, cr4); +} + +void ml_print_stack_trace(struct cpu_context *ctx) +{ + +} diff --git a/include/socks/compiler.h b/include/socks/compiler.h index 4145e8f..7a21e58 100644 --- a/include/socks/compiler.h +++ b/include/socks/compiler.h @@ -21,15 +21,18 @@ void write_once(volatile T *ptr, T value) #endif #undef __used -#define __used __attribute__((used)) +#define __used __attribute__((__used__)) + +#undef __noreturn +#define __noreturn __attribute__((__noreturn__)) #undef __packed -#define __packed __attribute__((packed)) +#define __packed __attribute__((__packed__)) #undef __section -#define __section(name) __attribute__((section(name))) +#define __section(name) __attribute__((__section__(name))) #undef __aligned -#define __aligned(x) __attribute__((aligned(x))) +#define __aligned(x) __attribute__((__aligned__(x))) #endif diff --git a/include/socks/panic.h b/include/socks/panic.h new file mode 100644 index 0000000..3ff7b0a --- /dev/null +++ b/include/socks/panic.h @@ -0,0 +1,8 @@ +#ifndef SOCKS_PANIC_H_ +#define SOCKS_PANIC_H_ + +#include + +extern void __noreturn panic(const char *fmt, ...); + +#endif diff --git a/kernel/panic.c b/kernel/panic.c new file mode 100644 index 0000000..36154db --- /dev/null +++ b/kernel/panic.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include + +static int has_panicked = 0; + +void panic(const char *fmt, ...) +{ + char buf[512]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + printk("---[ kernel panic: %s", buf); + printk("kernel: " BUILD_ID ", compiler version: " __VERSION__); + + task_t *task = current_task(); + thread_t *thr = current_thread(); + + if (task && thr) { + printk("task: %s (id: %d, thread: %d)", task->t_name, task->t_id, thr->tr_id); + } else { + printk("task: [bootstrap]"); + } + + printk("cpu: %u", this_cpu()); + + ml_print_cpu_state(NULL); + + if (READ_ONCE(has_panicked)) { + ml_halt_cpu(); + } + + WRITE_ONCE(has_panicked, 1); + + printk("---[ end kernel panic: %s", buf); + ml_halt_cpu(); +}