]> git.itanic.dy.fi Git - linux-stable/commitdiff
mm: Fix TLB flush for not-first PFNMAP mappings in unmap_region()
authorJann Horn <jannh@google.com>
Thu, 15 Sep 2022 14:25:19 +0000 (16:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Sep 2022 09:51:30 +0000 (11:51 +0200)
This is a stable-specific patch.
I botched the stable-specific rewrite of
commit b67fbebd4cf98 ("mmu_gather: Force tlb-flush VM_PFNMAP vmas"):
As Hugh pointed out, unmap_region() actually operates on a list of VMAs,
and the variable "vma" merely points to the first VMA in that list.
So if we want to check whether any of the VMAs we're operating on is
PFNMAP or MIXEDMAP, we have to iterate through the list and check each VMA.

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mm/mmap.c

index 17caf44807dee2f82771d2c73d18e0c5c9541810..e230e08d47b8bd6d173d8428cc95f9e0b45c83bc 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2524,6 +2524,7 @@ static void unmap_region(struct mm_struct *mm,
 {
        struct vm_area_struct *next = prev ? prev->vm_next : mm->mmap;
        struct mmu_gather tlb;
+       struct vm_area_struct *cur_vma;
 
        lru_add_drain();
        tlb_gather_mmu(&tlb, mm, start, end);
@@ -2538,8 +2539,12 @@ static void unmap_region(struct mm_struct *mm,
         * concurrent flush in this region has to be coming through the rmap,
         * and we synchronize against that using the rmap lock.
         */
-       if ((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) != 0)
-               tlb_flush_mmu(&tlb);
+       for (cur_vma = vma; cur_vma; cur_vma = cur_vma->vm_next) {
+               if ((cur_vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) != 0) {
+                       tlb_flush_mmu(&tlb);
+                       break;
+               }
+       }
 
        free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
                                 next ? next->vm_start : USER_PGTABLES_CEILING);