diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 35b92d8..16019a3 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -15,8 +15,10 @@ #include #include #include +#include #include +#include #include #include #include "internal.h" @@ -999,6 +1001,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, struct mm_struct *mm; struct vm_area_struct *vma; enum clear_refs_types type; + struct mmu_gather tlb; int itype; int rv; @@ -1045,6 +1048,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, } down_read(&mm->mmap_sem); + tlb_gather_mmu(&tlb, mm, 0, -1); if (type == CLEAR_REFS_SOFT_DIRTY) { for (vma = mm->mmap; vma; vma = vma->vm_next) { if (!(vma->vm_flags & VM_SOFTDIRTY)) @@ -1066,7 +1070,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, walk_page_range(0, mm->highest_vm_end, &clear_refs_walk); if (type == CLEAR_REFS_SOFT_DIRTY) mmu_notifier_invalidate_range_end(mm, 0, -1); - flush_tlb_mm(mm); + tlb_finish_mmu(&tlb, 0, -1); up_read(&mm->mmap_sem); out_mm: mmput(mm); diff --git a/mm/uksm.c b/mm/uksm.c index 40f947c..fa87161 100644 --- a/mm/uksm.c +++ b/mm/uksm.c @@ -1505,7 +1505,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, if (old_pte) *old_pte = *ptep; - if (pte_write(*ptep) || pte_dirty(*ptep)) { + if (pte_write(*ptep) || pte_dirty(*ptep) || mm_tlb_flush_pending(mm)) { pte_t entry; swapped = PageSwapCache(page);