diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-07 21:47:14 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-07 21:47:14 +0300 |
| commit | 219c27d420fe0abe5515cefc2513c6fe60aafdf9 (patch) | |
| tree | 5cd0c38a971245c91fd7bc3539b4a37c8a08a7f1 /src | |
| parent | fe4c623cb9320226866829317cea8ba0c49e7dbc (diff) | |
| download | kmi-219c27d420fe0abe5515cefc2513c6fe60aafdf9.tar.gz kmi-219c27d420fe0abe5515cefc2513c6fe60aafdf9.zip | |
add req_page back in as I realized it's useful
+ Can be used to pass contiguous memory regions to things like virtio
block devices for implementing disk drivers etc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/debug.c | 5 | ||||
| -rw-r--r-- | src/uapi/dispatch.c | 1 | ||||
| -rw-r--r-- | src/uapi/mem.c | 28 | ||||
| -rw-r--r-- | src/vmem.c | 28 |
4 files changed, 61 insertions, 1 deletions
diff --git a/src/debug.c b/src/debug.c index 9573bbc..567911b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -753,7 +753,10 @@ void dbg(const char *fmt, ...) if (is_set(flags, PRECS_FLAG)) i = precision; - chars_written += __puts(s); + for (; *s && i--;) { + __putchar(*s++); + chars_written++; + } fmt++; break; diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c index 16a17d2..4135171 100644 --- a/src/uapi/dispatch.c +++ b/src/uapi/dispatch.c @@ -50,6 +50,7 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, 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_PMEM: sys_req_pmem(t, a, b, c, d, e); break; + case SYS_REQ_PAGE: sys_req_page(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; diff --git a/src/uapi/mem.c b/src/uapi/mem.c index 17823a1..49370fc 100644 --- a/src/uapi/mem.c +++ b/src/uapi/mem.c @@ -106,6 +106,34 @@ SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size, } /** + * Allocate some contiguous region in memory. + * Due to page allocation constraints, this is generally just one page that's + * larger than the \p size parameter. Should work fine for 4K - 2M allocations, + * which I assume is generally what is used, but we'll see if I have to + * implement an actually good page allocator at some point. + * + * @param t Current tcb. + * @param size Minimum size of mapping. + * @param flags Flags of mapping. Unsure why you'd want anything besides VM_W | + * VM_R, but eh. + * + * @return \see sys_req_page(). + */ +SYSCALL_DEFINE2(req_page)(struct tcb *t, sys_arg_t size, sys_arg_t flags) +{ + struct tcb *r = get_cproc(t); + + pm_t addr = 0; + vm_t start = 0; + size_t asize = 0; + flags = sanitize_uvflags(flags); + if (!(start = alloc_uvpage(r, size, flags, &addr, &asize))) + return_args1(t, ERR_OOMEM); + + return_args4(t, OK, start, addr, asize); +} + +/** * Request shared memory syscall handler. * * @param t Current tcb. @@ -279,6 +279,34 @@ vm_t map_fixed_uvmem(struct tcb *t, pm_t start, size_t size, vmflags_t flags) return v + (start % BASE_PAGE_SIZE); } +vm_t alloc_uvpage(struct tcb *t, size_t size, vmflags_t flags, pm_t *startp, + size_t *sizep) +{ + enum mm_order order = nearest_order(size); + size = order_size(order); + + const vm_t v = alloc_region(&t->uvmem.region, size, &size, flags); + if (!v) + return 0; + + pm_t start = alloc_page(order); + if (!start) { + free_region(&t->uvmem.region, size); + return 0; + } + + if (map_fixed_region(t->proc.vmem, v, start, size, flags)) { + unmap_region(t->proc.vmem, v, size); + free_region(&t->uvmem.region, v); + return NULL; + } + + *startp = (pm_t)__pa(start); + *sizep = size; + return v; +} + + /* free_shared_uvmem shouldn't be needed, likely to work with free_uvmem */ vm_t alloc_shared_uvmem(struct tcb *s, size_t size, vmflags_t flags) { |
