diff options
-rw-r--r-- | fs/proc/task_mmu.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index cfa63ee92c96..dfc791c42d64 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -925,15 +925,30 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, | |||
925 | struct mm_walk *walk) | 925 | struct mm_walk *walk) |
926 | { | 926 | { |
927 | struct pagemapread *pm = walk->private; | 927 | struct pagemapread *pm = walk->private; |
928 | unsigned long addr; | 928 | unsigned long addr = start; |
929 | int err = 0; | 929 | int err = 0; |
930 | pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); | ||
931 | 930 | ||
932 | for (addr = start; addr < end; addr += PAGE_SIZE) { | 931 | while (addr < end) { |
933 | err = add_to_pagemap(addr, &pme, pm); | 932 | struct vm_area_struct *vma = find_vma(walk->mm, addr); |
934 | if (err) | 933 | pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); |
935 | break; | 934 | unsigned long vm_end; |
935 | |||
936 | if (!vma) { | ||
937 | vm_end = end; | ||
938 | } else { | ||
939 | vm_end = min(end, vma->vm_end); | ||
940 | if (vma->vm_flags & VM_SOFTDIRTY) | ||
941 | pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY); | ||
942 | } | ||
943 | |||
944 | for (; addr < vm_end; addr += PAGE_SIZE) { | ||
945 | err = add_to_pagemap(addr, &pme, pm); | ||
946 | if (err) | ||
947 | goto out; | ||
948 | } | ||
936 | } | 949 | } |
950 | |||
951 | out: | ||
937 | return err; | 952 | return err; |
938 | } | 953 | } |
939 | 954 | ||