refactor (syscalls): improved syscall handling infrastructure

This commit is contained in:
antifallobst 2023-04-18 17:06:48 +02:00
parent d9c3b4060b
commit af95bd2ba1
2 changed files with 67 additions and 38 deletions

View File

@ -7,11 +7,11 @@
#include "utils/status.h" #include "utils/status.h"
typedef enum { typedef enum {
SYSCALLS_FILES = 0x00, SYSCALLS_FILES = 0x01,
SYSCALLS_MEMORY = 0x01, SYSCALLS_MEMORY = 0x02,
SYSCALLS_PROC = 0x02, SYSCALLS_PROC = 0x03,
SYSCALLS_RUNTIME_LINKER = 0x02, SYSCALLS_RUNTIME_LINKER = 0x04,
SYSCALLS_COMPATABILITY = 0x02, SYSCALLS_COMPATABILITY = 0x05,
SYSCALLS_KERNEL = 0xFF SYSCALLS_KERNEL = 0xFF
}syscall_group_E; }syscall_group_E;

View File

@ -6,55 +6,84 @@
#include "proc/scheduler.h" #include "proc/scheduler.h"
#include "drivers/fs/vfs.h" #include "drivers/fs/vfs.h"
void syscall_handle_nx_fopen(cpu_state_T* state) {
// read arguments
uint64_t arg1 = state->rdi;
vfs_node_T *node = vfs_resolve_path(&g_root_fs, (string_t) arg1);
if (node == NULL) {
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
return;
}
log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node);
}
cpu_state_T* syscall_handle(cpu_state_T* state) { cpu_state_T* syscall_handle(cpu_state_T* state) {
cpu_state_T* return_state = state; cpu_state_T* return_state = state;
syscall_group_E group_id = (state->rax & 0xFF00) >> 8; syscall_group_E group_id = (state->rax & 0xFF00) >> 8;
if (group_id == SYSCALLS_KERNEL &&
scheduler_is_initialized() &&
scheduler_get_current_process()->id != PROCESS_KERNEL)
{
log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread());
return return_state;
}
// read arguments // read arguments
uint64_t arg1 = state->rdi; uint64_t arg1 = state->rdi;
uint64_t arg2 = state->rsi;
uint64_t arg3 = state->rdx; switch (group_id) {
uint64_t arg4 = state->rcx; case SYSCALLS_FILES: {
uint64_t ret = STATUS_SUCCESS;
switch (state->rax) { switch (state->rax) {
case SYSCALL_FILES_OPEN: { case SYSCALL_FILES_OPEN: {
vfs_node_T* node = vfs_resolve_path(&g_root_fs, (string_t)arg1); syscall_handle_nx_fopen(state);
if (node == NULL) { break;
ret = STATUS_RESOURCE_NOT_AVAILABLE; }
}
break; break;
} }
log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node); case SYSCALLS_MEMORY: {
break; break;
} }
case SYSCALLS_PROC: {
break;
}
case SYSCALLS_RUNTIME_LINKER: {
break;
}
case SYSCALLS_COMPATABILITY: {
break;
}
case SYSCALLS_KERNEL: {
// check if the current Process is permitted to perform a kernel syscall
if (scheduler_is_initialized() &&
scheduler_get_current_process()->id != PROCESS_KERNEL)
{
log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread());
state->rax = STATUS_PERMISSION_DENIED;
return return_state;
}
switch (state->rax) {
case SYSCALL_KERNEL_SCHEDULER_START: { case SYSCALL_KERNEL_SCHEDULER_START: {
return_state = scheduler_start(state); return_state = scheduler_start(state);
break; break;
} }
case SYSCALL_KERNEL_PANIC: { case SYSCALL_KERNEL_PANIC: {
panic(state, (string_t)arg1); panic(state, (string_t)arg1);
break; break;
} }
}
}
default: { default: {
log(LOG_WARNING, "unhandled syscall: 0x%xw", state->rax); log(LOG_WARNING, "unknown syscall group: 0x%xb", group_id);
break; break;
} }
} }
// apply return value
state->rax = ret;
return return_state; return return_state;
} }