From 8a5e4cf53d981e793fca90d9b51bd395265cf4db Mon Sep 17 00:00:00 2001 From: Kimplul Date: Thu, 26 Jan 2023 15:53:16 +0200 Subject: add req_page syscall --- common/mem.c | 9 +++++++++ common/uapi/dispatch.c | 1 + common/uapi/mem.c | 19 +++++++++++++++++++ common/vmem.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) (limited to 'common') diff --git a/common/mem.c b/common/mem.c index 2cf72e3..f4a0919 100644 --- a/common/mem.c +++ b/common/mem.c @@ -17,6 +17,15 @@ size_t __mm_sizes[10]; size_t __mm_page_shift; enum mm_order __mm_max_order; +enum mm_order nearest_order(size_t size) +{ + for (enum mm_order order = max_order(); order >= MM_MIN; --order) + if (order_size(order) >= size) + return order; + + return MM_O0; +} + void init_mem(size_t max_order, size_t bits[10], size_t page_shift) { __mm_max_order = max_order; diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index d11e02e..b5cd51e 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -51,6 +51,7 @@ 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; diff --git a/common/uapi/mem.c b/common/uapi/mem.c index 099028e..41ebcca 100644 --- a/common/uapi/mem.c +++ b/common/uapi/mem.c @@ -32,6 +32,25 @@ SYSCALL_DEFINE2(req_mem)(struct tcb *t, sys_arg_t size, sys_arg_t flags) return_args(t, SYS_RET2(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_args(t, SYS_RET1(ERR_OOMEM)); + + return_args(t, SYS_RET4(OK, start, asize, paddr)); +} + /** * Fixed memory request syscall handler. * diff --git a/common/vmem.c b/common/vmem.c index f1eed83..b28a3d6 100644 --- a/common/vmem.c +++ b/common/vmem.c @@ -200,6 +200,36 @@ vm_t alloc_uvmem(struct tcb *t, size_t size, vmflags_t flags) return w; } +vm_t alloc_uvpage(struct tcb *t, size_t size, vmflags_t flags, size_t *asize, + pm_t *paddr) +{ + hard_assert(t && is_proc(t), ERR_INVAL); + + enum mm_order order = nearest_order(size); + size_t actual_size = order_size(order); + stat_t status = OK; + + const vm_t v = alloc_region(&t->sp_r, size, &size, flags); + const vm_t w = __addr(__page(v)); + + pm_t addr = alloc_page(order); + /** @todo should free region */ + if (!addr) + return NULL; + + status = map_vpage(t->proc.vmem, addr, w, flags, order); + if (is_rpc(t) && status == INFO_SEFF) + clone_rpc_maps(t); + + if (asize) + *asize = actual_size; + + if (paddr) + *paddr = addr; + + return w; +} + vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags) { hard_assert(t && is_proc(t), ERR_INVAL); -- cgit v1.3