From c6c92ac39f4f37f4b56e9bd9522031d5d28c808a Mon Sep 17 00:00:00 2001 From: fef Date: Mon, 22 Nov 2021 20:01:26 +0100 Subject: [PATCH] x86/trap: fix trap frame layout --- arch/x86/include/amd64/trap.h | 10 +++---- arch/x86/sys/amd64/systm.c | 20 ++++++------- arch/x86/sys/amd64/trap.S | 53 +++++++++++++++++------------------ arch/x86/sys/interrupt.c | 4 +++ cmake/config.cmake | 2 +- kernel/panic.c | 25 +++++++++++++++++ 6 files changed, 70 insertions(+), 44 deletions(-) diff --git a/arch/x86/include/amd64/trap.h b/arch/x86/include/amd64/trap.h index 9fe3eda..40563d4 100644 --- a/arch/x86/include/amd64/trap.h +++ b/arch/x86/include/amd64/trap.h @@ -10,11 +10,6 @@ * @brief Complete context save on the amd64. */ struct amd64_trap_frame { - /* this doesn't need to be a pointer because unlike on - * i386, the hardware frame always has the same size */ - struct amd64_hw_frame hw_frame; - u64 rsi; - u64 rdi; u64 rax; u64 rbx; u64 rcx; @@ -28,5 +23,10 @@ struct amd64_trap_frame { u64 r13; u64 r14; u64 r15; + u64 rdi; + u64 rsi; + /* this doesn't need to be a pointer because unlike on + * i386, the hardware frame always has the same size */ + struct amd64_hw_frame hw_frame; } __packed; typedef struct amd64_trap_frame trap_frame_t; diff --git a/arch/x86/sys/amd64/systm.c b/arch/x86/sys/amd64/systm.c index 48993ef..448ba0f 100644 --- a/arch/x86/sys/amd64/systm.c +++ b/arch/x86/sys/amd64/systm.c @@ -7,14 +7,14 @@ void print_regs(const struct amd64_trap_frame *ctx) { - kprintf("RIP = %#x:%#016lx\n", ctx->hw_frame.cs, ctx->hw_frame.rip); - kprintf("RFLAGS = %#016lx\n", ctx->hw_frame.rflags); - kprintf("RAX = %#016lx RDI = %#016lx\n", ctx->rax, ctx->rdi); - kprintf("RBX = %#016lx RSI = %#016lx\n", ctx->rbx, ctx->rsi); - kprintf("RCX = %#016lx RSP = %#016lx\n", ctx->rcx, ctx->hw_frame.rsp); - kprintf("RDX = %#016lx RBP = %#016lx\n", ctx->rdx, ctx->rbp); - kprintf("R8 = %#016lx R12 = %#016lx\n", ctx->r8, ctx->r12); - kprintf("R9 = %#016lx R13 = %#016lx\n", ctx->r9, ctx->r13); - kprintf("R10 = %#016lx R14 = %#016lx\n", ctx->r10, ctx->r14); - kprintf("R11 = %#016lx R15 = %#016lx\n", ctx->r11, ctx->r15); + kprintf("RIP = %04hx:0x%016lx\n", ctx->hw_frame.cs, ctx->hw_frame.rip); + kprintf("RFLAGS = 0x%016lx\n", ctx->hw_frame.rflags); + kprintf("RAX = 0x%016lx RDI = 0x%016lx\n", ctx->rax, ctx->rdi); + kprintf("RBX = 0x%016lx RSI = 0x%016lx\n", ctx->rbx, ctx->rsi); + kprintf("RCX = 0x%016lx RSP = 0x%016lx\n", ctx->rcx, ctx->hw_frame.rsp); + kprintf("RDX = 0x%016lx RBP = 0x%016lx\n", ctx->rdx, ctx->rbp); + kprintf("R8 = 0x%016lx R12 = 0x%016lx\n", ctx->r8, ctx->r12); + kprintf("R9 = 0x%016lx R13 = 0x%016lx\n", ctx->r9, ctx->r13); + kprintf("R10 = 0x%016lx R14 = 0x%016lx\n", ctx->r10, ctx->r14); + kprintf("R11 = 0x%016lx R15 = 0x%016lx\n", ctx->r11, ctx->r15); } diff --git a/arch/x86/sys/amd64/trap.S b/arch/x86/sys/amd64/trap.S index e72d955..aae9886 100644 --- a/arch/x86/sys/amd64/trap.S +++ b/arch/x86/sys/amd64/trap.S @@ -15,39 +15,36 @@ */ .macro prepare_trap_entry pushq %rdi - movq %rsp, %rdi - /* 16 bytes for %rsi and %rdi, plus sizeof(struct amd64_hw_frame) */ - subq $56, %rdi - - pushq %rax - pushq %rbx - pushq %rcx - pushq %rdx - pushq %rbp - pushq %r8 - pushq %r9 - pushq %r10 - pushq %r11 - pushq %r12 - pushq %r13 - pushq %r14 pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rbp + pushq %rdx + pushq %rcx + pushq %rbx + pushq %rax + movq %rsp, %rdi .endm .macro prepare_trap_leave - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rbp - popq %rdx - popq %rcx - popq %rbx popq %rax + popq %rbx + popq %rcx + popq %rdx + popq %rbp + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 popq %rdi .endm diff --git a/arch/x86/sys/interrupt.c b/arch/x86/sys/interrupt.c index c2abec7..c896a8d 100644 --- a/arch/x86/sys/interrupt.c +++ b/arch/x86/sys/interrupt.c @@ -45,7 +45,11 @@ void x86_setup_interrupts(void) void x86_set_gate(u8 vector, void (*handler)(void), u8 flags) { struct x86_idt_entry *entry = &x86_idt[vector]; +#ifdef __x86_64__ + entry->selector = X86_64_KERN_CS; +#else entry->selector = X86_32_KERN_CS; +#endif entry->_rsvd0 = 0; entry->attr = flags; diff --git a/cmake/config.cmake b/cmake/config.cmake index 3aaf223..fda3d1a 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -12,7 +12,7 @@ set(CFG_KERN_ORIGIN "0x00400000" CACHE STRING "Physical address where the kernel option(CFG_POISON_PAGES "Poison pages after allocate and free" ON) -option(CFG_POISON_HEAP "Poison heap memory after kmalloc() and kfree()" ON) +option(CFG_POISON_SLABS "Poison slab allocations (kmalloc() and friends)" ON) set(CFG_PAGE_EMERG_DENOM "16" CACHE STRING "Denominator for the fraction of pages kept in emergency reserves") diff --git a/kernel/panic.c b/kernel/panic.c index 3ddc0a3..3fecfb8 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -23,6 +24,7 @@ void panic(const char *fmt, ...) else kvprintf(fmt, args); + kprintf("\n"); ktrace_print(); kprintf("\nKernel version: %s\nSystem halted", GAY_VERSION_STR); @@ -33,3 +35,26 @@ void panic(const char *fmt, ...) disable_intr(); } } + +__noreturn +void panic_notrace(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + disable_intr(); + + kprintf("Kernel panic: "); + if (fmt == nil) + kprintf("(nil)\n"); + else + kvprintf(fmt, args); + + kprintf("\nKernel version: %s\nSystem halted", GAY_VERSION_STR); + + /* no need for va_end() here i guess */ + while (1) { + halt(); + disable_intr(); + } +}