From 9a90662eaaa44ad8430ee4ceed5668395662e236 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 19 Feb 2026 19:22:06 +0000 Subject: [PATCH] libmango: add userspace syscall call-gates --- libmango/CMakeLists.txt | 13 ++++ libmango/arch/x86_64/syscall.S | 93 ++++++++++++++++++++++++++++ libmango/include-user/mango/config.h | 17 +++++ libmango/include-user/mango/handle.h | 9 +++ libmango/include-user/mango/log.h | 21 +++++++ libmango/include-user/mango/msg.h | 62 +++++++++++++++++++ libmango/include-user/mango/task.h | 25 ++++++++ libmango/include-user/mango/vm.h | 79 +++++++++++++++++++++++ libmango/msg.c | 0 9 files changed, 319 insertions(+) create mode 100644 libmango/CMakeLists.txt create mode 100644 libmango/arch/x86_64/syscall.S create mode 100644 libmango/include-user/mango/config.h create mode 100644 libmango/include-user/mango/handle.h create mode 100644 libmango/include-user/mango/log.h create mode 100644 libmango/include-user/mango/msg.h create mode 100644 libmango/include-user/mango/task.h create mode 100644 libmango/include-user/mango/vm.h create mode 100644 libmango/msg.c diff --git a/libmango/CMakeLists.txt b/libmango/CMakeLists.txt new file mode 100644 index 0000000..afff680 --- /dev/null +++ b/libmango/CMakeLists.txt @@ -0,0 +1,13 @@ +file(GLOB headers ${CMAKE_CURRENT_SOURCE_DIR}/include/mango/*.h) +file(GLOB asm_sources + ${CMAKE_CURRENT_SOURCE_DIR}/arch/${CMAKE_SYSTEM_PROCESSOR}/*.S) +set_property(SOURCE ${asm_sources} PROPERTY LANGUAGE C) + +set(public_include_dirs + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include-user) + +add_library(libmango STATIC ${asm_sources}) +target_include_directories(libmango PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include-user) diff --git a/libmango/arch/x86_64/syscall.S b/libmango/arch/x86_64/syscall.S new file mode 100644 index 0000000..ea4b2af --- /dev/null +++ b/libmango/arch/x86_64/syscall.S @@ -0,0 +1,93 @@ +#include "mango/syscall.h" + +# Registers: +# rax = syscall ID + return value +# rdi = 1st parameter +# rsi = 2nd parameter +# rdx = 3rd parameter +# r12 = 4th parameter +# r8 = 5th parameter +# r9 = 6th parameter +# r13 = 7th parameter +# r14 = 8th parameter +.macro SYSCALL_GATE name index args +.global \name +.type \name, @function +\name: + push %rbp + mov %rsp, %rbp + + # Syscall ID + mov $\index, %rax + + # The syscall instruction uses rcx, so move this parameter to r12 + .if \args >= 4 + pushq %r12 + movq %rcx, %r12 + .endif + + # r13 and r14 are callee-saved so we save it beforehand + .if \args >= 7 + pushq %r13 + movq 16(%rbp), %r13 + .endif + + .if \args >= 8 + pushq %r14 + movq 24(%rbp), %r14 + .endif + + syscall + + .if \args >= 8 + popq %r14 + .endif + + .if \args >= 7 + popq %r13 + .endif + + .if \args >= 4 + popq %r12 + .endif + + pop %rbp + ret +.endm + +SYSCALL_GATE task_exit SYS_TASK_EXIT 1 +SYSCALL_GATE task_create SYS_TASK_CREATE 5 +SYSCALL_GATE task_create_thread SYS_TASK_CREATE_THREAD 6 + +SYSCALL_GATE thread_start SYS_THREAD_START 1 + +SYSCALL_GATE vm_object_create SYS_VM_OBJECT_CREATE 5 +SYSCALL_GATE vm_object_read SYS_VM_OBJECT_READ 5 +SYSCALL_GATE vm_object_write SYS_VM_OBJECT_WRITE 5 +SYSCALL_GATE vm_object_copy SYS_VM_OBJECT_COPY 6 + +SYSCALL_GATE vm_region_create SYS_VM_REGION_CREATE 8 +SYSCALL_GATE vm_region_read SYS_VM_REGION_READ 5 +SYSCALL_GATE vm_region_write SYS_VM_REGION_WRITE 5 +SYSCALL_GATE vm_region_map_absolute SYS_VM_REGION_MAP_ABSOLUTE 7 +SYSCALL_GATE vm_region_map_relative SYS_VM_REGION_MAP_RELATIVE 7 +SYSCALL_GATE vm_region_unmap_absolute SYS_VM_REGION_UNMAP_ABSOLUTE 3 +SYSCALL_GATE vm_region_unmap_relative SYS_VM_REGION_UNMAP_RELATIVE 3 + +SYSCALL_GATE kern_log SYS_KERN_LOG 1 +SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1 +SYSCALL_GATE kern_config_get SYS_KERN_CONFIG_GET 3 +SYSCALL_GATE kern_config_set SYS_KERN_CONFIG_SET 3 + +SYSCALL_GATE channel_create SYS_CHANNEL_CREATE 3 +SYSCALL_GATE port_create SYS_PORT_CREATE 1 +SYSCALL_GATE port_connect SYS_PORT_CONNECT 3 +SYSCALL_GATE port_disconnect SYS_PORT_DISCONNECT 1 +SYSCALL_GATE msg_send SYS_MSG_SEND 4 +SYSCALL_GATE msg_recv SYS_MSG_RECV 4 +SYSCALL_GATE msg_reply SYS_MSG_REPLY 4 +SYSCALL_GATE msg_read SYS_MSG_READ 5 +SYSCALL_GATE msg_read_handles SYS_MSG_READ_HANDLES 5 +SYSCALL_GATE msg_write SYS_MSG_WRITE 5 +SYSCALL_GATE msg_write_handles SYS_MSG_WRITE_HANDLES 5 + diff --git a/libmango/include-user/mango/config.h b/libmango/include-user/mango/config.h new file mode 100644 index 0000000..c27de5e --- /dev/null +++ b/libmango/include-user/mango/config.h @@ -0,0 +1,17 @@ +#ifndef MANGO_CONFIG_H_ +#define MANGO_CONFIG_H_ + +#include +#include +#include + +extern kern_status_t kern_config_get( + kern_config_key_t key, + void *ptr, + size_t len); +extern kern_status_t kern_config_set( + kern_config_key_t key, + const void *ptr, + size_t len); + +#endif diff --git a/libmango/include-user/mango/handle.h b/libmango/include-user/mango/handle.h new file mode 100644 index 0000000..8d8196d --- /dev/null +++ b/libmango/include-user/mango/handle.h @@ -0,0 +1,9 @@ +#ifndef MANGO_HANDLE_H_ +#define MANGO_HANDLE_H_ + +#include +#include + +extern kern_status_t kern_handle_close(kern_handle_t handle); + +#endif diff --git a/libmango/include-user/mango/log.h b/libmango/include-user/mango/log.h new file mode 100644 index 0000000..de1f630 --- /dev/null +++ b/libmango/include-user/mango/log.h @@ -0,0 +1,21 @@ +#ifndef MANGO_LOG_H_ +#define MANGO_LOG_H_ + +#include + +extern kern_status_t kern_log(const char *s); + +#ifdef TRACE +#define kern_trace(...) kern_log(__VA_ARGS__) +#define kern_tracef(...) \ + do { \ + char s[128]; \ + snprintf(s, sizeof s, __VA_ARGS__); \ + kern_log(s); \ + } while (0) +#else +#define kern_trace(...) +#define kern_tracef(...) +#endif + +#endif diff --git a/libmango/include-user/mango/msg.h b/libmango/include-user/mango/msg.h new file mode 100644 index 0000000..870a8ef --- /dev/null +++ b/libmango/include-user/mango/msg.h @@ -0,0 +1,62 @@ +#ifndef MANGO_MSG_H_ +#define MANGO_MSG_H_ + +#include +#include + +extern kern_status_t channel_create( + unsigned int id, + channel_flags_t flags, + kern_handle_t *out); +extern kern_status_t port_create(kern_handle_t *out); +extern kern_status_t port_connect( + kern_handle_t port, + tid_t task_id, + unsigned int channel_id); +extern kern_status_t port_disconnect(kern_handle_t port); + +extern kern_status_t msg_send( + kern_handle_t port, + msg_flags_t flags, + const struct msg *req, + struct msg *resp); + +extern kern_status_t msg_recv( + kern_handle_t channel, + msg_flags_t flags, + msgid_t *out_id, + struct msg *out_msg); + +extern kern_status_t msg_reply( + kern_handle_t channel, + msg_flags_t flags, + msgid_t id, + const struct msg *reply); + +extern kern_status_t msg_read( + kern_handle_t channel, + msgid_t id, + size_t offset, + struct iovec *out, + size_t nr_out); +extern kern_status_t msg_read_handles( + kern_handle_t channel, + msgid_t id, + size_t offset, + struct handle_list *out, + size_t nr_out); + +extern kern_status_t msg_write( + kern_handle_t channel, + msgid_t id, + size_t offset, + const struct iovec *in, + size_t nr_in); +extern kern_status_t msg_write_handles( + kern_handle_t channel, + msgid_t id, + size_t offset, + const struct handle_list *in, + size_t nr_in); + +#endif diff --git a/libmango/include-user/mango/task.h b/libmango/include-user/mango/task.h new file mode 100644 index 0000000..236ee14 --- /dev/null +++ b/libmango/include-user/mango/task.h @@ -0,0 +1,25 @@ +#ifndef MANGO_TASK_H_ +#define MANGO_TASK_H_ + +#include +#include + +extern kern_status_t task_exit(int status); + +extern kern_status_t task_create( + kern_handle_t parent, + const char *name, + size_t name_len, + kern_handle_t *out_task, + kern_handle_t *out_address_space); +extern kern_status_t task_create_thread( + kern_handle_t task, + virt_addr_t ip, + virt_addr_t sp, + uintptr_t *args, + size_t nr_args, + kern_handle_t *out_thread); + +extern kern_status_t thread_start(kern_handle_t thread); + +#endif diff --git a/libmango/include-user/mango/vm.h b/libmango/include-user/mango/vm.h new file mode 100644 index 0000000..67ee6db --- /dev/null +++ b/libmango/include-user/mango/vm.h @@ -0,0 +1,79 @@ +#ifndef MANGO_VM_H_ +#define MANGO_VM_H_ + +#include +#include + +extern kern_status_t vm_object_create( + const char *name, + size_t name_len, + size_t data_len, + vm_prot_t prot, + kern_handle_t *out); +extern kern_status_t vm_object_read( + kern_handle_t object, + void *dst, + off_t offset, + size_t count, + size_t *nr_read); +extern kern_status_t vm_object_write( + kern_handle_t object, + const void *src, + off_t offset, + size_t count, + size_t *nr_written); +extern kern_status_t vm_object_copy( + kern_handle_t dst, + off_t dst_offset, + kern_handle_t src, + off_t src_offset, + size_t count, + size_t *nr_copied); + +extern kern_status_t vm_region_create( + kern_handle_t parent, + const char *name, + size_t name_len, + off_t offset, + size_t region_len, + vm_prot_t prot, + kern_handle_t *out, + virt_addr_t *out_base_address); +extern kern_status_t vm_region_read( + kern_handle_t region, + void *dst, + off_t offset, + size_t count, + size_t *nr_read); +extern kern_status_t vm_region_write( + kern_handle_t region, + const void *src, + off_t offset, + size_t count, + size_t *nr_read); +extern kern_status_t vm_region_map_absolute( + kern_handle_t region, + virt_addr_t map_address, + kern_handle_t object, + off_t object_offset, + size_t length, + vm_prot_t prot, + virt_addr_t *out_base_address); +extern kern_status_t vm_region_map_relative( + kern_handle_t region, + off_t region_offset, + kern_handle_t object, + off_t object_offset, + size_t length, + vm_prot_t prot, + virt_addr_t *out_base_address); +extern kern_status_t vm_region_unmap_absolute( + kern_handle_t region, + virt_addr_t address, + size_t length); +extern kern_status_t vm_region_unmap_relative( + kern_handle_t region, + off_t offset, + size_t length); + +#endif diff --git a/libmango/msg.c b/libmango/msg.c new file mode 100644 index 0000000..e69de29