From: Greg Kroah-Hartman Date: Thu, 25 Nov 2021 10:26:19 +0000 (+0100) Subject: new version of queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch X-Git-Tag: v5.10.82~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7c3e83d7f45568e66f6ec248628beeff6b2551d5;p=thirdparty%2Fkernel%2Fstable-queue.git new version of queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch --- diff --git a/queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch b/queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch index 957b42f330b..ebefca1708c 100644 --- a/queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch +++ b/queue-4.19/hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch @@ -33,25 +33,134 @@ Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- - include/asm-generic/tlb.h | 6 ++++++ - mm/hugetlb.c | 23 +++++++++++++++++++---- - 2 files changed, 25 insertions(+), 4 deletions(-) + arch/arm/include/asm/tlb.h | 8 ++++++++ + arch/ia64/include/asm/tlb.h | 10 ++++++++++ + arch/s390/include/asm/tlb.h | 16 ++++++++++++++++ + arch/sh/include/asm/tlb.h | 9 +++++++++ + arch/um/include/asm/tlb.h | 12 ++++++++++++ + include/asm-generic/tlb.h | 2 ++ + mm/hugetlb.c | 23 +++++++++++++++++++---- + mm/memory.c | 10 ++++++++++ + 8 files changed, 86 insertions(+), 4 deletions(-) ---- a/include/asm-generic/tlb.h -+++ b/include/asm-generic/tlb.h -@@ -205,6 +205,12 @@ static inline void tlb_remove_check_page - #define tlb_end_vma __tlb_end_vma - #endif +--- a/arch/arm/include/asm/tlb.h ++++ b/arch/arm/include/asm/tlb.h +@@ -280,6 +280,14 @@ tlb_remove_pmd_tlb_entry(struct mmu_gath + tlb_add_flush(tlb, addr); + } + ++static inline void ++tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size) ++{ ++ tlb_add_flush(tlb, address); ++ tlb_add_flush(tlb, address + size - PMD_SIZE); ++} ++ + #define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) + #define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) + #define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp) +--- a/arch/ia64/include/asm/tlb.h ++++ b/arch/ia64/include/asm/tlb.h +@@ -268,6 +268,16 @@ __tlb_remove_tlb_entry (struct mmu_gathe + tlb->end_addr = address + PAGE_SIZE; + } + ++static inline void ++tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size) ++{ ++ if (tlb->start_addr > address) ++ tlb->start_addr = address; ++ if (tlb->end_addr < address + size) ++ tlb->end_addr = address + size; ++} ++ + #define tlb_migrate_finish(mm) platform_tlb_migrate_finish(mm) + + #define tlb_start_vma(tlb, vma) do { } while (0) +--- a/arch/s390/include/asm/tlb.h ++++ b/arch/s390/include/asm/tlb.h +@@ -116,6 +116,20 @@ static inline void tlb_remove_page_size( + return tlb_remove_page(tlb, page); + } +static inline void tlb_flush_pmd_range(struct mmu_gather *tlb, + unsigned long address, unsigned long size) +{ -+ __tlb_adjust_range(tlb, address, size); ++ /* ++ * the range might exceed the original range that was provided to ++ * tlb_gather_mmu(), so we need to update it despite the fact it is ++ * usually not updated. ++ */ ++ if (tlb->start > address) ++ tlb->start = address; ++ if (tlb->end < address + size) ++ tlb->end = address + size; ++} ++ + /* + * pte_free_tlb frees a pte table and clears the CRSTE for the + * page table from the tlb. +@@ -177,6 +191,8 @@ static inline void pud_free_tlb(struct m + #define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0) + #define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr) do { } while (0) + #define tlb_migrate_finish(mm) do { } while (0) ++#define tlb_flush_pmd_range(tlb, addr, sz) do { } while (0) ++ + #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \ + tlb_remove_tlb_entry(tlb, ptep, address) + +--- a/arch/sh/include/asm/tlb.h ++++ b/arch/sh/include/asm/tlb.h +@@ -127,6 +127,15 @@ static inline void tlb_remove_page_size( + return tlb_remove_page(tlb, page); + } + ++static inline tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size) ++{ ++ if (tlb->start > address) ++ tlb->start = address; ++ if (tlb->end < address + size) ++ tlb->end = address + size; ++} ++ + #define tlb_remove_check_page_size_change tlb_remove_check_page_size_change + static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb, + unsigned int page_size) +--- a/arch/um/include/asm/tlb.h ++++ b/arch/um/include/asm/tlb.h +@@ -130,6 +130,18 @@ static inline void tlb_remove_page_size( + return tlb_remove_page(tlb, page); + } + ++static inline void ++tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size) ++{ ++ tlb->need_flush = 1; ++ ++ if (tlb->start > address) ++ tlb->start = address; ++ if (tlb->end < address + size) ++ tlb->end = address + size; +} + - #ifndef __tlb_remove_tlb_entry - #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) - #endif + /** + * tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation. + * +--- a/include/asm-generic/tlb.h ++++ b/include/asm-generic/tlb.h +@@ -118,6 +118,8 @@ void arch_tlb_gather_mmu(struct mmu_gath + void tlb_flush_mmu(struct mmu_gather *tlb); + void arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force); ++void tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size); + extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, + int page_size); + --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3425,6 +3425,7 @@ void __unmap_hugepage_range(struct mmu_g @@ -98,3 +207,22 @@ Signed-off-by: Greg Kroah-Hartman } void __unmap_hugepage_range_final(struct mmu_gather *tlb, +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -324,6 +324,16 @@ bool __tlb_remove_page_size(struct mmu_g + return false; + } + ++void tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address, ++ unsigned long size) ++{ ++ if (tlb->page_size != 0 && tlb->page_size != PMD_SIZE) ++ tlb_flush_mmu(tlb); ++ ++ tlb->page_size = PMD_SIZE; ++ tlb->start = min(tlb->start, address); ++ tlb->end = max(tlb->end, address + size); ++} + #endif /* HAVE_GENERIC_MMU_GATHER */ + + #ifdef CONFIG_HAVE_RCU_TABLE_FREE