[ Sasha's backport helper bot ] Hi, Summary of potential issues: ⚠️ Found matching upstream commit but patch is missing proper reference to it Found matching upstream commit: 02410ac72ac3707936c07ede66e94360d0d65319 Note: The patch differs from the upstream commit: --- 1: 02410ac72ac37 ! 1: db66591c2390e mm: hugetlb: Add huge page size param to huge_ptep_get_and_clear() @@ Commit message Acked-by: Alexander Gordeev <agordeev@xxxxxxxxxxxxx> # s390 Link: https://lore.kernel.org/r/20250226120656.2400136-2-ryan.roberts@xxxxxxx Signed-off-by: Will Deacon <will@xxxxxxxxxx> + (cherry picked from commit 02410ac72ac3707936c07ede66e94360d0d65319) + Signed-off-by: Ryan Roberts <ryan.roberts@xxxxxxx> ## arch/arm64/include/asm/hugetlb.h ## @@ arch/arm64/include/asm/hugetlb.h: extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, @@ arch/arm64/include/asm/hugetlb.h: extern int huge_ptep_set_access_flags(struct v ## arch/arm64/mm/hugetlbpage.c ## @@ arch/arm64/mm/hugetlbpage.c: void huge_pte_clear(struct mm_struct *mm, unsigned long addr, - __pte_clear(mm, addr, ptep); + pte_clear(mm, addr, ptep); } -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, @@ arch/arm64/mm/hugetlbpage.c: bool __init arch_hugetlb_valid_size(unsigned long s { + unsigned long psize = huge_page_size(hstate_vma(vma)); + - if (alternative_has_cap_unlikely(ARM64_WORKAROUND_2645198)) { + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2645198) && + cpus_have_const_cap(ARM64_WORKAROUND_2645198)) { /* - * Break-before-make (BBM) is required for all user space mappings @@ arch/arm64/mm/hugetlbpage.c: pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr - if (pte_user_exec(__ptep_get(ptep))) + if (pte_user_exec(READ_ONCE(*ptep))) return huge_ptep_clear_flush(vma, addr, ptep); } - return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); @@ arch/loongarch/include/asm/hugetlb.h: static inline void huge_pte_clear(struct m + unsigned long sz) { pte_t clear; - pte_t pte = ptep_get(ptep); + pte_t pte = *ptep; @@ arch/loongarch/include/asm/hugetlb.h: static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { @@ arch/parisc/include/asm/hugetlb.h: void set_huge_pte_at(struct mm_struct *mm, un - pte_t *ptep); + pte_t *ptep, unsigned long sz); - #define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH - static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, + /* + * If the arch doesn't supply something else, assume that hugepage ## arch/parisc/mm/hugetlbpage.c ## @@ arch/parisc/mm/hugetlbpage.c: void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, @@ arch/parisc/mm/hugetlbpage.c: void set_huge_pte_at(struct mm_struct *mm, unsigne ## arch/powerpc/include/asm/hugetlb.h ## -@@ arch/powerpc/include/asm/hugetlb.h: void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, +@@ arch/powerpc/include/asm/hugetlb.h: void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, @@ arch/riscv/mm/hugetlbpage.c: int huge_ptep_set_access_flags(struct vm_area_struc int pte_num; ## arch/s390/include/asm/hugetlb.h ## -@@ arch/s390/include/asm/hugetlb.h: 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); - +@@ arch/s390/include/asm/hugetlb.h: void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte); + pte_t huge_ptep_get(pte_t *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); + - #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) @@ arch/s390/include/asm/hugetlb.h: void __set_huge_pte_at(struct mm_struct *mm, un + return __huge_ptep_get_and_clear(mm, addr, ptep); +} - static inline void arch_clear_hugetlb_flags(struct folio *folio) - { + /* + * If the arch doesn't supply something else, assume that hugepage @@ arch/s390/include/asm/hugetlb.h: 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) @@ arch/s390/include/asm/hugetlb.h: static inline void huge_pte_clear(struct mm_str + return __huge_ptep_get_and_clear(vma->vm_mm, address, ptep); } - #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS + static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, @@ arch/s390/include/asm/hugetlb.h: 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); - + { + int changed = !pte_same(huge_ptep_get(ptep), pte); if (changed) { - huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); + __huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); @@ arch/s390/include/asm/hugetlb.h: static inline int huge_ptep_set_access_flags(st { - 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)); } + ## arch/s390/mm/hugetlbpage.c ## -@@ arch/s390/mm/hugetlbpage.c: pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +@@ arch/s390/mm/hugetlbpage.c: pte_t huge_ptep_get(pte_t *ptep) return __rste_to_pte(pte_val(*ptep)); } @@ arch/s390/mm/hugetlbpage.c: pte_t huge_ptep_get(struct mm_struct *mm, unsigned l +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); + pte_t pte = huge_ptep_get(ptep); pmd_t *pmdp = (pmd_t *) ptep; ## arch/sparc/include/asm/hugetlb.h ## @@ mm/hugetlb.c: static void move_huge_pte(struct vm_area_struct *vma, unsigned lon - pte = huge_ptep_get_and_clear(mm, old_addr, src_pte); + pte = huge_ptep_get_and_clear(mm, old_addr, src_pte, sz); + set_huge_pte_at(mm, new_addr, dst_pte, pte, sz); - if (need_clear_uffd_wp && pte_marker_uffd_wp(pte)) - huge_pte_clear(mm, new_addr, dst_pte, sz); + if (src_ptl != dst_ptl) @@ mm/hugetlb.c: void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED); } --- Results of testing on various branches: | Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.6.y | Success | Success |