diff options
Diffstat (limited to 'mm/mremap.c')
-rw-r--r-- | mm/mremap.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/mm/mremap.c b/mm/mremap.c index 457d34ef3bf2..0843feb66f3d 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/swap.h> | 15 | #include <linux/swap.h> |
16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/swapops.h> | ||
18 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
19 | #include <linux/security.h> | 20 | #include <linux/security.h> |
20 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
@@ -69,6 +70,23 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma, | |||
69 | return pmd; | 70 | return pmd; |
70 | } | 71 | } |
71 | 72 | ||
73 | static pte_t move_soft_dirty_pte(pte_t pte) | ||
74 | { | ||
75 | /* | ||
76 | * Set soft dirty bit so we can notice | ||
77 | * in userspace the ptes were moved. | ||
78 | */ | ||
79 | #ifdef CONFIG_MEM_SOFT_DIRTY | ||
80 | if (pte_present(pte)) | ||
81 | pte = pte_mksoft_dirty(pte); | ||
82 | else if (is_swap_pte(pte)) | ||
83 | pte = pte_swp_mksoft_dirty(pte); | ||
84 | else if (pte_file(pte)) | ||
85 | pte = pte_file_mksoft_dirty(pte); | ||
86 | #endif | ||
87 | return pte; | ||
88 | } | ||
89 | |||
72 | static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, | 90 | static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
73 | unsigned long old_addr, unsigned long old_end, | 91 | unsigned long old_addr, unsigned long old_end, |
74 | struct vm_area_struct *new_vma, pmd_t *new_pmd, | 92 | struct vm_area_struct *new_vma, pmd_t *new_pmd, |
@@ -126,7 +144,8 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, | |||
126 | continue; | 144 | continue; |
127 | pte = ptep_get_and_clear(mm, old_addr, old_pte); | 145 | pte = ptep_get_and_clear(mm, old_addr, old_pte); |
128 | pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); | 146 | pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); |
129 | set_pte_at(mm, new_addr, new_pte, pte_mksoft_dirty(pte)); | 147 | pte = move_soft_dirty_pte(pte); |
148 | set_pte_at(mm, new_addr, new_pte, pte); | ||
130 | } | 149 | } |
131 | 150 | ||
132 | arch_leave_lazy_mmu_mode(); | 151 | arch_leave_lazy_mmu_mode(); |