aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/task_mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r--fs/proc/task_mmu.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index dfc791c42d64..c34156888d70 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -931,23 +931,32 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
931 while (addr < end) { 931 while (addr < end) {
932 struct vm_area_struct *vma = find_vma(walk->mm, addr); 932 struct vm_area_struct *vma = find_vma(walk->mm, addr);
933 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); 933 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
934 unsigned long vm_end; 934 /* End of address space hole, which we mark as non-present. */
935 unsigned long hole_end;
935 936
936 if (!vma) { 937 if (vma)
937 vm_end = end; 938 hole_end = min(end, vma->vm_start);
938 } else { 939 else
939 vm_end = min(end, vma->vm_end); 940 hole_end = end;
940 if (vma->vm_flags & VM_SOFTDIRTY) 941
941 pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY); 942 for (; addr < hole_end; addr += PAGE_SIZE) {
943 err = add_to_pagemap(addr, &pme, pm);
944 if (err)
945 goto out;
942 } 946 }
943 947
944 for (; addr < vm_end; addr += PAGE_SIZE) { 948 if (!vma)
949 break;
950
951 /* Addresses in the VMA. */
952 if (vma->vm_flags & VM_SOFTDIRTY)
953 pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY);
954 for (; addr < min(end, vma->vm_end); addr += PAGE_SIZE) {
945 err = add_to_pagemap(addr, &pme, pm); 955 err = add_to_pagemap(addr, &pme, pm);
946 if (err) 956 if (err)
947 goto out; 957 goto out;
948 } 958 }
949 } 959 }
950
951out: 960out:
952 return err; 961 return err;
953} 962}