diff options
Diffstat (limited to 'mm/mprotect.c')
-rw-r--r-- | mm/mprotect.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/mm/mprotect.c b/mm/mprotect.c index 848e946b08e5..8edd0d576254 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -193,14 +193,14 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, | |||
193 | } | 193 | } |
194 | 194 | ||
195 | static inline unsigned long change_pud_range(struct vm_area_struct *vma, | 195 | static inline unsigned long change_pud_range(struct vm_area_struct *vma, |
196 | pgd_t *pgd, unsigned long addr, unsigned long end, | 196 | p4d_t *p4d, unsigned long addr, unsigned long end, |
197 | pgprot_t newprot, int dirty_accountable, int prot_numa) | 197 | pgprot_t newprot, int dirty_accountable, int prot_numa) |
198 | { | 198 | { |
199 | pud_t *pud; | 199 | pud_t *pud; |
200 | unsigned long next; | 200 | unsigned long next; |
201 | unsigned long pages = 0; | 201 | unsigned long pages = 0; |
202 | 202 | ||
203 | pud = pud_offset(pgd, addr); | 203 | pud = pud_offset(p4d, addr); |
204 | do { | 204 | do { |
205 | next = pud_addr_end(addr, end); | 205 | next = pud_addr_end(addr, end); |
206 | if (pud_none_or_clear_bad(pud)) | 206 | if (pud_none_or_clear_bad(pud)) |
@@ -212,6 +212,26 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma, | |||
212 | return pages; | 212 | return pages; |
213 | } | 213 | } |
214 | 214 | ||
215 | static inline unsigned long change_p4d_range(struct vm_area_struct *vma, | ||
216 | pgd_t *pgd, unsigned long addr, unsigned long end, | ||
217 | pgprot_t newprot, int dirty_accountable, int prot_numa) | ||
218 | { | ||
219 | p4d_t *p4d; | ||
220 | unsigned long next; | ||
221 | unsigned long pages = 0; | ||
222 | |||
223 | p4d = p4d_offset(pgd, addr); | ||
224 | do { | ||
225 | next = p4d_addr_end(addr, end); | ||
226 | if (p4d_none_or_clear_bad(p4d)) | ||
227 | continue; | ||
228 | pages += change_pud_range(vma, p4d, addr, next, newprot, | ||
229 | dirty_accountable, prot_numa); | ||
230 | } while (p4d++, addr = next, addr != end); | ||
231 | |||
232 | return pages; | ||
233 | } | ||
234 | |||
215 | static unsigned long change_protection_range(struct vm_area_struct *vma, | 235 | static unsigned long change_protection_range(struct vm_area_struct *vma, |
216 | unsigned long addr, unsigned long end, pgprot_t newprot, | 236 | unsigned long addr, unsigned long end, pgprot_t newprot, |
217 | int dirty_accountable, int prot_numa) | 237 | int dirty_accountable, int prot_numa) |
@@ -230,7 +250,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma, | |||
230 | next = pgd_addr_end(addr, end); | 250 | next = pgd_addr_end(addr, end); |
231 | if (pgd_none_or_clear_bad(pgd)) | 251 | if (pgd_none_or_clear_bad(pgd)) |
232 | continue; | 252 | continue; |
233 | pages += change_pud_range(vma, pgd, addr, next, newprot, | 253 | pages += change_p4d_range(vma, pgd, addr, next, newprot, |
234 | dirty_accountable, prot_numa); | 254 | dirty_accountable, prot_numa); |
235 | } while (pgd++, addr = next, addr != end); | 255 | } while (pgd++, addr = next, addr != end); |
236 | 256 | ||