From: Jann Horn jannh@google.com
stable inclusion from stable-v5.10.144 commit 891f03f688de8418f44b32b88f6b4faed5b2aa81 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0V7
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
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 Signed-off-by: Jialin Zhang zhangjialin11@huawei.com Reviewed-by: Zheng Zengkai zhengzengkai@huawei.com --- mm/mmap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/mm/mmap.c b/mm/mmap.c index b7a5a135f20d..94c24b6efe99 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2963,6 +2963,7 @@ static void unmap_region(struct mm_struct *mm, { struct vm_area_struct *next = vma_next(mm, prev); struct mmu_gather tlb; + struct vm_area_struct *cur_vma;
lru_add_drain(); tlb_gather_mmu(&tlb, mm, start, end); @@ -2977,8 +2978,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);