summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init/syscall.s11
-rw-r--r--src/init/syscalls.c26
-rw-r--r--src/kernel/arch/generic.h2
-rw-r--r--src/kernel/arch/i386/sysenter.c2
-rw-r--r--src/kernel/syscalls.c2
5 files changed, 23 insertions, 20 deletions
diff --git a/src/init/syscall.s b/src/init/syscall.s
index 78ce817..bea1452 100644
--- a/src/init/syscall.s
+++ b/src/init/syscall.s
@@ -5,16 +5,19 @@ _syscall:
push %ebx // preserve registers
push %esi
push %edi
+ push %ebp
// note: i could squeeze out another parameter out of %ebp
- mov 16(%esp), %eax
- mov 20(%esp), %ebx
+ mov 20(%esp), %eax
+ mov 24(%esp), %ebx
mov %esp, %ecx
mov $_syscall_ret, %edx
- mov 24(%esp), %esi
- mov 28(%esp), %edi
+ mov 28(%esp), %esi
+ mov 32(%esp), %edi
+ mov 36(%esp), %ebp
sysenter
_syscall_ret:
+ pop %ebp
pop %edi
pop %esi
pop %ebx
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 1f80d29..a5d1024 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -2,53 +2,53 @@
#include <init/types.h>
#include <shared/syscalls.h>
-int _syscall(int, int, int, int);
+int _syscall(int, int, int, int, int);
_Noreturn void _syscall_exit(const char __user *msg, size_t len) {
- _syscall(_SYSCALL_EXIT, (int)msg, len, 0);
+ _syscall(_SYSCALL_EXIT, (int)msg, len, 0, 0);
__builtin_unreachable();
}
int _syscall_fork(void) {
- return _syscall(_SYSCALL_FORK, 0, 0, 0);
+ return _syscall(_SYSCALL_FORK, 0, 0, 0, 0);
}
int _syscall_await(char __user *buf, int len) {
- return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0);
+ return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0, 0);
}
handle_t _syscall_open(const char __user *path, int len) {
- return _syscall(_SYSCALL_OPEN, (int)path, len, 0);
+ return _syscall(_SYSCALL_OPEN, (int)path, len, 0, 0);
}
int _syscall_mount(handle_t handle, const char __user *path, int len) {
- return _syscall(_SYSCALL_MOUNT, handle, (int)path, len);
+ return _syscall(_SYSCALL_MOUNT, handle, (int)path, len, 0);
}
int _syscall_read(handle_t handle, char __user *buf, int len) {
- return _syscall(_SYSCALL_READ, handle, (int)buf, len);
+ return _syscall(_SYSCALL_READ, handle, (int)buf, len, 0);
}
int _syscall_write(handle_t handle, const char __user *buf, int len) {
- return _syscall(_SYSCALL_WRITE, handle, (int)buf, len);
+ return _syscall(_SYSCALL_WRITE, handle, (int)buf, len, 0);
}
int _syscall_close(handle_t handle) {
- return _syscall(_SYSCALL_CLOSE, handle, 0, 0);
+ return _syscall(_SYSCALL_CLOSE, handle, 0, 0, 0);
}
handle_t _syscall_fs_create(handle_t __user *back) {
- return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0);
+ return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0, 0);
}
int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len) {
- return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len);
+ return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len, 0);
}
int _syscall_fs_respond(char __user *buf, int ret) {
- return _syscall(_SYSCALL_FS_RESPOND, (int)buf, ret, 0);
+ return _syscall(_SYSCALL_FS_RESPOND, (int)buf, ret, 0, 0);
}
int _syscall_memflag(void __user *addr, size_t len, int flags) {
- return _syscall(_SYSCALL_MEMFLAG, (int)addr, len, flags);
+ return _syscall(_SYSCALL_MEMFLAG, (int)addr, len, flags, 0);
}
diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h
index 547109f..dd145f7 100644
--- a/src/kernel/arch/generic.h
+++ b/src/kernel/arch/generic.h
@@ -18,7 +18,7 @@ void halt_cpu(void);
// src/arch/i386/sysenter.s
_Noreturn void sysexit(struct registers);
-int syscall_handler(int, int, int, int);
+int syscall_handler(int, int, int, int, int);
// all of those can allocate memory
struct pagedir *pagedir_new(void);
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c
index 231aba5..6419439 100644
--- a/src/kernel/arch/i386/sysenter.c
+++ b/src/kernel/arch/i386/sysenter.c
@@ -22,7 +22,7 @@ _Noreturn void sysenter_stage2(void) {
regs->eip = (userptr_t) regs->edx;
val = syscall_handler(regs->eax, regs->ebx,
- regs->esi, regs->edi);
+ regs->esi, regs->edi, (uintptr_t)regs->ebp);
regs_savereturn(&process_current->regs, val);
process_switch(process_current); // TODO process_resume
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 6821871..9002628 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -250,7 +250,7 @@ int _syscall_memflag(void __user *addr, size_t len, int flags) {
return -1;
}
-int syscall_handler(int num, int a, int b, int c) {
+int syscall_handler(int num, int a, int b, int c, int d) {
switch (num) {
case _SYSCALL_EXIT:
_syscall_exit((userptr_t)a, b);