aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-05-21 21:02:17 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-05-21 21:02:17 +0300
commit8da0171e5ca3492cdb34422184a1c96acd0b5165 (patch)
treec125b7286f929c8ff7f8a2b938cec84328e99de4 /common
parent836026dbba64793afc0d2591ffdb6fb39b696977 (diff)
downloadkmi-8da0171e5ca3492cdb34422184a1c96acd0b5165.tar.gz
kmi-8da0171e5ca3492cdb34422184a1c96acd0b5165.zip
add status info to memory mappings
+ next up would probably be to start working on process/thread relationships, largely as documented. Still not entirely sure about how I want to handle fork, but I suppose I might figure it out at some point.
Diffstat (limited to 'common')
-rw-r--r--common/dmem.c17
-rw-r--r--common/elf.c2
-rw-r--r--common/mem_regions.c5
-rw-r--r--common/tcb.c15
-rw-r--r--common/uapi/ipc.c2
-rw-r--r--common/vmem.c71
6 files changed, 82 insertions, 30 deletions
diff --git a/common/dmem.c b/common/dmem.c
index 59ea666..6c207c1 100644
--- a/common/dmem.c
+++ b/common/dmem.c
@@ -27,15 +27,17 @@ stat_t init_devmem(pm_t ram_base, pm_t ram_top)
}
stat_t dev_alloc_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order)
+ vmflags_t flags, enum mm_order order, void *data)
{
- map_vpage(b, *offset, vaddr, flags, order);
+ stat_t *status = (stat_t *)data;
+ /* TODO: remember to do something with this status info */
+ *status = map_vpage(b, *offset, vaddr, flags, order);
*offset += __o_size(order);
return OK;
}
stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order)
+ vmflags_t flags, enum mm_order order, void *data)
{
UNUSED(offset);
UNUSED(flags);
@@ -43,9 +45,10 @@ stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
enum mm_order v_order = 0;
stat_vpage(b, vaddr, &paddr, &v_order, 0);
if (order != v_order)
- return REGION_TRY_AGAIN;
+ return INFO_TRGN;
- unmap_vpage(b, vaddr);
+ stat_t *status = (stat_t *)data;
+ *status = unmap_vpage(b, vaddr);
return OK;
}
@@ -62,7 +65,7 @@ vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, vmflags_t flags)
return 0;
return map_fill_region(t->b_r, &dev_alloc_wrapper, dev_start, region,
- bytes, flags);
+ bytes, flags, 0);
}
stat_t free_devmem(struct tcb *t, vm_t dev_start)
@@ -85,7 +88,7 @@ stat_t free_devmem(struct tcb *t, vm_t dev_start)
size_t region_size = __addr(m->end - m->start);
map_fill_region(t->b_r, &dev_free_wrapper, dev_paddr, dev_start,
- region_size, 0);
+ region_size, 0, 0);
if (dev_paddr < __pre_top)
free_region(&pre_ram, dev_paddr);
diff --git a/common/elf.c b/common/elf.c
index 459cacf..9af4f08 100644
--- a/common/elf.c
+++ b/common/elf.c
@@ -46,7 +46,7 @@ static void __map_exec(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart,
uint8_t elf_flags = program_header_prop(ei_c, runner, p_flags);
uint8_t uvflags = __elf_to_uvflags(elf_flags);
- map_allocd_region(t->b_r, start, vsz, default_flags);
+ map_allocd_region(t->b_r, start, vsz, default_flags, 0);
vm_t vo = bin + program_header_prop(ei_c, runner, p_offset);
vm_t vfz = program_header_prop(ei_c, runner, p_filesz);
diff --git a/common/mem_regions.c b/common/mem_regions.c
index b0cbe0e..bbc894e 100644
--- a/common/mem_regions.c
+++ b/common/mem_regions.c
@@ -426,7 +426,8 @@ stat_t free_known_region(struct mem_region_root *r, struct mem_region *m)
* permutations etc. which would be slow and I don't want to implement it.
*/
vm_t map_fill_region(struct vm_branch *b, region_callback_t *mem_handler,
- pm_t offset, vm_t start, size_t bytes, vmflags_t flags)
+ pm_t offset, vm_t start, size_t bytes, vmflags_t flags,
+ void *data)
{
pm_t runner = __page(start);
size_t pages = __pages(bytes);
@@ -447,7 +448,7 @@ vm_t map_fill_region(struct vm_branch *b, region_callback_t *mem_handler,
while (pages >= o_pages) {
stat_t res = mem_handler(b, &offset, __addr(runner),
- flags, top);
+ flags, top, data);
if (res > 0)
break;
diff --git a/common/tcb.c b/common/tcb.c
index bb1bcec..212e20f 100644
--- a/common/tcb.c
+++ b/common/tcb.c
@@ -4,7 +4,9 @@
#include <apos/pmem.h>
#include <apos/nodes.h>
#include <apos/types.h>
+#include <apos/assert.h>
#include <apos/string.h>
+#include <arch/vmem.h>
/* arguably exessively many globals... */
static id_t start_tid;
@@ -98,3 +100,16 @@ struct tcb *get_tcb(id_t tid)
return tcbs[tid];
}
+
+stat_t clone_tcb_maps(struct tcb *r)
+{
+ hard_assert(r && !r->parent, ERR_INVAL);
+ struct tcb *t = r;
+ while ((t = t->next)) {
+ stat_t ret = clone_vmbranch(r->b_r, t->b_r);
+ if (ret)
+ return ret;
+ }
+
+ return OK;
+}
diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c
index bef9665..d7c9d16 100644
--- a/common/uapi/ipc.c
+++ b/common/uapi/ipc.c
@@ -14,7 +14,7 @@ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback)
SYSCALL_DEFINE3(ipc_req)(sys_arg_t tid, sys_arg_t d0, sys_arg_t d1)
{
struct tcb *r = get_tcb(tid);
- /* something like jump_to_callback(t, d0, d1) */
+ /* something like jump_to_callback(t) */
return (struct sys_ret){ d0, d1 };
}
diff --git a/common/vmem.c b/common/vmem.c
index 989029a..817f851 100644
--- a/common/vmem.c
+++ b/common/vmem.c
@@ -1,4 +1,6 @@
#include <apos/mem_regions.h>
+#include <apos/assert.h>
+#include <apos/debug.h>
#include <apos/bits.h>
#include <apos/vmem.h>
#include <arch/vmem.h>
@@ -10,23 +12,46 @@ stat_t init_uvmem(struct tcb *t, vm_t base, vm_t top)
vm_t alloc_uvmem(struct tcb *t, size_t size, vmflags_t flags)
{
- vm_t v = alloc_region(&t->sp_r, size, &size, flags);
- return map_allocd_region(t->b_r, v, size, flags);
+ /* t exists and is the root tcb of the current process */
+ hard_assert(t && !t->parent, ERR_INVAL);
+
+ stat_t status = OK;
+ const vm_t v = alloc_region(&t->sp_r, size, &size, flags);
+ const vm_t w = map_allocd_region(t->b_r, v, size, flags, &status);
+ if (status == INFO_SEFF)
+ clone_tcb_maps(t);
+
+ return w;
}
vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags)
{
- vm_t v = alloc_fixed_region(&t->sp_r, start, size, &size, flags);
- return map_allocd_region(t->b_r, v, size, flags);
+ hard_assert(t && !t->parent, ERR_INVAL);
+
+ stat_t status = OK;
+ const vm_t v = alloc_fixed_region(&t->sp_r, start, size, &size, flags);
+ const vm_t w = map_allocd_region(t->b_r, v, size, flags, &status);
+
+ if (status == INFO_SEFF)
+ clone_tcb_maps(t);
+
+ return w;
}
/* free_shared_uvmem shouldn't be needed, likely to work with free_uvmem */
vm_t alloc_shared_uvmem(struct tcb *t, size_t size, vmflags_t flags)
{
- /* TODO: proper error handling */
- vm_t v = alloc_region(&t->sp_r, size, &size,
- flags | MR_SHARED | MR_OWNED);
- return map_shared_region(t->b_r, v, size, flags);
+ hard_assert(t && t->parent, ERR_INVAL);
+
+ stat_t status = OK;
+ const vm_t v = alloc_region(&t->sp_r, size, &size,
+ flags | MR_SHARED | MR_OWNED);
+ const vm_t w = map_shared_region(t->b_r, v, size, flags, &status);
+
+ if (status == INFO_SEFF)
+ clone_tcb_maps(t);
+
+ return w;
}
vm_t ref_shared_uvmem(struct tcb *t1, struct tcb *t2, vm_t va, vmflags_t flags)
@@ -54,6 +79,7 @@ vm_t ref_shared_uvmem(struct tcb *t1, struct tcb *t2, vm_t va, vmflags_t flags)
return v;
}
+/* TODO: assume tcb is root tcb? */
stat_t free_uvmem(struct tcb *t, vm_t va)
{
struct mem_region *m = find_used_region(&t->sp_r, va);
@@ -64,26 +90,31 @@ stat_t free_uvmem(struct tcb *t, vm_t va)
vmflags_t flags = m->flags;
free_region(&t->sp_r, va);
- unmap_freed_region(t->b_r, va, pa, flags);
- return 0;
+
+ stat_t status = OK;
+ unmap_freed_region(t->b_r, va, pa, flags, &status);
+ if (status == INFO_SEFF)
+ return clone_tcb_maps(t);
+
+ return status;
}
stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order)
+ vmflags_t flags, enum mm_order order, void *data)
{
*offset = alloc_page(order, *offset);
if (!*offset)
- return REGION_TRY_AGAIN; /* try again */
+ return INFO_TRGN; /* try again */
- map_vpage(b, *offset, vaddr, flags, order);
- return OK;
+ stat_t ret = map_vpage(b, *offset, vaddr, flags, order);
+ return ret;
}
stat_t alloc_shared_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order)
+ vmflags_t flags, enum mm_order order, void *data)
{
if (order != MM_O0)
- return REGION_TRY_AGAIN;
+ return INFO_TRGN;
*offset = alloc_page(MM_O0, *offset);
map_vpage(b, *offset, vaddr, flags, order);
@@ -91,7 +122,7 @@ stat_t alloc_shared_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
}
stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order)
+ vmflags_t flags, enum mm_order order, void *data)
{
UNUSED(flags);
UNUSED(offset);
@@ -100,11 +131,13 @@ stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr,
enum mm_order v_order = 0;
stat_vpage(b, vaddr, &paddr, &v_order, 0);
if (order != v_order)
- return REGION_TRY_AGAIN;
+ return INFO_TRGN;
- unmap_vpage(b, vaddr);
+ stat_t *status = (stat_t *)data;
+ *status = unmap_vpage(b, vaddr);
/* don't free shared pages, unless they're owned */
if (!__is_set(flags, MR_SHARED) || __is_set(flags, MR_OWNED))
free_page(order, paddr);
+
return OK;
}