From 8a21e8bf758153a482dee0af3e5f7a5a65dcfa70 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 7 Aug 2020 12:05:58 +0300 Subject: [PATCH] Add (pretty PoC) shared memory primitives --- include/sys/mem/shmem.h | 3 ++ include/user/syscall.h | 4 +++ sys/mem/shmem.c | 64 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/include/sys/mem/shmem.h b/include/sys/mem/shmem.h index 6eff022..2538891 100644 --- a/include/sys/mem/shmem.h +++ b/include/sys/mem/shmem.h @@ -5,5 +5,8 @@ struct thread; +int sys_shmget(size_t size, int flags); +void *sys_shmat(int id, const void *hint, int flags); + void *sys_mmap(void *hint, size_t length, int prot, int flags, int fd, off_t offset); int sys_munmap(void *addr, size_t length); diff --git a/include/user/syscall.h b/include/user/syscall.h index dc525ac..17dcf75 100644 --- a/include/user/syscall.h +++ b/include/user/syscall.h @@ -27,6 +27,10 @@ #define SYSCALL_NR_CHOWN 92 #define SYSCALL_NR_MKNOD 133 +#define SYSCALL_NR_SHMGET 113 +#define SYSCALL_NR_SHMAT 114 +#define SYSCALL_NR_SHMDT 115 + #define SYSCALL_NR_NANOSLEEP 35 #define SYSCALL_NR_UNAME 63 #define SYSCALL_NR_GETTIMEOFDAY 96 diff --git a/sys/mem/shmem.c b/sys/mem/shmem.c index 552b953..2d28cd7 100644 --- a/sys/mem/shmem.c +++ b/sys/mem/shmem.c @@ -15,6 +15,16 @@ #include "fs/node.h" #include "sys/mm.h" +// TODO: access control and stuff +struct shm_chunk { + int id; + struct list_head link; + size_t page_count; + uintptr_t pages[]; +}; + +static LIST_HEAD(g_shm_chunks); + static int sys_mmap_anon(mm_space_t space, uintptr_t base, size_t page_count, int prot, int flags) { uint64_t map_flags = MM_PAGE_USER; int map_usage = PU_PRIVATE; @@ -192,3 +202,57 @@ int sys_munmap(void *ptr, size_t len) { return 0; } + +int sys_shmget(size_t size, int flags) { + static int shmid = 0; + size = (size + MM_PAGE_SIZE - 1) / MM_PAGE_SIZE; + + struct shm_chunk *chunk = kmalloc(sizeof(struct shm_chunk) + size * sizeof(uintptr_t)); + _assert(chunk); + + chunk->page_count = size; + chunk->id = ++shmid; + list_head_init(&chunk->link); + + for (size_t i = 0; i < size; ++i) { + chunk->pages[i] = mm_phys_alloc_page(); + _assert(chunk->pages[i] != MM_NADDR); + } + + list_add(&chunk->link, &g_shm_chunks); + + return chunk->id; +} + +void *sys_shmat(int id, const void *hint, int flags) { + uintptr_t virt_base; + mm_space_t space; + struct shm_chunk *chunk, *iter; + + chunk = NULL; + list_for_each_entry(iter, &g_shm_chunks, link) { + if (iter->id == id) { + chunk = iter; + break; + } + } + if (!chunk) { + return (void *) -ENOENT; + } + + space = thread_self->proc->space; + + // TODO: use hint + virt_base = vmfind(space, 0x100000000, 0x400000000, chunk->page_count); + _assert(virt_base != MM_NADDR); + + for (size_t i = 0; i < chunk->page_count; ++i) { + mm_map_single(space, + virt_base + i * MM_PAGE_SIZE, + chunk->pages[i], + MM_PAGE_WRITE | MM_PAGE_USER, + PU_SHARED); + } + + return (void *) virt_base; +}