diff options
Diffstat (limited to 'mm/mprotect.c')
-rw-r--r-- | mm/mprotect.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/mm/mprotect.c b/mm/mprotect.c index 14f93e62270f..638edabaff71 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -123,6 +123,7 @@ 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; | ||
126 | pgprot_t newprot; | 127 | pgprot_t newprot; |
127 | pgoff_t pgoff; | 128 | pgoff_t pgoff; |
128 | int error; | 129 | int error; |
@@ -149,8 +150,6 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, | |||
149 | } | 150 | } |
150 | } | 151 | } |
151 | 152 | ||
152 | newprot = protection_map[newflags & 0xf]; | ||
153 | |||
154 | /* | 153 | /* |
155 | * First try to merge with previous and/or next vma. | 154 | * First try to merge with previous and/or next vma. |
156 | */ | 155 | */ |
@@ -177,6 +176,14 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, | |||
177 | } | 176 | } |
178 | 177 | ||
179 | success: | 178 | 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 | |||
180 | /* | 187 | /* |
181 | * vm_flags and vm_page_prot are protected by the mmap_sem | 188 | * vm_flags and vm_page_prot are protected by the mmap_sem |
182 | * held in write mode. | 189 | * held in write mode. |