--- mm/mmap.c.orig 2005-03-05 13:29:06.000000000 -0500 +++ mm/mmap.c 2005-03-05 13:33:51.000000000 -0500 @@ -1014,7 +1014,7 @@ * we just free'd - but there's no telling how much before. */ static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev, - unsigned long start, unsigned long end) + struct vm_area_struct *mpnt, unsigned long start, unsigned long end) { unsigned long first = start & PGDIR_MASK; unsigned long last = end + PGDIR_SIZE - 1; @@ -1046,6 +1046,14 @@ break; } no_mmaps: + while (mpnt && first < last) { + if ((mpnt->vm_end > first) &&(last > mpnt->vm_start)) { + first = mpnt->vm_end + PGDIR_SIZE - 1; + last = mpnt->vm_start; + } + mpnt = mpnt->vm_next; + } + if (last < first) return; /* @@ -1106,7 +1114,7 @@ extra = unmap_vma(mm, addr, len, mpnt, extra); } - free_pgtables(mm, prev, addr, addr+len); + free_pgtables(mm, prev, NULL, addr, addr+len); return extra; } @@ -1130,7 +1138,7 @@ find_vma_prev(mm, mpnt->vm_start, &prev); extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m); - free_pgtables(mm, prev, start, end); + free_pgtables(mm, prev, free_m, start, end); } return extra_m;