On Wed, Feb 26, 2025 at 12:06:51PM +0000, Ryan Roberts wrote: > In order to fix a bug, arm64 needs to be told the size of the huge page > for which the huge_pte is being cleared in huge_ptep_get_and_clear(). > Provide for this by adding an `unsigned long sz` parameter to the > function. This follows the same pattern as huge_pte_clear() and > set_huge_pte_at(). > > This commit makes the required interface modifications to the core mm as > well as all arches that implement this function (arm64, loongarch, mips, > parisc, powerpc, riscv, s390, sparc). The actual arm64 bug will be fixed > in a separate commit. > > Cc: stable@xxxxxxxxxxxxxxx > Fixes: 66b3923a1a0f ("arm64: hugetlb: add support for PTE contiguous bit") > Acked-by: David Hildenbrand <david@xxxxxxxxxx> > Reviewed-by: Alexandre Ghiti <alexghiti@xxxxxxxxxxxx> # riscv > Reviewed-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx> > Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx> > Reviewed-by: Anshuman Khandual <anshuman.khandual@xxxxxxx> > Signed-off-by: Ryan Roberts <ryan.roberts@xxxxxxx> > --- > arch/arm64/include/asm/hugetlb.h | 4 ++-- > arch/arm64/mm/hugetlbpage.c | 8 +++++--- > arch/loongarch/include/asm/hugetlb.h | 6 ++++-- > arch/mips/include/asm/hugetlb.h | 6 ++++-- > arch/parisc/include/asm/hugetlb.h | 2 +- > arch/parisc/mm/hugetlbpage.c | 2 +- > arch/powerpc/include/asm/hugetlb.h | 6 ++++-- > arch/riscv/include/asm/hugetlb.h | 3 ++- > arch/riscv/mm/hugetlbpage.c | 2 +- > arch/s390/include/asm/hugetlb.h | 16 ++++++++++++---- > arch/s390/mm/hugetlbpage.c | 4 ++-- > arch/sparc/include/asm/hugetlb.h | 2 +- > arch/sparc/mm/hugetlbpage.c | 2 +- > include/asm-generic/hugetlb.h | 2 +- > include/linux/hugetlb.h | 4 +++- > mm/hugetlb.c | 4 ++-- > 16 files changed, 46 insertions(+), 27 deletions(-) ... > diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h > index 7c52acaf9f82..663e87220e89 100644 > --- a/arch/s390/include/asm/hugetlb.h > +++ b/arch/s390/include/asm/hugetlb.h > @@ -25,8 +25,16 @@ void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, > #define __HAVE_ARCH_HUGE_PTEP_GET > pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep); > > +pte_t __huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, > + pte_t *ptep); > + > #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR > -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); > +static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, > + unsigned long addr, pte_t *ptep, > + unsigned long sz) > +{ > + return __huge_ptep_get_and_clear(mm, addr, ptep); > +} > > static inline void arch_clear_hugetlb_flags(struct folio *folio) > { > @@ -48,7 +56,7 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, > static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, > unsigned long address, pte_t *ptep) > { > - return huge_ptep_get_and_clear(vma->vm_mm, address, ptep); > + return __huge_ptep_get_and_clear(vma->vm_mm, address, ptep); > } > > #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS > @@ -59,7 +67,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, > int changed = !pte_same(huge_ptep_get(vma->vm_mm, addr, ptep), pte); > > if (changed) { > - huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); > + __huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); > __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); > } > return changed; > @@ -69,7 +77,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, > static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, > unsigned long addr, pte_t *ptep) > { > - pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); > + pte_t pte = __huge_ptep_get_and_clear(mm, addr, ptep); > > __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); > } > diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c > index d9ce199953de..2e568f175cd4 100644 > --- a/arch/s390/mm/hugetlbpage.c > +++ b/arch/s390/mm/hugetlbpage.c > @@ -188,8 +188,8 @@ pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) > return __rste_to_pte(pte_val(*ptep)); > } > > -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, > - unsigned long addr, pte_t *ptep) > +pte_t __huge_ptep_get_and_clear(struct mm_struct *mm, > + unsigned long addr, pte_t *ptep) > { > pte_t pte = huge_ptep_get(mm, addr, ptep); > pmd_t *pmdp = (pmd_t *) ptep; ... Acked-by: Alexander Gordeev <agordeev@xxxxxxxxxxxxx> # s390 Thanks!