diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index dd7004c..47f6dc2 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -183,23 +183,8 @@ struct vm_area { unsigned long file_offset; /* File offset in pfns */ }; -/* Finds 'a' vma that is in this range. Only useful for munmap() */ -static inline struct vm_area * -find_vma_byrange(unsigned long pfn_start, - unsigned long pfn_end, struct list_head *vm_area_list) -{ - struct vm_area *vma; - - list_for_each_entry(vma, vm_area_list, list) { - if ((pfn_start >= vma->pfn_start) && (pfn_start < vma->pfn_end)) - return vma; - if ((pfn_end >= vma->pfn_start) && (pfn_end < vma->pfn_end)) - return vma; - } - return 0; -} - - +int vma_intersect(unsigned long pfn_start, unsigned long pfn_end, + struct vm_area *vma); /* * Finds the vma that has the given address. * TODO: In the future a lot of use cases may need to traverse each vma diff --git a/tasks/mm0/src/munmap.c b/tasks/mm0/src/munmap.c index ba28c4f..780289d 100644 --- a/tasks/mm0/src/munmap.c +++ b/tasks/mm0/src/munmap.c @@ -129,21 +129,24 @@ int do_munmap(struct tcb *task, void *vaddr, unsigned long npages) { const unsigned long munmap_start = __pfn(vaddr); const unsigned long munmap_end = munmap_start + npages; - struct vm_area *vma; + struct vm_area *vma, *n; int err; - /* Find a vma that overlaps with this address range */ - while ((vma = find_vma_byrange(munmap_start, munmap_end, - &task->vm_area_head->list))) { + list_for_each_entry_safe(vma, n, &task->vm_area_head->list, list) { + /* Check for intersection */ + if (vma_intersect(munmap_start, munmap_end, vma)) { + /* + * Flush pages if vma is writable, + * dirty and file-backed. + */ + if ((err = vma_flush_pages(vma)) < 0) + return err; - /* Flush pages if vma is writable, dirty and file-backed. */ - if ((err = vma_flush_pages(vma)) < 0) - return err; - - /* Unmap the vma accordingly. Note, this may delete the vma */ - if ((err = vma_unmap(vma, task, munmap_start, - munmap_end)) < 0) - return err; + /* Unmap the vma accordingly. This may delete the vma */ + if ((err = vma_unmap(vma, task, munmap_start, + munmap_end)) < 0) + return err; + } } /* Unmap those pages from the task address space */ @@ -152,7 +155,6 @@ int do_munmap(struct tcb *task, void *vaddr, unsigned long npages) return 0; } - int sys_munmap(struct tcb *task, void *start, unsigned long length) { /* Must be aligned on a page boundary */