diff --git a/include/sys/amd64/syscall.h b/include/sys/amd64/syscall.h index 805b90f..580968f 100644 --- a/include/sys/amd64/syscall.h +++ b/include/sys/amd64/syscall.h @@ -7,5 +7,5 @@ struct cpu_context; extern uint64_t syscall_count; void amd64_syscall_init(void); -extern void amd64_syscall_iretq(struct cpu_context *ctx); +__attribute__((noreturn)) void amd64_syscall_iretq(struct cpu_context *ctx); __attribute__((noreturn)) void amd64_syscall_yield_stopped(void); diff --git a/include/sys/signum.h b/include/sys/signum.h index 9d9305e..17bd15a 100644 --- a/include/sys/signum.h +++ b/include/sys/signum.h @@ -1,12 +1,10 @@ #pragma once #define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 #define SIGABRT 6 -#define SIGFPE 8 #define SIGKILL 9 #define SIGSEGV 11 +#define SIGSYS 12 #define SIGTERM 15 #define SIGUSR1 16 diff --git a/include/sys/types.h b/include/sys/types.h index c06286c..5ebb87b 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -1,5 +1,13 @@ #pragma once +#if defined(__KERNEL__) #include +#else +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned long uint64_t; +typedef long int64_t; +typedef int sig_atomic_t; +#endif #ifndef NULL #define NULL ((void *) 0) diff --git a/sys/amd64/hw/pfault.c b/sys/amd64/hw/pfault.c index 962c53a..beb25de 100644 --- a/sys/amd64/hw/pfault.c +++ b/sys/amd64/hw/pfault.c @@ -1,7 +1,9 @@ #include "sys/amd64/mm/map.h" +#include "sys/amd64/syscall.h" #include "sys/amd64/cpu.h" #include "sys/assert.h" #include "sys/thread.h" +#include "sys/signum.h" #include "sys/debug.h" extern void amd64_syscall_yield_stopped(); @@ -23,6 +25,7 @@ int amd64_pfault(uintptr_t cr2) { thr->pid); kerror("CR2 = %p\n", cr2); + kerror("RIP = %p\n", ctx->rip); // Dump registers cpu_print_context(DEBUG_ERROR, ctx); @@ -35,9 +38,25 @@ int amd64_pfault(uintptr_t cr2) { // because they're presumably fucked up by error code // push - thr->flags |= THREAD_STOPPED; - amd64_syscall_yield_stopped(); - return -1; + // The whole thread context is on the stack + + if (thr->pid > 0) { + thread_signal(thr, SIGSEGV); + + // Suicide signal, just hang on and wait + // until scheduler decides it's our time + while (thr->sigq) { + asm volatile ("sti; hlt; cli"); + } + + amd64_syscall_iretq(ctx); + } else { + panic("Segmentation fault happened in kernel thread\n"); + } + + //thr->flags |= THREAD_STOPPED; + //amd64_syscall_yield_stopped(); + //return -1; } void amd64_pfault_kernel(uintptr_t rip, uintptr_t cr2) { diff --git a/sys/amd64/hw/pfault_s.S b/sys/amd64/hw/pfault_s.S index 0242149..5177c59 100644 --- a/sys/amd64/hw/pfault_s.S +++ b/sys/amd64/hw/pfault_s.S @@ -14,9 +14,12 @@ amd64_exc_isr_14: // rip swapgs_if_needed + // Fuck error code + addq $8, %rsp + pushq %rax movq $(1 << 63), %rax - testq %rax, 16(%rsp) + testq %rax, 8(%rsp) jnz _pfault_kernel popq %rax @@ -38,16 +41,7 @@ amd64_exc_isr_14: movq %cr2, %rdi call amd64_pfault - - // If fault handler returned zero, it means next task is selected - // and should be run - test %rax, %rax - jnz 1f - - // Ok, continue - - - // Fail + // Failed to handle the fault 1: cli hlt diff --git a/sys/amd64/sys_proc.c b/sys/amd64/sys_proc.c index e3dbc35..9daab3f 100644 --- a/sys/amd64/sys_proc.c +++ b/sys/amd64/sys_proc.c @@ -2,6 +2,7 @@ #include "sys/amd64/syscall.h" #include "sys/amd64/cpu.h" #include "sys/assert.h" +#include "sys/signum.h" #include "sys/sched.h" #include "sys/thread.h" #include "sys/debug.h" @@ -138,3 +139,19 @@ gid_t sys_getgid(void) { _assert(thr); return thr->ioctx.gid; } + +int sys_unknown(int no) { + asm volatile ("cli"); + struct thread *thr = get_cpu()->thread; + _assert(thr); + + thread_signal(thr, SIGSYS); + + // Suicide signal, just hang on and wait + // until scheduler decides it's our time + while (thr->sigq) { + asm volatile ("sti; hlt; cli"); + } + + return -EINVAL; +} diff --git a/sys/amd64/syscall.c b/sys/amd64/syscall.c index b7045f8..0503314 100644 --- a/sys/amd64/syscall.c +++ b/sys/amd64/syscall.c @@ -53,6 +53,5 @@ const void *amd64_syscall_jmp_table[256] = { // Memory [SYSCALL_NR_BRK] = sys_brk, - NULL }; diff --git a/sys/amd64/syscall_s.S b/sys/amd64/syscall_s.S index 1a05509..ecefd5d 100644 --- a/sys/amd64/syscall_s.S +++ b/sys/amd64/syscall_s.S @@ -76,15 +76,15 @@ amd64_syscall_entry: movq %r10, %rcx incq syscall_count(%rip) leaq amd64_syscall_jmp_table(%rip), %r10 - movq (%r10, %rax, 8), %rax - test %rax, %rax + movq (%r10, %rax, 8), %r10 + test %r10, %r10 jz 1f sti - call *%rax + call *%r10 jmp 2f 1: - // -EINVAL - mov $-22, %rax + movq %rax, %rdi + call sys_unknown 2: //movq %rax, %r9 //call amd64_syscall diff --git a/sys/vfs/vfs.c b/sys/vfs/vfs.c index 918abda..bd4ee23 100644 --- a/sys/vfs/vfs.c +++ b/sys/vfs/vfs.c @@ -307,7 +307,6 @@ static int vfs_find_internal(struct vfs_ioctx *ctx, struct vnode *at, const char break; } - // TODO: lookup_or_load if ((err = vfs_lookup_or_load(at, name, &node)) != 0) { kdebug("miss %s in %s\n", name, at->name); return err;