From 76517486919657ecadda9867125dc6730f29a5b7 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 6 Jul 2024 18:14:04 +0300 Subject: pretty massive virtual memory rewrite + The system is now a bit simpler and hopefully easier to understand, while also extending the shared memory to be 1:N, where there is one owner who may become a zombie while waiting for the N to die. --- src/uapi/dispatch.c | 2 +- src/uapi/mem.c | 80 +++++++++++++++++++++++++++-------------------------- src/uapi/proc.c | 6 ++-- 3 files changed, 45 insertions(+), 43 deletions(-) (limited to 'src/uapi') diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c index c4ad811..b5dbda2 100644 --- a/src/uapi/dispatch.c +++ b/src/uapi/dispatch.c @@ -49,10 +49,10 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, case SYS_NOOP: sys_noop(t, a, b, c, d, e); break; case SYS_PUTCH: sys_putch(t, a, b, c, d, e); break; case SYS_REQ_MEM: sys_req_mem(t, a, b, c, d, e); break; - case SYS_REQ_PAGE: sys_req_page(t, a, b, c, d, e); break; case SYS_REQ_PMEM: sys_req_pmem(t, a, b, c, d, e); break; case SYS_REQ_FIXMEM: sys_req_fixmem(t, a, b, c, d, e); break; case SYS_REQ_SHAREDMEM: sys_req_sharedmem(t, a, b, c, d, e); break; + case SYS_REF_SHAREDMEM: sys_ref_sharedmem(t, a, b, c, d, e); break; case SYS_FREE_MEM: sys_free_mem(t, a, b, c, d, e); break; case SYS_TIMEBASE: sys_timebase(t, a, b, c, d, e); break; case SYS_TICKS: sys_ticks(t, a, b, c, d, e); break; diff --git a/src/uapi/mem.c b/src/uapi/mem.c index d54390a..932027b 100644 --- a/src/uapi/mem.c +++ b/src/uapi/mem.c @@ -25,31 +25,13 @@ SYSCALL_DEFINE2(req_mem)(struct tcb *t, sys_arg_t size, sys_arg_t flags) { struct tcb *r = get_cproc(t); vm_t start = 0; - /** @todo expose flags to users */ + flags = sanitize_uvflags(flags); if (!(start = alloc_uvmem(r, size, flags))) return_args1(t, ERR_OOMEM); return_args2(t, OK, start); } -/** - * Allocate single page to program. - * - * @param t Current tcb. - * @param size Size of the allocation. - * @param flags Flags of allocation. - * @return \ref ERR_OOMEM if unsucessful, otherwise \ref OK, virtual address, - * actual size, physical address, in that order. - */ -SYSCALL_DEFINE2(req_page)(struct tcb *t, sys_arg_t size, sys_arg_t flags) -{ - struct tcb *r = get_cproc(t); - vm_t start = 0; pm_t paddr = 0; size_t asize = size; - if (!(start = alloc_uvpage(r, asize, flags, &asize, &paddr))) - return_args1(t, ERR_OOMEM); - - return_args4(t, OK, start, asize, paddr); -} /** * Fixed memory request syscall handler. @@ -66,6 +48,7 @@ SYSCALL_DEFINE3(req_fixmem)(struct tcb *t, sys_arg_t fixed, sys_arg_t size, { struct tcb *r = get_cproc(t); vm_t start = 0; + flags = sanitize_uvflags(flags); if (!(start = alloc_fixed_uvmem(r, fixed, size, flags))) return_args1(t, ERR_OOMEM); @@ -116,6 +99,7 @@ SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size, */ struct tcb *r = get_cproc(t); vm_t start = 0; + flags = sanitize_uvflags(flags); if (!(start = alloc_devmem(r, paddr, size, flags))) return_args1(t, ERR_OOMEM); @@ -126,33 +110,51 @@ SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size, * Request shared memory syscall handler. * * @param t Current tcb. - * @param tid Thread to share memory with. * @param size Minimum size of allocation. - * @param sflags Flags of allocation for \p t. - * @param cflags Flags of allocation for \p tid. - * @return \ref OK and start of \p t allocation and start of \p tid allocation, + * @param flags Flags of allocation. + * @return \ref OK, start and size * in that order, \ref ERR_OOMEM otherwise. + */ +SYSCALL_DEFINE2(req_sharedmem)(struct tcb *t, sys_arg_t size, sys_arg_t flags) +{ + struct tcb *c = get_cproc(t); + if (!has_cap(c->caps, CAP_SHARED)) + return_args1(t, ERR_PERM); + + vm_t start = 0; + flags = sanitize_uvflags(flags); + if (!(start = alloc_shared_uvmem(c, size, flags))) + return_args1(t, ERR_OOMEM); + + return_args3(t, OK, start, size); +} + +/** + * Reference shared memory. * - * @todo should we also take the thread who should get the other end of the - * memory? + * @param t Current tcb. + * @param tid In which thread's address space to create mapping. + * @param addr Address of shared region in \p t. + * @param flags Flags of allocation. + * @return \ref ERR_OOMEM if unsucessful, otherwise \ref OK, virtual address, + * actual size, in that order. Generally the actual size should match with the + * original shared region, but I wouldn't count on it. */ -SYSCALL_DEFINE4(req_sharedmem)(struct tcb *t, sys_arg_t tid, - sys_arg_t size, sys_arg_t sflags, - sys_arg_t cflags) +SYSCALL_DEFINE3(ref_sharedmem)(struct tcb *t, sys_arg_t tid, sys_arg_t addr, + sys_arg_t flags) { - /** @todo check capability for shared memory */ - struct tcb *u = get_tcb(tid); - if (!u) - return_args1(t, ERR_INVAL); + struct tcb *c = get_cproc(t); + if (!has_cap(c->caps, CAP_SHARED)) + return_args1(t, ERR_PERM); - struct tcb *s = get_cproc(t); - struct tcb *c = get_rproc(u); + struct tcb *r = get_tcb(tid); + if (!r || zombie(r)) + return_args1(t, ERR_INVAL); - vm_t sstart, cstart; - if (alloc_shared_uvmem(s, c, size, sflags, cflags, &sstart, &cstart)) + vm_t start = 0; size_t size = 0; + flags = sanitize_uvflags(flags); + if (!(start = ref_shared_uvmem(r, c, addr, flags))) return_args1(t, ERR_OOMEM); - return_args3(t, OK, sstart, cstart); + return_args3(t, OK, start, size); } - -/** \todo add some way to specify who gets to access the shared memory? */ diff --git a/src/uapi/proc.c b/src/uapi/proc.c index 85acb29..ff02113 100644 --- a/src/uapi/proc.c +++ b/src/uapi/proc.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include @@ -100,7 +100,7 @@ SYSCALL_DEFINE2(exec)(struct tcb *t, sys_arg_t bin, sys_arg_t interp) return_args1(t, ERR_INVAL); /* mark binary to be kept */ - struct mem_region *b = find_used_region(&t->sp_r, bin); + struct mem_region *b = find_used_region(&t->uvmem.region, bin); if (!b) return_args1(t, ERR_ADDR); @@ -109,7 +109,7 @@ SYSCALL_DEFINE2(exec)(struct tcb *t, sys_arg_t bin, sys_arg_t interp) struct mem_region *i = 0; if (interp) { /* mark interpreter to be kept */ - i = find_used_region(&t->sp_r, interp); + i = find_used_region(&t->uvmem.region, interp); if (!i) return_args1(t, ERR_INVAL); -- cgit v1.3