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 --- 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); _