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