refactor (syscalls): improved syscall handling infrastructure
This commit is contained in:
parent
d9c3b4060b
commit
af95bd2ba1
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
||||||
uint64_t arg4 = state->rcx;
|
|
||||||
uint64_t ret = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
switch (state->rax) {
|
switch (group_id) {
|
||||||
case SYSCALL_FILES_OPEN: {
|
case SYSCALLS_FILES: {
|
||||||
vfs_node_T* node = vfs_resolve_path(&g_root_fs, (string_t)arg1);
|
|
||||||
if (node == NULL) {
|
switch (state->rax) {
|
||||||
ret = STATUS_RESOURCE_NOT_AVAILABLE;
|
case SYSCALL_FILES_OPEN: {
|
||||||
break;
|
syscall_handle_nx_fopen(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SYSCALLS_MEMORY: {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node);
|
switch (state->rax) {
|
||||||
|
case SYSCALL_KERNEL_SCHEDULER_START: {
|
||||||
|
return_state = scheduler_start(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
case SYSCALL_KERNEL_PANIC: {
|
||||||
}
|
panic(state, (string_t)arg1);
|
||||||
|
break;
|
||||||
case SYSCALL_KERNEL_SCHEDULER_START: {
|
}
|
||||||
return_state = scheduler_start(state);
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SYSCALL_KERNEL_PANIC: {
|
|
||||||
panic(state, (string_t)arg1);
|
|
||||||
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;
|
||||||
}
|
}
|
Loading…
Reference in New Issue