| @@ -37,12 +37,14 @@ · 36 unmodified lines |
| 37 | 37 | |
| 38 | 38 | static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, |
| 39 | 39 | unsigned long addr, unsigned long end, pgprot_t newprot, |
| 40 | | − int dirty_accountable, int prot_numa) |
| 40 | + unsigned long cp_flags) |
| 41 | 41 | { |
| 42 | 42 | pte_t *pte, oldpte; |
| 43 | 43 | spinlock_t *ptl; |
| 44 | 44 | unsigned long pages = 0; |
| 45 | 45 | int target_node = NUMA_NO_NODE; |
| 46 | + bool dirty_accountable = cp_flags & MM_CP_DIRTY_ACCT; |
| 47 | + bool prot_numa = cp_flags & MM_CP_PROT_NUMA; |
| 46 | 48 | |
| 47 | 49 | /* |
| 48 | 50 | * Can be called with only the mmap_sem for reading by |
| @@ -188,7 +190,7 @@ static inline int pmd_none_or_clear_bad_unless_trans_huge(pmd_t *pmd) · 139 unmodified lines |
| 188 | 190 | |
| 189 | 191 | static inline unsigned long change_pmd_range(struct vm_area_struct *vma, |
| 190 | 192 | pud_t *pud, unsigned long addr, unsigned long end, |
| 191 | | − pgprot_t newprot, int dirty_accountable, int prot_numa) |
| 193 | + pgprot_t newprot, unsigned long cp_flags) |
| 192 | 194 | { |
| 193 | 195 | pmd_t *pmd; |
| 194 | 196 | unsigned long next; |
| @@ -229,7 +231,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, · 34 unmodified lines |
| 229 | 231 | __split_huge_pmd(vma, pmd, addr, false, NULL); |
| 230 | 232 | } else { |
| 231 | 233 | int nr_ptes = change_huge_pmd(vma, pmd, addr, |
| 232 | | − newprot, prot_numa); |
| 234 | + newprot, cp_flags); |
| 233 | 235 | |
| 234 | 236 | if (nr_ptes) { |
| 235 | 237 | if (nr_ptes == HPAGE_PMD_NR) { |
| @@ -244,7 +246,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, · 8 unmodified lines |
| 244 | 246 | /* fall through, the trans huge pmd just split */ |
| 245 | 247 | } |
| 246 | 248 | this_pages = change_pte_range(vma, pmd, addr, next, newprot, |
| 247 | | − dirty_accountable, prot_numa); |
| 249 | + cp_flags); |
| 248 | 250 | pages += this_pages; |
| 249 | 251 | next: |
| 250 | 252 | cond_resched(); |
| @@ -260,7 +262,7 @@ next: · 9 unmodified lines |
| 260 | 262 | |
| 261 | 263 | static inline unsigned long change_pud_range(struct vm_area_struct *vma, |
| 262 | 264 | p4d_t *p4d, unsigned long addr, unsigned long end, |
| 263 | | − pgprot_t newprot, int dirty_accountable, int prot_numa) |
| 265 | + pgprot_t newprot, unsigned long cp_flags) |
| 264 | 266 | { |
| 265 | 267 | pud_t *pud; |
| 266 | 268 | unsigned long next; |
| @@ -272,7 +274,7 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma, · 5 unmodified lines |
| 272 | 274 | if (pud_none_or_clear_bad(pud)) |
| 273 | 275 | continue; |
| 274 | 276 | pages += change_pmd_range(vma, pud, addr, next, newprot, |
| 275 | | − dirty_accountable, prot_numa); |
| 277 | + cp_flags); |
| 276 | 278 | } while (pud++, addr = next, addr != end); |
| 277 | 279 | |
| 278 | 280 | return pages; |
| @@ -280,7 +282,7 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma, · 1 unmodified line |
| 280 | 282 | |
| 281 | 283 | static inline unsigned long change_p4d_range(struct vm_area_struct *vma, |
| 282 | 284 | pgd_t *pgd, unsigned long addr, unsigned long end, |
| 283 | | − pgprot_t newprot, int dirty_accountable, int prot_numa) |
| 285 | + pgprot_t newprot, unsigned long cp_flags) |
| 284 | 286 | { |
| 285 | 287 | p4d_t *p4d; |
| 286 | 288 | unsigned long next; |
| @@ -292,7 +294,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma, · 5 unmodified lines |
| 292 | 294 | if (p4d_none_or_clear_bad(p4d)) |
| 293 | 295 | continue; |
| 294 | 296 | pages += change_pud_range(vma, p4d, addr, next, newprot, |
| 295 | | − dirty_accountable, prot_numa); |
| 297 | + cp_flags); |
| 296 | 298 | } while (p4d++, addr = next, addr != end); |
| 297 | 299 | |
| 298 | 300 | return pages; |
| @@ -300,7 +302,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma, · 1 unmodified line |
| 300 | 302 | |
| 301 | 303 | static unsigned long change_protection_range(struct vm_area_struct *vma, |
| 302 | 304 | unsigned long addr, unsigned long end, pgprot_t newprot, |
| 303 | | − int dirty_accountable, int prot_numa) |
| 305 | + unsigned long cp_flags) |
| 304 | 306 | { |
| 305 | 307 | struct mm_struct *mm = vma->vm_mm; |
| 306 | 308 | pgd_t *pgd; |
| @@ -317,7 +319,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma, · 10 unmodified lines |
| 317 | 319 | if (pgd_none_or_clear_bad(pgd)) |
| 318 | 320 | continue; |
| 319 | 321 | pages += change_p4d_range(vma, pgd, addr, next, newprot, |
| 320 | | − dirty_accountable, prot_numa); |
| 322 | + cp_flags); |
| 321 | 323 | } while (pgd++, addr = next, addr != end); |
| 322 | 324 | |
| 323 | 325 | /* Only flush the TLB if we actually modified any entries: */ |
| @@ -330,14 +332,15 @@ static unsigned long change_protection_range(struct vm_area_struct *vma, · 6 unmodified lines |
| 330 | 332 | |
| 331 | 333 | unsigned long change_protection(struct vm_area_struct *vma, unsigned long start, |
| 332 | 334 | unsigned long end, pgprot_t newprot, |
| 333 | | − int dirty_accountable, int prot_numa) |
| 335 | + unsigned long cp_flags) |
| 334 | 336 | { |
| 335 | 337 | unsigned long pages; |
| 336 | 338 | |
| 337 | 339 | if (is_vm_hugetlb_page(vma)) |
| 338 | 340 | pages = hugetlb_change_protection(vma, start, end, newprot); |
| 339 | 341 | else |
| 340 | | − pages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa); |
| 342 | + pages = change_protection_range(vma, start, end, newprot, |
| 343 | + cp_flags); |
| 341 | 344 | |
| 342 | 345 | return pages; |
| 343 | 346 | } |
| @@ -459,7 +462,7 @@ success: · 115 unmodified lines |
| 459 | 462 | vma_set_page_prot(vma); |
| 460 | 463 | |
| 461 | 464 | change_protection(vma, start, end, vma->vm_page_prot, |
| 462 | | − dirty_accountable, 0); |
| 465 | + dirty_accountable ? MM_CP_DIRTY_ACCT : 0); |
| 463 | 466 | |
| 464 | 467 | /* |
| 465 | 468 | * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major |