diff --git a/tasks/libposix/exit.c b/tasks/libposix/exit.c index 79083ad..d9cede9 100644 --- a/tasks/libposix/exit.c +++ b/tasks/libposix/exit.c @@ -21,6 +21,7 @@ static inline void __attribute__ ((noreturn)) l4_exit(int status) void __attribute__ ((noreturn)) _exit(int status) { + printf("In %s.\n", __FUNCTION__); l4_exit(status); } diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index fd9d7ed..e9a9742 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -248,10 +248,7 @@ int validate_task_range(struct tcb *t, unsigned long start, /* Changes all shadows and their ptes to read-only */ int vm_freeze_shadows(struct tcb *task); -static inline void task_add_vma(struct tcb *task, struct vm_area *vma) -{ - list_add(&vma->list, &task->vm_area_head->list); -} +int task_insert_vma(struct vm_area *vma, struct list_head *vma_list); /* Main page fault entry point */ int page_fault_handler(struct tcb *faulty_task, fault_kdata_t *fkdata); diff --git a/tasks/mm0/src/execve.c b/tasks/mm0/src/execve.c index 0d244f2..52d3fe4 100644 --- a/tasks/mm0/src/execve.c +++ b/tasks/mm0/src/execve.c @@ -225,7 +225,8 @@ int strncpy_page(void *to_ptr, void *from_ptr, int maxlength) /* * Copy from one buffer to another. Stop if maxlength or * a page boundary is hit. Breaks if unsigned long sized copy value is 0, - * as opposed to a 0 byte as in string copy. + * as opposed to a 0 byte as in string copy. If byte size 0 was used + * a valid pointer with a 0 byte in it would give a false termination. */ int bufncpy_page(void *to_ptr, void *from_ptr, int maxlength) { diff --git a/tasks/mm0/src/file.c b/tasks/mm0/src/file.c index 1295c35..ff89890 100644 --- a/tasks/mm0/src/file.c +++ b/tasks/mm0/src/file.c @@ -243,6 +243,7 @@ int file_open(struct tcb *opener, int fd) return 0; } + /* * Inserts the page to vmfile's list in order of page frame offset. * We use an ordered list instead of a better data structure for now. diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 792a7c3..8fc315e 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -38,6 +38,65 @@ struct vm_area *vma_new(unsigned long pfn_start, unsigned long npages, return vma; } +/* + * Inserts a new vma to the ordered vm area list. + * + * The new vma is assumed to have been correctly set up not to intersect + * with any other existing vma. + */ +int task_insert_vma(struct vm_area *this, struct list_head *vma_list) +{ + struct vm_area *before, *after; + + /* Add if list is empty */ + if (list_empty(vma_list)) { + list_add_tail(&this->list, vma_list); + return 0; + } + + /* Else find the right interval */ + list_for_each_entry(before, vma_list, list) { + after = list_entry(before->list.next, struct vm_area, list); + + /* If there's only one in list */ + if (before->list.next == vma_list) { + + /* Eliminate the possibility of intersection */ + BUG_ON(set_intersection(this->pfn_start, this->pfn_end, + before->pfn_start, + before->pfn_end)); + + /* Add as next if greater */ + if (this->pfn_start > before->pfn_start) + list_add(&this->list, &before->list); + /* Add as previous if smaller */ + else if (this->pfn_start < before->pfn_start) + list_add_tail(&this->list, &before->list); + else + BUG(); + + return 0; + } + + /* If this page is in-between two other, insert it there */ + if (before->pfn_start < this->pfn_start && + after->pfn_start > this->pfn_start) { + + /* Eliminate possibility of intersection */ + BUG_ON(set_intersection(this->pfn_start, this->pfn_end, + before->pfn_start, + before->pfn_end)); + BUG_ON(set_intersection(this->pfn_start, this->pfn_end, + after->pfn_start, + after->pfn_end)); + list_add(&this->list, &before->list); + + return 0; + } + } + BUG(); +} + /* Search an empty space in the task's mmapable address region. */ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task) { @@ -234,7 +293,7 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset, /* Finished initialising the vma, add it to task */ dprintf("%s: Mapping 0x%x - 0x%x\n", __FUNCTION__, map_address, map_address + __pfn_to_addr(npages)); - task_add_vma(task, new); + task_insert_vma(new, &task->vm_area_head->list); /* * If area is going to be used going downwards, (i.e. as a stack) diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 6937d73..e37453e 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -194,7 +194,7 @@ int task_copy_vmas(struct tcb *to, struct tcb *from) vma_copy_links(new_vma, vma); /* All link copying is finished, now add the new vma to task */ - task_add_vma(to, new_vma); + task_insert_vma(new_vma, &to->vm_area_head->list); } return 0; diff --git a/tasks/test0/src/forktest.c b/tasks/test0/src/forktest.c index 9d83806..410f2e4 100644 --- a/tasks/test0/src/forktest.c +++ b/tasks/test0/src/forktest.c @@ -21,12 +21,14 @@ int forktest(void) myid = getpid(); pid = myid; if (global != 0) { + printf("Global not zero.\n"); printf("-- FAILED --\n"); goto out; } global = myid; if (global != myid) { + printf("Global has not changed to myid.\n"); printf("-- FAILED --\n"); goto out; }