Add a way to handle illegal system call and segmentation faults in

signal handlers
This commit is contained in:
Mark
2020-01-16 14:04:14 +02:00
parent 1e597e0ac4
commit 97db4331b4
9 changed files with 59 additions and 25 deletions
+1 -1
View File
@@ -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);
+1 -3
View File
@@ -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
+8
View File
@@ -1,5 +1,13 @@
#pragma once
#if defined(__KERNEL__)
#include <stdint.h>
#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)
+22 -3
View File
@@ -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) {
+5 -11
View File
@@ -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
+17
View File
@@ -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;
}
-1
View File
@@ -53,6 +53,5 @@ const void *amd64_syscall_jmp_table[256] = {
// Memory
[SYSCALL_NR_BRK] = sys_brk,
NULL
};
+5 -5
View File
@@ -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
-1
View File
@@ -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;