@@ -214,6 +214,19 @@ static pte_t get_clear_contig(struct mm_struct *mm,
214
214
return orig_pte ;
215
215
}
216
216
217
+ static pte_t get_clear_contig_flush (struct mm_struct * mm ,
218
+ unsigned long addr ,
219
+ pte_t * ptep ,
220
+ unsigned long pgsize ,
221
+ unsigned long ncontig )
222
+ {
223
+ pte_t orig_pte = get_clear_contig (mm , addr , ptep , pgsize , ncontig );
224
+ struct vm_area_struct vma = TLB_FLUSH_VMA (mm , 0 );
225
+
226
+ flush_tlb_range (& vma , addr , addr + (pgsize * ncontig ));
227
+ return orig_pte ;
228
+ }
229
+
217
230
/*
218
231
* Changing some bits of contiguous entries requires us to follow a
219
232
* Break-Before-Make approach, breaking the whole contiguous set
@@ -447,19 +460,20 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
447
460
int ncontig , i ;
448
461
size_t pgsize = 0 ;
449
462
unsigned long pfn = pte_pfn (pte ), dpfn ;
463
+ struct mm_struct * mm = vma -> vm_mm ;
450
464
pgprot_t hugeprot ;
451
465
pte_t orig_pte ;
452
466
453
467
if (!pte_cont (pte ))
454
468
return ptep_set_access_flags (vma , addr , ptep , pte , dirty );
455
469
456
- ncontig = find_num_contig (vma -> vm_mm , addr , ptep , & pgsize );
470
+ ncontig = find_num_contig (mm , addr , ptep , & pgsize );
457
471
dpfn = pgsize >> PAGE_SHIFT ;
458
472
459
473
if (!__cont_access_flags_changed (ptep , pte , ncontig ))
460
474
return 0 ;
461
475
462
- orig_pte = get_clear_contig ( vma -> vm_mm , addr , ptep , pgsize , ncontig );
476
+ orig_pte = get_clear_contig_flush ( mm , addr , ptep , pgsize , ncontig );
463
477
464
478
/* Make sure we don't lose the dirty or young state */
465
479
if (pte_dirty (orig_pte ))
@@ -470,7 +484,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
470
484
471
485
hugeprot = pte_pgprot (pte );
472
486
for (i = 0 ; i < ncontig ; i ++ , ptep ++ , addr += pgsize , pfn += dpfn )
473
- set_pte_at (vma -> vm_mm , addr , ptep , pfn_pte (pfn , hugeprot ));
487
+ set_pte_at (mm , addr , ptep , pfn_pte (pfn , hugeprot ));
474
488
475
489
return 1 ;
476
490
}
@@ -492,7 +506,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
492
506
ncontig = find_num_contig (mm , addr , ptep , & pgsize );
493
507
dpfn = pgsize >> PAGE_SHIFT ;
494
508
495
- pte = get_clear_contig (mm , addr , ptep , pgsize , ncontig );
509
+ pte = get_clear_contig_flush (mm , addr , ptep , pgsize , ncontig );
496
510
pte = pte_wrprotect (pte );
497
511
498
512
hugeprot = pte_pgprot (pte );
@@ -505,17 +519,15 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
505
519
pte_t huge_ptep_clear_flush (struct vm_area_struct * vma ,
506
520
unsigned long addr , pte_t * ptep )
507
521
{
522
+ struct mm_struct * mm = vma -> vm_mm ;
508
523
size_t pgsize ;
509
524
int ncontig ;
510
- pte_t orig_pte ;
511
525
512
526
if (!pte_cont (READ_ONCE (* ptep )))
513
527
return ptep_clear_flush (vma , addr , ptep );
514
528
515
- ncontig = find_num_contig (vma -> vm_mm , addr , ptep , & pgsize );
516
- orig_pte = get_clear_contig (vma -> vm_mm , addr , ptep , pgsize , ncontig );
517
- flush_tlb_range (vma , addr , addr + pgsize * ncontig );
518
- return orig_pte ;
529
+ ncontig = find_num_contig (mm , addr , ptep , & pgsize );
530
+ return get_clear_contig_flush (mm , addr , ptep , pgsize , ncontig );
519
531
}
520
532
521
533
static int __init hugetlbpage_init (void )
0 commit comments