summaryrefslogtreecommitdiff
blob: baf4907aba343c8857006421d2b199054ec07632 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
--- 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;