|
@@ -931,23 +931,32 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
|
|
while (addr < end) {
|
|
while (addr < end) {
|
|
struct vm_area_struct *vma = find_vma(walk->mm, addr);
|
|
struct vm_area_struct *vma = find_vma(walk->mm, addr);
|
|
pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
|
|
pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
|
|
- unsigned long vm_end;
|
|
|
|
|
|
+ /* End of address space hole, which we mark as non-present. */
|
|
|
|
+ unsigned long hole_end;
|
|
|
|
|
|
- if (!vma) {
|
|
|
|
- vm_end = end;
|
|
|
|
- } else {
|
|
|
|
- vm_end = min(end, vma->vm_end);
|
|
|
|
- if (vma->vm_flags & VM_SOFTDIRTY)
|
|
|
|
- pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY);
|
|
|
|
|
|
+ if (vma)
|
|
|
|
+ hole_end = min(end, vma->vm_start);
|
|
|
|
+ else
|
|
|
|
+ hole_end = end;
|
|
|
|
+
|
|
|
|
+ for (; addr < hole_end; addr += PAGE_SIZE) {
|
|
|
|
+ err = add_to_pagemap(addr, &pme, pm);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- for (; addr < vm_end; addr += PAGE_SIZE) {
|
|
|
|
|
|
+ if (!vma)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ /* Addresses in the VMA. */
|
|
|
|
+ if (vma->vm_flags & VM_SOFTDIRTY)
|
|
|
|
+ pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY);
|
|
|
|
+ for (; addr < min(end, vma->vm_end); addr += PAGE_SIZE) {
|
|
err = add_to_pagemap(addr, &pme, pm);
|
|
err = add_to_pagemap(addr, &pme, pm);
|
|
if (err)
|
|
if (err)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
out:
|
|
out:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|