aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pmem.c1
-rw-r--r--src/proc.c12
-rw-r--r--src/regions.c13
-rw-r--r--src/tcb.c22
-rw-r--r--src/uapi/proc.c6
-rw-r--r--src/vmem.c18
6 files changed, 52 insertions, 20 deletions
diff --git a/src/pmem.c b/src/pmem.c
index e2177ea..871e15a 100644
--- a/src/pmem.c
+++ b/src/pmem.c
@@ -235,6 +235,7 @@ static bool __free_page(enum mm_order order, pm_t addr)
struct mm_bmap *bmap = __get_set(bucket, set);
bmap->used--;
+ assert(bitmap_is_set(bmap->bits, bit));
bitmap_clear(bmap->bits, bit);
__attach_set(bucket, bmap);
diff --git a/src/proc.c b/src/proc.c
index 5753659..1c90fdc 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -65,14 +65,14 @@ stat_t init_proc(void *fdt, vm_t *proc_fdt, vm_t *proc_initrd)
/** \todo start one thread per core, with special handling for init in
* that each thread starts at the entry point of init? */
- *proc_fdt = map_fixed_uvmem(t,
- (pm_t)fdt, fdt_totalsize(fdt),
- MR_SHARED | VM_V | VM_R | VM_U);
+ *proc_fdt = map_shared_fixed_uvmem(t,
+ (pm_t)fdt, fdt_totalsize(fdt),
+ VM_V | VM_R | VM_U);
pm_t initrd = (pm_t)__va(get_initrdbase(fdt));
- *proc_initrd = map_fixed_uvmem(t,
- initrd, get_initrdsize(fdt),
- MR_SHARED | VM_V | VM_R | VM_U);
+ *proc_initrd = map_shared_fixed_uvmem(t,
+ initrd, get_initrdsize(fdt),
+ VM_V | VM_R | VM_U);
info("mapped fdt at %lx\n", *proc_fdt);
info("mapped initrd at %lx\n", *proc_initrd);
diff --git a/src/regions.c b/src/regions.c
index fcfa0cc..64bfb88 100644
--- a/src/regions.c
+++ b/src/regions.c
@@ -466,8 +466,9 @@ vm_t alloc_region(struct mem_region_root *r, size_t size, size_t *actual_size,
return alloc_shared_region(r, size, actual_size, flags, 0);
}
-vm_t alloc_fixed_region(struct mem_region_root *r, vm_t start, size_t size,
- size_t *actual_size, vmflags_t flags)
+vm_t alloc_shared_fixed_region(struct mem_region_root *r, vm_t start,
+ size_t size, size_t *actual_size,
+ vmflags_t flags, id_t pid)
{
size_t asize = align_up(size, BASE_PAGE_SIZE);
if (actual_size)
@@ -499,7 +500,13 @@ vm_t alloc_fixed_region(struct mem_region_root *r, vm_t start, size_t size,
return 0;
/* actually start marking region used */
- return __partition_region(r, m, pages, start - m->start, flags, 0);
+ return __partition_region(r, m, pages, start - m->start, flags, pid);
+}
+
+vm_t alloc_fixed_region(struct mem_region_root *r, vm_t start, size_t size,
+ size_t *actual_size, vmflags_t flags)
+{
+ return alloc_shared_fixed_region(r, start, size, actual_size, flags, 0);
}
/**
diff --git a/src/tcb.c b/src/tcb.c
index 64d95a5..43c5a94 100644
--- a/src/tcb.c
+++ b/src/tcb.c
@@ -106,6 +106,7 @@ stat_t alloc_stack(struct tcb *t)
{
/* get parent process */
struct tcb *p = get_tcb(t->eid);
+ assert(p);
t->thread_stack = __setup_thread_stack(p, thread_stack_size());
if (!t->thread_stack)
@@ -171,16 +172,33 @@ struct tcb *create_thread(struct tcb *p)
t->eid = t->pid;
t->rid = p->rid;
+ /* hmm, the rest of this function is maybe a bit too difficult to follow
+ * for my liking. Will have to think about ways to make the logic more
+ * easy to follow */
if (!(t->rpc.vmem = create_vmem())) {
- if (likely(p))
+ if (likely(p)) {
+ free_page(MM_O0, bottom);
return NULL;
+ }
+
+ destroy_vmem(t->proc.vmem);
+ free_page(MM_O0, bottom);
+ return NULL;
+ }
+
+ if (setup_rpc_stack(t)) {
+ destroy_rpc_stack(t);
+ destroy_vmem(t->rpc.vmem);
+ if (likely(p)) {
+ free_page(MM_O0, bottom);
+ return NULL;
+ }
destroy_vmem(t->proc.vmem);
free_page(MM_O0, bottom);
return NULL;
}
- setup_rpc_stack(t);
reference_thread(p);
t->regs = (vm_t)t;
diff --git a/src/uapi/proc.c b/src/uapi/proc.c
index a99acb5..b010220 100644
--- a/src/uapi/proc.c
+++ b/src/uapi/proc.c
@@ -41,7 +41,11 @@ SYSCALL_DEFINE5(create)(struct tcb *t, sys_arg_t func,
/** @todo there's quite a bit of overlap between this and what
* core_bringup() is doing, might separate this out into its own
* function? */
- alloc_stack(c);
+ if (alloc_stack(c)) {
+ destroy_thread(c);
+ return_args1(t, ERR_OOMEM);
+ }
+
set_thread(c);
set_ret5(c, c->tid, d0, d1, d2, d3);
diff --git a/src/vmem.c b/src/vmem.c
index 96d4005..2feff45 100644
--- a/src/vmem.c
+++ b/src/vmem.c
@@ -83,8 +83,8 @@ static stat_t __copy_shared_region(struct tcb *d, struct mem_region *m)
reference_thread(s);
size_t size = end - start;
- vm_t v = alloc_fixed_region(&d->uvmem.region, start, size, &size,
- m->flags);
+ vm_t v = alloc_shared_fixed_region(&d->uvmem.region, start, size, &size,
+ m->flags, m->pid);
if (ERR_CODE(v))
return v;
@@ -155,9 +155,9 @@ static void __free_mapping(struct tcb *t, struct mem_region *m)
size_t size = end - start;
if (m->pid)
- unmap_fixed_region(t->proc.vmem, start, size);
+ unmap_fixed_region(t->uvmem.vmem, start, size);
else
- unmap_region(t->proc.vmem, start, size);
+ unmap_region(t->uvmem.vmem, start, size);
}
void clear_uvmem(struct tcb *t)
@@ -165,7 +165,7 @@ void clear_uvmem(struct tcb *t)
if (t->uvmem.owner != t->tid)
return;
- struct mem_region *m = find_closest_used_region(&t->uvmem.region, 0);
+ struct mem_region *m = find_first_region(&t->uvmem.region);
for (; m; m = m->next) {
if (is_region_kept(m))
continue;
@@ -183,7 +183,7 @@ void purge_uvmem(struct tcb *t)
if (t->uvmem.owner != t->tid)
return;
- struct mem_region *m = find_closest_used_region(&t->uvmem.region, 0);
+ struct mem_region *m = find_first_region(&t->uvmem.region);
for (; m; m = m->next) {
if (!is_set(m->flags, MR_USED))
continue;
@@ -266,11 +266,13 @@ vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags)
return v;
}
-vm_t map_fixed_uvmem(struct tcb *t, pm_t start, size_t size, vmflags_t flags)
+vm_t map_shared_fixed_uvmem(struct tcb *t, pm_t start, size_t size,
+ vmflags_t flags)
{
assert(is_aligned(start, BASE_PAGE_SIZE));
- const vm_t v = alloc_region(&t->uvmem.region, size, &size, flags);
+ const vm_t v = alloc_shared_region(&t->uvmem.region, size, &size, flags,
+ get_rproc(t)->tid);
if (ERR_CODE(v))
return v;