We're modifying src_pte and dst_pte in the for-loop, and then unmapping the
modified pointers.  If one of them walked off the end of the page then blam.


Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/mm/memory.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff -puN mm/memory.c~4level-highpte-fix mm/memory.c
--- 25/mm/memory.c~4level-highpte-fix	Wed Nov 10 14:58:55 2004
+++ 25-akpm/mm/memory.c	Wed Nov 10 15:00:58 2004
@@ -332,7 +332,8 @@ static int copy_pte_range(struct mm_stru
 				struct vm_area_struct *vma,
 			   	unsigned long addr, unsigned long end)
 {
-	pte_t * src_pte, * dst_pte;
+	pte_t *src_pte, *dst_pte;
+	pte_t *s, *d;
 	unsigned long vm_flags = vma->vm_flags;
 
 	dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
@@ -341,12 +342,12 @@ static int copy_pte_range(struct mm_stru
 
 	spin_lock(&src_mm->page_table_lock);
 	src_pte = pte_offset_map_nested(src_pmd, addr);
-	for (;
-	     addr < end;
-	     addr += PAGE_SIZE, src_pte++, dst_pte++) {
-		if (pte_none(*src_pte))
+	d = dst_pte;
+	s = src_pte;
+	for ( ; addr < end; addr += PAGE_SIZE, s++, d++) {
+		if (pte_none(*s))
 			continue;
-		copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vm_flags, addr);
+		copy_one_pte(dst_mm, src_mm, d, s, vm_flags, addr);
 	}
 	pte_unmap_nested(src_pte);
 	pte_unmap(dst_pte);
_