diff options
| -rw-r--r-- | arch/riscv/kernel/main.c | 6 | ||||
| -rw-r--r-- | common/vmem.c | 45 | ||||
| -rw-r--r-- | include/apos/tcb.h | 1 | ||||
| -rw-r--r-- | include/apos/vmem.h | 11 |
4 files changed, 29 insertions, 34 deletions
diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c index 794b71b..914dcba 100644 --- a/arch/riscv/kernel/main.c +++ b/arch/riscv/kernel/main.c @@ -251,12 +251,14 @@ static void init_proc(void *fdt, struct vm_branch_t *b) sp_mem_init(&t->sp_r, SZ_4K, SZ_256G); /* binary itself */ - size_t sz = align_up(get_init_size(fdt), BASE_PAGE_SIZE); + size_t sz = get_init_size(fdt); + /* these need to be fixed and actually map the addresses that the ELF + * binary wants, instead of willy nilly */ t->bin = alloc_uvmem(t, sz, VM_V | VM_X | VM_R | VM_W | VM_U); /* stack */ t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U); - /* if it needs heap, it'll ask for it */ + /* should probably wrap this in like tlb_flush_all() or something */ __asm__ ("sfence.vma" : : : "memory"); move_init(fdt, (void *)t->bin); diff --git a/common/vmem.c b/common/vmem.c index 6d2b7dc..c6a4706 100644 --- a/common/vmem.c +++ b/common/vmem.c @@ -103,6 +103,9 @@ static struct sp_mem *sp_used_insert_region(struct sp_reg_root *r, struct sp_mem int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t arena_size) { + /* convert bytes to pages */ + start = __page(start); + arena_size = __page(arena_size); struct sp_mem *m = get_mem_node(); m->start = start; m->end = start + arena_size; @@ -162,12 +165,12 @@ static struct sp_mem *sp_mem_create_region(vm_t start, vm_t end, return m; } -static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size, size_t alignment) +static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size) { struct sp_node *n = sp_root(r->free_regions); while(n){ struct sp_mem *t = mem_container(n); - size_t nsize = t->end - align_up(t->start, alignment); + size_t nsize = t->end - t->start; if(size <= nsize) return t; @@ -182,34 +185,23 @@ static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size, siz * just ignore them for now. Note that alloc_region should only be used when * mmap is called with MAP_ANON, all other situations should be handled in some * fs server */ -vm_t alloc_region(struct sp_reg_root *r, size_t size, size_t alignment) +vm_t alloc_region(struct sp_reg_root *r, + size_t size, size_t *actual_size) { - struct sp_mem *m = sp_free_find_first(r, size, alignment); + *actual_size = align_up(size, BASE_PAGE_SIZE); + size_t pages = __page(*actual_size); + struct sp_mem *m = sp_free_find_first(r, pages); if(!m) return 0; sp_remove(&sp_root(r->free_regions), &m->sp_n); - vm_t aligned_start = align_up(m->start, alignment); - - vm_t pre_start = m->start; - vm_t pre_end = aligned_start; - - vm_t start = pre_end; - vm_t end = aligned_start + size; + vm_t start = m->start; + vm_t end = m->start + pages; vm_t post_start = end; vm_t post_end = m->end; - if(pre_start != pre_end){ - struct sp_mem *n = sp_mem_create_region(pre_start, pre_end, m->prev, m); - m->prev = n; - if(n->prev) - n->prev->next = n; - - sp_free_insert_region(r, n); - } - if(post_start != post_end){ struct sp_mem *n = sp_mem_create_region(post_start, post_end, m, m->next); m->next = n; @@ -223,7 +215,7 @@ vm_t alloc_region(struct sp_reg_root *r, size_t size, size_t alignment) m->start = start; mark_region_used(m->flags); sp_used_insert_region(r, m); - return start; + return __addr(start); } static void __sp_try_coalesce_prev(struct sp_reg_root *r, struct sp_mem *m) @@ -280,7 +272,11 @@ static void sp_mem_try_coalesce(struct sp_reg_root *r, struct sp_mem *m) void free_region(struct sp_reg_root *r, vm_t start) { - struct sp_mem *m = sp_used_find(r, start); + /* addr not aligned to page boundary, corrupted or incorrect pointer */ + if(start != __addr(__page(start))) + return; + + struct sp_mem *m = sp_used_find(r, __page(start)); if(!m) return; @@ -315,9 +311,8 @@ vm_t map_fill_region(struct vm_branch_t *b, vm_t start, size_t bytes, uint8_t fl vm_t alloc_uvmem(struct tcb *t, size_t s, uint8_t flags) { - size_t sa = align_up(s, BASE_PAGE_SIZE); - vm_t v = alloc_region(&t->sp_r, sa, 0); - return map_fill_region(t->b_r, v, sa, flags); + vm_t v = alloc_region(&t->sp_r, s, &s); + return map_fill_region(t->b_r, v, s, flags); } void free_uvmem(struct tcb *t, vm_t a) diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 9cef386..f987b43 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -23,6 +23,7 @@ struct tcb { id_t tid; vm_t stack; + vm_t heap; vm_t bin; struct vm_branch_t *b_r; diff --git a/include/apos/vmem.h b/include/apos/vmem.h index 2f6b10c..6918ba4 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -28,15 +28,12 @@ struct sp_mem { #define __va(x) (((char *)(x)) + VM_DMAP - RAM_BASE) #define __pa(x) (((char *)(x)) + RAM_BASE - VM_DMAP) +#define __page(x) ((x) / BASE_PAGE_SIZE) +#define __addr(x) ((x) * BASE_PAGE_SIZE) /* general overview of the different functions: - * (un)map_vmem: map one known page of physical memory to one known page of - * virtual memory - * - * (un)map_vregion: map known physical region to unknown virtual region within - * start and end - * - * (un)map_vsize: map unknown physical region to unknown virtual region + * internally they all work with pages, but they are called and return usable + * addresses, though within page bounds of course. */ /* defined by arch */ |
