diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r-- | fs/proc/task_mmu.c | 27 |
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 | |||
951 | out: | 960 | out: |
952 | return err; | 961 | return err; |
953 | } | 962 | } |