From 9108299c31947d59a9cab7a3923ca7e50253b9a4 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 14 Oct 2025 08:12:04 +0200 Subject: [PATCH] Migrate off the big ipcpipe() syscall --- kernel/syscall/ipcpipe.c | 321 +++++++++++++++++++++++---------------- kernel/syscall/ipcpipe.h | 6 +- kernel/syscall/syscall.c | 6 +- share/sysdefs/syscall.h | 7 +- 4 files changed, 203 insertions(+), 137 deletions(-) diff --git a/kernel/syscall/ipcpipe.c b/kernel/syscall/ipcpipe.c index 27649ca..9756a75 100644 --- a/kernel/syscall/ipcpipe.c +++ b/kernel/syscall/ipcpipe.c @@ -10,13 +10,167 @@ #include "util/util.h" #include "kprintf.h" -int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) { +int32_t SYSCALL4(sys_ipc_piperead, pid1, pipenum1, buffer1, len1) { uint64_t pid = pid1; uint64_t pipenum = pipenum1; - uint64_t cmd = cmd1; int32_t ret = E_OK; - if (pid == -1) { + if (pid == (uint64_t)-1) { + pid = PROCS.current->pid; + } + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = NULL; + LL_FINDPROP(PROCS.procs, proc, pid, pid); + spinlock_release(&PROCS.spinlock); + + if (proc == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_INVALIDARGUMENT; + goto done; + } + + uint8_t *const buffer = (uint8_t *const)buffer1; + if (buffer == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + spinlock_acquire(&proc->pipes_spinlock); + IpcPipe *pipe = proc->pipes[pipenum]; + spinlock_release(&proc->pipes_spinlock); + + if (pipe == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + ret = ipc_piperead(pipe, buffer, len1); +done: + return ret; +} + +int32_t SYSCALL4(sys_ipc_pipewrite, pid1, pipenum1, buffer1, len1) { + uint64_t pid = pid1; + uint64_t pipenum = pipenum1; + int32_t ret = E_OK; + + if (pid == (uint64_t)-1) { + pid = PROCS.current->pid; + } + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = NULL; + LL_FINDPROP(PROCS.procs, proc, pid, pid); + spinlock_release(&PROCS.spinlock); + + if (proc == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_INVALIDARGUMENT; + goto done; + } + + const uint8_t *const buffer = (const uint8_t *const)buffer1; + if (buffer == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + spinlock_acquire(&proc->pipes_spinlock); + IpcPipe *pipe = proc->pipes[pipenum]; + spinlock_release(&proc->pipes_spinlock); + + if (pipe == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + ret = ipc_pipewrite(pipe, buffer, len1); +done: + return ret; +} + +int32_t SYSCALL1(sys_ipc_pipemake, pipenum1) { + uint64_t pipenum = pipenum1; + int32_t ret = E_OK; + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_NOMEMORY; + goto done; + } + + IpcPipe *pipe = dlmalloc(sizeof(*pipe)); + if (pipe == NULL) { + ret = E_NOMEMORY; + goto done; + } + + if ((ret = ipc_pipeinit(pipe, proc->pid)) < 0) { + ret = E_NOMEMORY; + goto done; + } + + spinlock_acquire(&proc->pipes_spinlock); + if (proc->pipes[pipenum] != NULL) { + spinlock_release(&proc->pipes_spinlock); + ipc_pipefree(pipe); + dlfree(pipe); + ret = E_RESOURCEAVAIL; + goto done; + } + proc->pipes[pipenum] = pipe; + spinlock_release(&proc->pipes_spinlock); + + ret = E_OK; + +done: + return ret; +} + +int32_t SYSCALL1(sys_ipc_pipedelete, pipenum1) { + uint64_t pipenum = pipenum1; + int32_t ret = E_OK; + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_NOMEMORY; + goto done; + } + + spinlock_acquire(&proc->pipes_spinlock); + if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) { + ipc_pipefree(proc->pipes[pipenum]); + dlfree(proc->pipes[pipenum]); + } + proc->pipes[pipenum] = NULL; + spinlock_release(&proc->pipes_spinlock); + ret = E_OK; + +done: + return ret; +} + +int32_t SYSCALL4(sys_ipc_pipeconnect, pid1, pipenum1, pid2, pipenum2) { + uint64_t pid = pid1; + uint64_t pipenum = pipenum1; + int32_t ret = E_OK; + + if (pid == (uint64_t)-1) { pid = PROCS.current->pid; } @@ -30,139 +184,38 @@ int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) { goto done; } - switch (cmd) { - case IPCPIPE_MAKE: { - if (pipenum >= PROC_PIPEHANDLES_MAX) { - ret = E_NOMEMORY; - goto done; - } - - IpcPipe *pipe = dlmalloc(sizeof(*pipe)); - if (pipe == NULL) { - ret = E_NOMEMORY; - goto done; - } - - if ((ret = ipc_pipeinit(pipe, proc->pid)) < 0) { - ret = E_NOMEMORY; - goto done; - } - - spinlock_acquire(&proc->pipes_spinlock); - if (proc->pipes[pipenum] != NULL) { - spinlock_release(&proc->pipes_spinlock); - ipc_pipefree(pipe); - dlfree(pipe); - ret = E_RESOURCEAVAIL; - goto done; - } - proc->pipes[pipenum] = pipe; - spinlock_release(&proc->pipes_spinlock); - - ret = E_OK; - } break; - case IPCPIPE_DELETE: { - if (pipenum >= PROC_PIPEHANDLES_MAX) { - ret = E_NOMEMORY; - goto done; - } - - spinlock_acquire(&proc->pipes_spinlock); - if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) { - ipc_pipefree(proc->pipes[pipenum]); - dlfree(proc->pipes[pipenum]); - } - proc->pipes[pipenum] = NULL; - spinlock_release(&proc->pipes_spinlock); - ret = E_OK; - } break; - case IPCPIPE_WRITE: { - if (pipenum >= PROC_PIPEHANDLES_MAX) { - ret = E_INVALIDARGUMENT; - goto done; - } - - const uint8_t *const buffer = (const uint8_t *const)buffer1; - if (buffer == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - spinlock_acquire(&proc->pipes_spinlock); - IpcPipe *pipe = proc->pipes[pipenum]; - spinlock_release(&proc->pipes_spinlock); - - if (pipe == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - ret = ipc_pipewrite(pipe, buffer, len1); - } break; - case IPCPIPE_READ: { - if (pipenum >= PROC_PIPEHANDLES_MAX) { - ret = E_INVALIDARGUMENT; - goto done; - } - - uint8_t *const buffer = (uint8_t *const)buffer1; - if (buffer == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - spinlock_acquire(&proc->pipes_spinlock); - IpcPipe *pipe = proc->pipes[pipenum]; - spinlock_release(&proc->pipes_spinlock); - - if (pipe == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - ret = ipc_piperead(pipe, buffer, len1); - } break; - case IPCPIPE_REPLACE: { - if (pipenum >= PROC_PIPEHANDLES_MAX) { - ret = E_NOMEMORY; - goto done; - } - - uint64_t pid2 = buffer1; - uint64_t pipenum2 = len1; - - spinlock_acquire(&PROCS.spinlock); - Proc *proc2 = NULL; - LL_FINDPROP(PROCS.procs, proc2, pid, pid2); - spinlock_release(&PROCS.spinlock); - - if (proc2 == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - if (pipenum2 >= PROC_PIPEHANDLES_MAX) { - ret = E_NOMEMORY; - goto done; - } - - spinlock_acquire(&proc2->pipes_spinlock); - spinlock_acquire(&proc->pipes_spinlock); - - if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) { - ipc_pipefree(proc->pipes[pipenum]); - dlfree(proc->pipes[pipenum]); - } - proc->pipes[pipenum] = proc2->pipes[pipenum2]; - - spinlock_release(&proc->pipes_spinlock); - spinlock_release(&proc2->pipes_spinlock); - } break; - default: { - ret = E_INVALIDARGUMENT; - } break; + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_NOMEMORY; + goto done; } + spinlock_acquire(&PROCS.spinlock); + Proc *proc2 = NULL; + LL_FINDPROP(PROCS.procs, proc2, pid, pid2); + spinlock_release(&PROCS.spinlock); + + if (proc2 == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + if (pipenum2 >= PROC_PIPEHANDLES_MAX) { + ret = E_NOMEMORY; + goto done; + } + + spinlock_acquire(&proc2->pipes_spinlock); + spinlock_acquire(&proc->pipes_spinlock); + + if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) { + ipc_pipefree(proc->pipes[pipenum]); + dlfree(proc->pipes[pipenum]); + } + proc->pipes[pipenum] = proc2->pipes[pipenum2]; + + spinlock_release(&proc->pipes_spinlock); + spinlock_release(&proc2->pipes_spinlock); + done: return ret; } diff --git a/kernel/syscall/ipcpipe.h b/kernel/syscall/ipcpipe.h index a757bf3..37d9f62 100644 --- a/kernel/syscall/ipcpipe.h +++ b/kernel/syscall/ipcpipe.h @@ -3,6 +3,10 @@ #include "syscall.h" -int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1); +int32_t SYSCALL4(sys_ipc_piperead, pid1, pipenum1, buffer1, len1); +int32_t SYSCALL4(sys_ipc_pipewrite, pid1, pipenum1, buffer1, len1); +int32_t SYSCALL1(sys_ipc_pipemake, pipenum1); +int32_t SYSCALL1(sys_ipc_pipedelete, pipenum1); +int32_t SYSCALL4(sys_ipc_pipeconnect, pid1, pipenum1, pid2, pipenum2); #endif // SYSCALL_IPCPIPE_H_ diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 7c1bbdb..8494092 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -22,7 +22,6 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { [SYS_DEBUGPRINT] = &sys_debugprint, [SYS_PROCESSCTL] = &sys_processctl, [SYS_IOCTL] = &sys_ioctl, - [SYS_IPCPIPE] = &sys_ipcpipe, [SYS_MMAN_MAP] = &sys_mman_map, [SYS_MMAN_UNMAP] = &sys_mman_unmap, [SYS_SCHEDRELEASE] = &sys_schedrelease, @@ -30,4 +29,9 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { [SYS_RAND] = &sys_rand, [SYS_VFSMOUNT] = &sys_vfsmount, [SYS_VFSUNMOUNT] = &sys_vfsunmount, + [SYS_IPC_PIPEREAD] = &sys_ipc_piperead, + [SYS_IPC_PIPEWRITE] = &sys_ipc_pipewrite, + [SYS_IPC_PIPEMAKE] = &sys_ipc_pipemake, + [SYS_IPC_PIPEDELETE] = &sys_ipc_pipedelete, + [SYS_IPC_PIPECONNECT] = &sys_ipc_pipeconnect, }; diff --git a/share/sysdefs/syscall.h b/share/sysdefs/syscall.h index 157f3a2..08d23fe 100644 --- a/share/sysdefs/syscall.h +++ b/share/sysdefs/syscall.h @@ -4,7 +4,6 @@ #define SYS_DEBUGPRINT 1 #define SYS_PROCESSCTL 2 #define SYS_IOCTL 3 -#define SYS_IPCPIPE 4 #define SYS_MMAN_MAP 5 #define SYS_MMAN_UNMAP 6 #define SYS_SCHEDRELEASE 7 @@ -12,5 +11,11 @@ #define SYS_RAND 9 #define SYS_VFSMOUNT 10 #define SYS_VFSUNMOUNT 11 +#define SYS_IPC_PIPEREAD 12 +#define SYS_IPC_PIPEWRITE 13 +#define SYS_IPC_PIPEMAKE 14 +#define SYS_IPC_PIPEDELETE 15 +#define SYS_IPC_PIPECONNECT 16 + #endif // SHARE_HDRS_SYSCALL_H_