diff options
Diffstat (limited to 'mm/mprotect.c')
-rw-r--r-- | mm/mprotect.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/mm/mprotect.c b/mm/mprotect.c index 638edabaff71..367b7f6c0637 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -123,8 +123,6 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, | |||
123 | unsigned long oldflags = vma->vm_flags; | 123 | unsigned long oldflags = vma->vm_flags; |
124 | long nrpages = (end - start) >> PAGE_SHIFT; | 124 | long nrpages = (end - start) >> PAGE_SHIFT; |
125 | unsigned long charged = 0; | 125 | unsigned long charged = 0; |
126 | unsigned int mask; | ||
127 | pgprot_t newprot; | ||
128 | pgoff_t pgoff; | 126 | pgoff_t pgoff; |
129 | int error; | 127 | int error; |
130 | 128 | ||
@@ -176,24 +174,21 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, | |||
176 | } | 174 | } |
177 | 175 | ||
178 | success: | 176 | success: |
179 | /* Don't make the VMA automatically writable if it's shared, but the | ||
180 | * backer wishes to know when pages are first written to */ | ||
181 | mask = VM_READ|VM_WRITE|VM_EXEC|VM_SHARED; | ||
182 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) | ||
183 | mask &= ~VM_SHARED; | ||
184 | |||
185 | newprot = protection_map[newflags & mask]; | ||
186 | |||
187 | /* | 177 | /* |
188 | * vm_flags and vm_page_prot are protected by the mmap_sem | 178 | * vm_flags and vm_page_prot are protected by the mmap_sem |
189 | * held in write mode. | 179 | * held in write mode. |
190 | */ | 180 | */ |
191 | vma->vm_flags = newflags; | 181 | vma->vm_flags = newflags; |
192 | vma->vm_page_prot = newprot; | 182 | vma->vm_page_prot = protection_map[newflags & |
183 | (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; | ||
184 | if (vma_wants_writenotify(vma)) | ||
185 | vma->vm_page_prot = protection_map[newflags & | ||
186 | (VM_READ|VM_WRITE|VM_EXEC)]; | ||
187 | |||
193 | if (is_vm_hugetlb_page(vma)) | 188 | if (is_vm_hugetlb_page(vma)) |
194 | hugetlb_change_protection(vma, start, end, newprot); | 189 | hugetlb_change_protection(vma, start, end, vma->vm_page_prot); |
195 | else | 190 | else |
196 | change_protection(vma, start, end, newprot); | 191 | change_protection(vma, start, end, vma->vm_page_prot); |
197 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); | 192 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
198 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); | 193 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
199 | return 0; | 194 | return 0; |