All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp
@ 2021-02-18 23:06 Peter Xu
  2021-02-18 23:06 ` [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share() Peter Xu
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Peter Xu @ 2021-02-18 23:06 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Andrew Morton, Matthew Wilcox, Axel Rasmussen,
	Kirill A . Shutemov, Mike Rapoport, Mike Kravetz,
	Andrea Arcangeli, peterx

v4:
- fix build for sparc by removing extra line in patch 1 [Mike]
- pick Mike's r-b for patch 4

v3:
- patch 4:
  - fix build failure for !CMA and/or !HUGETLBFS [Axel]
  - Fix mmu notifier range to use start/end [Mike]
- add more r-bs

v2:
- patch 4: move hugetlb_unshare_all_pmds() into mm/hugetlb.c, so it can be used
  even outside userfaultfd.c

This series tries to disable huge pmd unshare of hugetlbfs backed memory for
uffd-wp.  Although uffd-wp of hugetlbfs is still during rfc stage, the idea of
this series may be needed for multiple tasks (Axel's uffd minor fault series,
and Mike's soft dirty series), so I picked it out from the larger series.

References works:

Uffd shmem+hugetlbfs rfc:
https://lore.kernel.org/lkml/20210115170907.24498-1-peterx@redhat.com/

Uffd minor mode for hugetlbfs:
https://lore.kernel.org/lkml/20210212215403.3457686-1-axelrasmussen@google.com/

Soft dirty for hugetlbfs:
https://lore.kernel.org/lkml/20210211000322.159437-1-mike.kravetz@oracle.com/

Please review, thanks.

Peter Xu (4):
  hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share()
  hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
  mm/hugetlb: Move flush_hugetlb_tlb_range() into hugetlb.h
  hugetlb/userfaultfd: Unshare all pmds for hugetlbfs when register wp

 arch/arm64/mm/hugetlbpage.c   |  7 ++-
 arch/ia64/mm/hugetlbpage.c    |  3 +-
 arch/mips/mm/hugetlbpage.c    |  4 +-
 arch/parisc/mm/hugetlbpage.c  |  2 +-
 arch/powerpc/mm/hugetlbpage.c |  3 +-
 arch/s390/mm/hugetlbpage.c    |  2 +-
 arch/sh/mm/hugetlbpage.c      |  2 +-
 arch/sparc/mm/hugetlbpage.c   |  2 +-
 fs/userfaultfd.c              |  4 ++
 include/linux/hugetlb.h       | 18 ++++++-
 include/linux/userfaultfd_k.h |  9 ++++
 mm/hugetlb.c                  | 94 +++++++++++++++++++++++++++--------
 mm/userfaultfd.c              |  2 +-
 13 files changed, 116 insertions(+), 36 deletions(-)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share()
  2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
@ 2021-02-18 23:06 ` Peter Xu
  2021-03-04 16:31   ` kernel test robot
  2021-02-18 23:12 ` [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled Peter Xu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Peter Xu @ 2021-02-18 23:06 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Andrew Morton, Matthew Wilcox, Axel Rasmussen,
	Kirill A . Shutemov, Mike Rapoport, Mike Kravetz,
	Andrea Arcangeli, peterx

It is a preparation work to be able to behave differently in the per
architecture huge_pte_alloc() according to different VMA attributes.

Pass it deeper into huge_pmd_share() so that we can avoid the find_vma() call.

Suggested-by: Mike Kravetz <mike.kravetz@oracle.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 arch/arm64/mm/hugetlbpage.c   |  4 ++--
 arch/ia64/mm/hugetlbpage.c    |  3 ++-
 arch/mips/mm/hugetlbpage.c    |  4 ++--
 arch/parisc/mm/hugetlbpage.c  |  2 +-
 arch/powerpc/mm/hugetlbpage.c |  3 ++-
 arch/s390/mm/hugetlbpage.c    |  2 +-
 arch/sh/mm/hugetlbpage.c      |  2 +-
 arch/sparc/mm/hugetlbpage.c   |  2 +-
 include/linux/hugetlb.h       |  5 +++--
 mm/hugetlb.c                  | 15 ++++++++-------
 mm/userfaultfd.c              |  2 +-
 11 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 55ecf6de9ff7..6e3bcffe2837 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -252,7 +252,7 @@ void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
 		set_pte(ptep, pte);
 }
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 		      unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgdp;
@@ -286,7 +286,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
 	} else if (sz == PMD_SIZE) {
 		if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
 		    pud_none(READ_ONCE(*pudp)))
-			ptep = huge_pmd_share(mm, addr, pudp);
+			ptep = huge_pmd_share(mm, vma, addr, pudp);
 		else
 			ptep = (pte_t *)pmd_alloc(mm, pudp, addr);
 	} else if (sz == (CONT_PMD_SIZE)) {
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index b331f94d20ac..f993cb36c062 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -25,7 +25,8 @@ unsigned int hpage_shift = HPAGE_SHIFT_DEFAULT;
 EXPORT_SYMBOL(hpage_shift);
 
 pte_t *
-huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
+huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+	       unsigned long addr, unsigned long sz)
 {
 	unsigned long taddr = htlbpage_to_page(addr);
 	pgd_t *pgd;
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c
index b9f76f433617..7eaff5b07873 100644
--- a/arch/mips/mm/hugetlbpage.c
+++ b/arch/mips/mm/hugetlbpage.c
@@ -21,8 +21,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
-pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr,
-		      unsigned long sz)
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+		      unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
 	p4d_t *p4d;
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index d7ba014a7fbb..e141441bfa64 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -44,7 +44,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 }
 
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8b3cc4d688e8..d57276b8791c 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -106,7 +106,8 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
  * At this point we do the placement change only for BOOK3S 64. This would
  * possibly work on other subarchs.
  */
-pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+		      unsigned long addr, unsigned long sz)
 {
 	pgd_t *pg;
 	p4d_t *p4;
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index 3b5a4d25ca9b..da36d13ffc16 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -189,7 +189,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
 	return pte;
 }
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgdp;
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 220d7bc43d2b..999ab5916e69 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -21,7 +21,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index ad4b42f04988..04d8790f6c32 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -279,7 +279,7 @@ unsigned long pud_leaf_size(pud_t pud) { return 1UL << tte_to_shift(*(pte_t *)&p
 unsigned long pmd_leaf_size(pmd_t pmd) { return 1UL << tte_to_shift(*(pte_t *)&pmd); }
 unsigned long pte_leaf_size(pte_t pte) { return 1UL << tte_to_shift(pte); }
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index b5807f23caf8..a6113fa6d21d 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -152,7 +152,8 @@ void hugetlb_fix_reserve_counts(struct inode *inode);
 extern struct mutex *hugetlb_fault_mutex_table;
 u32 hugetlb_fault_mutex_hash(struct address_space *mapping, pgoff_t idx);
 
-pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud);
+pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+		      unsigned long addr, pud_t *pud);
 
 struct address_space *hugetlb_page_mapping_lock_write(struct page *hpage);
 
@@ -161,7 +162,7 @@ extern struct list_head huge_boot_pages;
 
 /* arch callbacks */
 
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz);
 pte_t *huge_pte_offset(struct mm_struct *mm,
 		       unsigned long addr, unsigned long sz);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4bdb58ab14cb..07bb9bdc3282 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3807,7 +3807,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 		src_pte = huge_pte_offset(src, addr, sz);
 		if (!src_pte)
 			continue;
-		dst_pte = huge_pte_alloc(dst, addr, sz);
+		dst_pte = huge_pte_alloc(dst, vma, addr, sz);
 		if (!dst_pte) {
 			ret = -ENOMEM;
 			break;
@@ -4544,7 +4544,7 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	 */
 	mapping = vma->vm_file->f_mapping;
 	i_mmap_lock_read(mapping);
-	ptep = huge_pte_alloc(mm, haddr, huge_page_size(h));
+	ptep = huge_pte_alloc(mm, vma, haddr, huge_page_size(h));
 	if (!ptep) {
 		i_mmap_unlock_read(mapping);
 		return VM_FAULT_OOM;
@@ -5334,9 +5334,9 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
  * if !vma_shareable check at the beginning of the routine. i_mmap_rwsem is
  * only required for subsequent processing.
  */
-pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+		      unsigned long addr, pud_t *pud)
 {
-	struct vm_area_struct *vma = find_vma(mm, addr);
 	struct address_space *mapping = vma->vm_file->f_mapping;
 	pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
 			vma->vm_pgoff;
@@ -5414,7 +5414,8 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
 }
 #define want_pmd_share()	(1)
 #else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
-pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
+		      unsigned long addr, pud_t *pud)
 {
 	return NULL;
 }
@@ -5433,7 +5434,7 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
 #endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
 
 #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB
-pte_t *huge_pte_alloc(struct mm_struct *mm,
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
@@ -5452,7 +5453,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
 		} else {
 			BUG_ON(sz != PMD_SIZE);
 			if (want_pmd_share() && pud_none(*pud))
-				pte = huge_pmd_share(mm, addr, pud);
+				pte = huge_pmd_share(mm, vma, addr, pud);
 			else
 				pte = (pte_t *)pmd_alloc(mm, pud, addr);
 		}
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 9a3d451402d7..063cbb17e8d8 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -290,7 +290,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm,
 		mutex_lock(&hugetlb_fault_mutex_table[hash]);
 
 		err = -ENOMEM;
-		dst_pte = huge_pte_alloc(dst_mm, dst_addr, vma_hpagesize);
+		dst_pte = huge_pte_alloc(dst_mm, dst_vma, dst_addr, vma_hpagesize);
 		if (!dst_pte) {
 			mutex_unlock(&hugetlb_fault_mutex_table[hash]);
 			i_mmap_unlock_read(mapping);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
  2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
  2021-02-18 23:06 ` [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share() Peter Xu
@ 2021-02-18 23:12 ` Peter Xu
  2021-03-10  7:48     ` Naresh Kamboju
  2021-02-18 23:12 ` [PATCH v4 3/4] mm/hugetlb: Move flush_hugetlb_tlb_range() into hugetlb.h Peter Xu
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Peter Xu @ 2021-02-18 23:12 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: peterx, Andrea Arcangeli, Axel Rasmussen, Mike Rapoport,
	Kirill A . Shutemov, Andrew Morton, Matthew Wilcox, Mike Kravetz

Huge pmd sharing could bring problem to userfaultfd.  The thing is that
userfaultfd is running its logic based on the special bits on page table
entries, however the huge pmd sharing could potentially share page table
entries for different address ranges.  That could cause issues on either:

  - When sharing huge pmd page tables for an uffd write protected range, the
    newly mapped huge pmd range will also be write protected unexpectedly, or,

  - When we try to write protect a range of huge pmd shared range, we'll first
    do huge_pmd_unshare() in hugetlb_change_protection(), however that also
    means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
    region, which could lead to data loss.

Since at it, a few other things are done altogether:

  - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
    that's definitely something that arch code would like to use too

  - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
    trying to share huge pmd.  Switch to the want_pmd_share() helper.

Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().

Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 arch/arm64/mm/hugetlbpage.c   |  3 +--
 include/linux/hugetlb.h       |  2 ++
 include/linux/userfaultfd_k.h |  9 +++++++++
 mm/hugetlb.c                  | 20 ++++++++++++++------
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 6e3bcffe2837..58987a98e179 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 		 */
 		ptep = pte_alloc_map(mm, pmdp, addr);
 	} else if (sz == PMD_SIZE) {
-		if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
-		    pud_none(READ_ONCE(*pudp)))
+		if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))
 			ptep = huge_pmd_share(mm, vma, addr, pudp);
 		else
 			ptep = (pte_t *)pmd_alloc(mm, pudp, addr);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index a6113fa6d21d..bc86f2f516e7 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -950,4 +950,6 @@ static inline __init void hugetlb_cma_check(void)
 }
 #endif
 
+bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr);
+
 #endif /* _LINUX_HUGETLB_H */
diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index a8e5f3ea9bb2..c63ccdae3eab 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -52,6 +52,15 @@ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
 	return vma->vm_userfaultfd_ctx.ctx == vm_ctx.ctx;
 }
 
+/*
+ * Never enable huge pmd sharing on uffd-wp registered vmas, because uffd-wp
+ * protect information is per pgtable entry.
+ */
+static inline bool uffd_disable_huge_pmd_share(struct vm_area_struct *vma)
+{
+	return vma->vm_flags & VM_UFFD_WP;
+}
+
 static inline bool userfaultfd_missing(struct vm_area_struct *vma)
 {
 	return vma->vm_flags & VM_UFFD_MISSING;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 07bb9bdc3282..8e8e2f3dfe06 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5292,6 +5292,18 @@ static bool vma_shareable(struct vm_area_struct *vma, unsigned long addr)
 	return false;
 }
 
+bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr)
+{
+#ifndef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
+	return false;
+#endif
+#ifdef CONFIG_USERFAULTFD
+	if (uffd_disable_huge_pmd_share(vma))
+		return false;
+#endif
+	return vma_shareable(vma, addr);
+}
+
 /*
  * Determine if start,end range within vma could be mapped by shared pmd.
  * If yes, adjust start and end to cover range associated with possible
@@ -5346,9 +5358,6 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
 	pte_t *pte;
 	spinlock_t *ptl;
 
-	if (!vma_shareable(vma, addr))
-		return (pte_t *)pmd_alloc(mm, pud, addr);
-
 	i_mmap_assert_locked(mapping);
 	vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) {
 		if (svma == vma)
@@ -5412,7 +5421,7 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
 	*addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE;
 	return 1;
 }
-#define want_pmd_share()	(1)
+
 #else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
 pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
 		      unsigned long addr, pud_t *pud)
@@ -5430,7 +5439,6 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
 				unsigned long *start, unsigned long *end)
 {
 }
-#define want_pmd_share()	(0)
 #endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
 
 #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB
@@ -5452,7 +5460,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			pte = (pte_t *)pud;
 		} else {
 			BUG_ON(sz != PMD_SIZE);
-			if (want_pmd_share() && pud_none(*pud))
+			if (want_pmd_share(vma, addr) && pud_none(*pud))
 				pte = huge_pmd_share(mm, vma, addr, pud);
 			else
 				pte = (pte_t *)pmd_alloc(mm, pud, addr);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 3/4] mm/hugetlb: Move flush_hugetlb_tlb_range() into hugetlb.h
  2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
  2021-02-18 23:06 ` [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share() Peter Xu
  2021-02-18 23:12 ` [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled Peter Xu
@ 2021-02-18 23:12 ` Peter Xu
  2021-02-18 23:12 ` [PATCH v4 4/4] hugetlb/userfaultfd: Unshare all pmds for hugetlbfs when register wp Peter Xu
  2021-03-01 14:20 ` [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
  4 siblings, 0 replies; 13+ messages in thread
From: Peter Xu @ 2021-02-18 23:12 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: peterx, Andrea Arcangeli, Axel Rasmussen, Mike Rapoport,
	Kirill A . Shutemov, Andrew Morton, Matthew Wilcox, Mike Kravetz

Prepare for it to be called outside of mm/hugetlb.c.

Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/linux/hugetlb.h | 8 ++++++++
 mm/hugetlb.c            | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index bc86f2f516e7..3b4104021dd3 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -952,4 +952,12 @@ static inline __init void hugetlb_cma_check(void)
 
 bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr);
 
+#ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
+/*
+ * ARCHes with special requirements for evicting HUGETLB backing TLB entries can
+ * implement this.
+ */
+#define flush_hugetlb_tlb_range(vma, addr, end)	flush_tlb_range(vma, addr, end)
+#endif
+
 #endif /* _LINUX_HUGETLB_H */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 8e8e2f3dfe06..f53a0b852ed8 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4965,14 +4965,6 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
 	return i ? i : err;
 }
 
-#ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
-/*
- * ARCHes with special requirements for evicting HUGETLB backing TLB entries can
- * implement this.
- */
-#define flush_hugetlb_tlb_range(vma, addr, end)	flush_tlb_range(vma, addr, end)
-#endif
-
 unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 		unsigned long address, unsigned long end, pgprot_t newprot)
 {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 4/4] hugetlb/userfaultfd: Unshare all pmds for hugetlbfs when register wp
  2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
                   ` (2 preceding siblings ...)
  2021-02-18 23:12 ` [PATCH v4 3/4] mm/hugetlb: Move flush_hugetlb_tlb_range() into hugetlb.h Peter Xu
@ 2021-02-18 23:12 ` Peter Xu
  2021-03-01 14:20 ` [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
  4 siblings, 0 replies; 13+ messages in thread
From: Peter Xu @ 2021-02-18 23:12 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: peterx, Andrea Arcangeli, Axel Rasmussen, Mike Rapoport,
	Kirill A . Shutemov, Andrew Morton, Matthew Wilcox, Mike Kravetz

Huge pmd sharing for hugetlbfs is racy with userfaultfd-wp because
userfaultfd-wp is always based on pgtable entries, so they cannot be shared.

Walk the hugetlb range and unshare all such mappings if there is, right before
UFFDIO_REGISTER will succeed and return to userspace.

This will pair with want_pmd_share() in hugetlb code so that huge pmd sharing
is completely disabled for userfaultfd-wp registered range.

Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 fs/userfaultfd.c        |  4 ++++
 include/linux/hugetlb.h |  3 +++
 mm/hugetlb.c            | 51 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 894cc28142e7..e259318fcae1 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -15,6 +15,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/mm.h>
 #include <linux/mm.h>
+#include <linux/mmu_notifier.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/seq_file.h>
@@ -1448,6 +1449,9 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 		vma->vm_flags = new_flags;
 		vma->vm_userfaultfd_ctx.ctx = ctx;
 
+		if (is_vm_hugetlb_page(vma) && uffd_disable_huge_pmd_share(vma))
+			hugetlb_unshare_all_pmds(vma);
+
 	skip:
 		prev = vma;
 		start = vma->vm_end;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 3b4104021dd3..6437483ad01b 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -188,6 +188,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 		unsigned long address, unsigned long end, pgprot_t newprot);
 
 bool is_hugetlb_entry_migration(pte_t pte);
+void hugetlb_unshare_all_pmds(struct vm_area_struct *vma);
 
 #else /* !CONFIG_HUGETLB_PAGE */
 
@@ -369,6 +370,8 @@ static inline vm_fault_t hugetlb_fault(struct mm_struct *mm,
 	return 0;
 }
 
+static inline void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) { }
+
 #endif /* !CONFIG_HUGETLB_PAGE */
 /*
  * hugepages at page global directory. If arch support
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f53a0b852ed8..fc62932c31cb 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5653,6 +5653,57 @@ void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason)
 	}
 }
 
+/*
+ * This function will unconditionally remove all the shared pmd pgtable entries
+ * within the specific vma for a hugetlbfs memory range.
+ */
+void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
+{
+	struct hstate *h = hstate_vma(vma);
+	unsigned long sz = huge_page_size(h);
+	struct mm_struct *mm = vma->vm_mm;
+	struct mmu_notifier_range range;
+	unsigned long address, start, end;
+	spinlock_t *ptl;
+	pte_t *ptep;
+
+	if (!(vma->vm_flags & VM_MAYSHARE))
+		return;
+
+	start = ALIGN(vma->vm_start, PUD_SIZE);
+	end = ALIGN_DOWN(vma->vm_end, PUD_SIZE);
+
+	if (start >= end)
+		return;
+
+	/*
+	 * No need to call adjust_range_if_pmd_sharing_possible(), because
+	 * we have already done the PUD_SIZE alignment.
+	 */
+	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm,
+				start, end);
+	mmu_notifier_invalidate_range_start(&range);
+	i_mmap_lock_write(vma->vm_file->f_mapping);
+	for (address = start; address < end; address += PUD_SIZE) {
+		unsigned long tmp = address;
+
+		ptep = huge_pte_offset(mm, address, sz);
+		if (!ptep)
+			continue;
+		ptl = huge_pte_lock(h, mm, ptep);
+		/* We don't want 'address' to be changed */
+		huge_pmd_unshare(mm, vma, &tmp, ptep);
+		spin_unlock(ptl);
+	}
+	flush_hugetlb_tlb_range(vma, start, end);
+	i_mmap_unlock_write(vma->vm_file->f_mapping);
+	/*
+	 * No need to call mmu_notifier_invalidate_range(), see
+	 * Documentation/vm/mmu_notifier.rst.
+	 */
+	mmu_notifier_invalidate_range_end(&range);
+}
+
 #ifdef CONFIG_CMA
 static bool cma_reserve_called __initdata;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp
  2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
                   ` (3 preceding siblings ...)
  2021-02-18 23:12 ` [PATCH v4 4/4] hugetlb/userfaultfd: Unshare all pmds for hugetlbfs when register wp Peter Xu
@ 2021-03-01 14:20 ` Peter Xu
  4 siblings, 0 replies; 13+ messages in thread
From: Peter Xu @ 2021-03-01 14:20 UTC (permalink / raw)
  To: linux-kernel, linux-mm, Mike Kravetz, Andrew Morton
  Cc: Andrew Morton, Matthew Wilcox, Axel Rasmussen,
	Kirill A . Shutemov, Mike Rapoport, Mike Kravetz,
	Andrea Arcangeli

On Thu, Feb 18, 2021 at 06:06:29PM -0500, Peter Xu wrote:
> v4:
> - fix build for sparc by removing extra line in patch 1 [Mike]
> - pick Mike's r-b for patch 4
> 
> v3:
> - patch 4:
>   - fix build failure for !CMA and/or !HUGETLBFS [Axel]
>   - Fix mmu notifier range to use start/end [Mike]
> - add more r-bs
> 
> v2:
> - patch 4: move hugetlb_unshare_all_pmds() into mm/hugetlb.c, so it can be used
>   even outside userfaultfd.c
> 
> This series tries to disable huge pmd unshare of hugetlbfs backed memory for
> uffd-wp.  Although uffd-wp of hugetlbfs is still during rfc stage, the idea of
> this series may be needed for multiple tasks (Axel's uffd minor fault series,
> and Mike's soft dirty series), so I picked it out from the larger series.
> 
> References works:
> 
> Uffd shmem+hugetlbfs rfc:
> https://lore.kernel.org/lkml/20210115170907.24498-1-peterx@redhat.com/
> 
> Uffd minor mode for hugetlbfs:
> https://lore.kernel.org/lkml/20210212215403.3457686-1-axelrasmussen@google.com/
> 
> Soft dirty for hugetlbfs:
> https://lore.kernel.org/lkml/20210211000322.159437-1-mike.kravetz@oracle.com/

Andrew/Mike,

Do you have any further comment on this series?

Thanks,

-- 
Peter Xu


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share()
  2021-02-18 23:06 ` [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share() Peter Xu
@ 2021-03-04 16:31   ` kernel test robot
  2021-03-04 16:46     ` Peter Xu
  0 siblings, 1 reply; 13+ messages in thread
From: kernel test robot @ 2021-03-04 16:31 UTC (permalink / raw)
  To: Peter Xu, linux-kernel, linux-mm
  Cc: Andrew Morton, Linux Memory Management List, Matthew Wilcox,
	Axel Rasmussen, Kirill A . Shutemov, Mike Rapoport, Mike Kravetz,
	Andrea Arcangeli

[-- Attachment #1: Type: text/plain, Size: 3581 bytes --]

Hi Peter,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on linux/master linus/master v5.12-rc1 next-20210304]
[cannot apply to hnaz-linux-mm/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Peter-Xu/hugetlb-Disable-huge-pmd-unshare-for-uffd-wp/20210219-071334
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: mips-randconfig-m031-20210304 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/7ede06d6f63e59db4b9dee54f78eeac0c9ca17e4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Peter-Xu/hugetlb-Disable-huge-pmd-unshare-for-uffd-wp/20210219-071334
        git checkout 7ede06d6f63e59db4b9dee54f78eeac0c9ca17e4
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> mm/hugetlb.c:5376:8: error: conflicting types for 'huge_pmd_share'
    5376 | pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
         |        ^~~~~~~~~~~~~~
   In file included from mm/hugetlb.c:39:
   include/linux/hugetlb.h:155:8: note: previous declaration of 'huge_pmd_share' was here
     155 | pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
         |        ^~~~~~~~~~~~~~


vim +/huge_pmd_share +5376 mm/hugetlb.c

  5343	
  5344	/*
  5345	 * unmap huge page backed by shared pte.
  5346	 *
  5347	 * Hugetlb pte page is ref counted at the time of mapping.  If pte is shared
  5348	 * indicated by page_count > 1, unmap is achieved by clearing pud and
  5349	 * decrementing the ref count. If count == 1, the pte page is not shared.
  5350	 *
  5351	 * Called with page table lock held and i_mmap_rwsem held in write mode.
  5352	 *
  5353	 * returns: 1 successfully unmapped a shared pte page
  5354	 *	    0 the underlying pte page is not shared, or it is the last user
  5355	 */
  5356	int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
  5357						unsigned long *addr, pte_t *ptep)
  5358	{
  5359		pgd_t *pgd = pgd_offset(mm, *addr);
  5360		p4d_t *p4d = p4d_offset(pgd, *addr);
  5361		pud_t *pud = pud_offset(p4d, *addr);
  5362	
  5363		i_mmap_assert_write_locked(vma->vm_file->f_mapping);
  5364		BUG_ON(page_count(virt_to_page(ptep)) == 0);
  5365		if (page_count(virt_to_page(ptep)) == 1)
  5366			return 0;
  5367	
  5368		pud_clear(pud);
  5369		put_page(virt_to_page(ptep));
  5370		mm_dec_nr_pmds(mm);
  5371		*addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE;
  5372		return 1;
  5373	}
  5374	#define want_pmd_share()	(1)
  5375	#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
> 5376	pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
  5377			      unsigned long addr, pud_t *pud)
  5378	{
  5379		return NULL;
  5380	}
  5381	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29604 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share()
  2021-03-04 16:31   ` kernel test robot
@ 2021-03-04 16:46     ` Peter Xu
  0 siblings, 0 replies; 13+ messages in thread
From: Peter Xu @ 2021-03-04 16:46 UTC (permalink / raw)
  To: kernel test robot, Andrew Morton
  Cc: linux-kernel, linux-mm, Andrew Morton, Matthew Wilcox,
	Axel Rasmussen, Kirill A . Shutemov, Mike Rapoport, Mike Kravetz,
	Andrea Arcangeli

On Fri, Mar 05, 2021 at 12:31:00AM +0800, kernel test robot wrote:
> Hi Peter,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on arm64/for-next/core]
> [also build test ERROR on linux/master linus/master v5.12-rc1 next-20210304]
> [cannot apply to hnaz-linux-mm/master]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/0day-ci/linux/commits/Peter-Xu/hugetlb-Disable-huge-pmd-unshare-for-uffd-wp/20210219-071334
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
> config: mips-randconfig-m031-20210304 (attached as .config)
> compiler: mipsel-linux-gcc (GCC) 9.3.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/0day-ci/linux/commit/7ede06d6f63e59db4b9dee54f78eeac0c9ca17e4
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Peter-Xu/hugetlb-Disable-huge-pmd-unshare-for-uffd-wp/20210219-071334
>         git checkout 7ede06d6f63e59db4b9dee54f78eeac0c9ca17e4
>         # save the attached .config to linux build tree
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
> >> mm/hugetlb.c:5376:8: error: conflicting types for 'huge_pmd_share'
>     5376 | pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
>          |        ^~~~~~~~~~~~~~
>    In file included from mm/hugetlb.c:39:
>    include/linux/hugetlb.h:155:8: note: previous declaration of 'huge_pmd_share' was here
>      155 | pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
>          |        ^~~~~~~~~~~~~~
> 
> 
> vim +/huge_pmd_share +5376 mm/hugetlb.c
> 
>   5343	
>   5344	/*
>   5345	 * unmap huge page backed by shared pte.
>   5346	 *
>   5347	 * Hugetlb pte page is ref counted at the time of mapping.  If pte is shared
>   5348	 * indicated by page_count > 1, unmap is achieved by clearing pud and
>   5349	 * decrementing the ref count. If count == 1, the pte page is not shared.
>   5350	 *
>   5351	 * Called with page table lock held and i_mmap_rwsem held in write mode.
>   5352	 *
>   5353	 * returns: 1 successfully unmapped a shared pte page
>   5354	 *	    0 the underlying pte page is not shared, or it is the last user
>   5355	 */
>   5356	int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
>   5357						unsigned long *addr, pte_t *ptep)
>   5358	{
>   5359		pgd_t *pgd = pgd_offset(mm, *addr);
>   5360		p4d_t *p4d = p4d_offset(pgd, *addr);
>   5361		pud_t *pud = pud_offset(p4d, *addr);
>   5362	
>   5363		i_mmap_assert_write_locked(vma->vm_file->f_mapping);
>   5364		BUG_ON(page_count(virt_to_page(ptep)) == 0);
>   5365		if (page_count(virt_to_page(ptep)) == 1)
>   5366			return 0;
>   5367	
>   5368		pud_clear(pud);
>   5369		put_page(virt_to_page(ptep));
>   5370		mm_dec_nr_pmds(mm);
>   5371		*addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE;
>   5372		return 1;
>   5373	}
>   5374	#define want_pmd_share()	(1)
>   5375	#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
> > 5376	pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
>   5377			      unsigned long addr, pud_t *pud)
>   5378	{
>   5379		return NULL;
>   5380	}
>   5381	

Sorry for this!  I think we need to squash below into this patch for
!CONFIG_ARCH_WANT_HUGE_PMD_SHARE:

-----8<-----
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index fc62932c31cb..94ac419f88cd 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5415,7 +5415,7 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
 }
 
 #else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
-pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct vma,
+pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
                      unsigned long addr, pud_t *pud)
 {
        return NULL;
-----8<-----

Andrew, please kindly let me know when a repost is needed.

Thanks,

-- 
Peter Xu


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
  2021-02-18 23:12 ` [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled Peter Xu
@ 2021-03-10  7:48     ` Naresh Kamboju
  0 siblings, 0 replies; 13+ messages in thread
From: Naresh Kamboju @ 2021-03-10  7:48 UTC (permalink / raw)
  To: Peter Xu, Linux-Next Mailing List
  Cc: open list, linux-mm, Andrea Arcangeli, Axel Rasmussen,
	Mike Rapoport, Kirill A . Shutemov, Andrew Morton,
	Matthew Wilcox, Mike Kravetz, lkft-triage, Arnd Bergmann,
	Stephen Rothwell

Hi Peter,

On Fri, 19 Feb 2021 at 04:43, Peter Xu <peterx@redhat.com> wrote:
>
> Huge pmd sharing could bring problem to userfaultfd.  The thing is that
> userfaultfd is running its logic based on the special bits on page table
> entries, however the huge pmd sharing could potentially share page table
> entries for different address ranges.  That could cause issues on either:
>
>   - When sharing huge pmd page tables for an uffd write protected range, the
>     newly mapped huge pmd range will also be write protected unexpectedly, or,
>
>   - When we try to write protect a range of huge pmd shared range, we'll first
>     do huge_pmd_unshare() in hugetlb_change_protection(), however that also
>     means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
>     region, which could lead to data loss.
>
> Since at it, a few other things are done altogether:
>
>   - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
>     that's definitely something that arch code would like to use too
>
>   - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
>     trying to share huge pmd.  Switch to the want_pmd_share() helper.
>
> Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().
>
> Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
> Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  arch/arm64/mm/hugetlbpage.c   |  3 +--
>  include/linux/hugetlb.h       |  2 ++
>  include/linux/userfaultfd_k.h |  9 +++++++++
>  mm/hugetlb.c                  | 20 ++++++++++++++------
>  4 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 6e3bcffe2837..58987a98e179 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
>                  */
>                 ptep = pte_alloc_map(mm, pmdp, addr);
>         } else if (sz == PMD_SIZE) {
> -               if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
> -                   pud_none(READ_ONCE(*pudp)))
> +               if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))

While building Linux next 20210310 tag for arm64 architecture with

  - CONFIG_ARM64_64K_PAGES=y

enabled the build failed due to below errors / warnings

make --silent --keep-going --jobs=8
O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
'HOSTCC=sccache gcc'
aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
aarch64-linux-gnu-ld: arch/arm64/mm/hugetlbpage.o: in function `huge_pte_alloc':
hugetlbpage.c:(.text+0x7d8): undefined reference to `want_pmd_share'

Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>

Steps to reproduce:
----------------------------
# TuxMake is a command line tool and Python library that provides
# portable and repeatable Linux kernel builds across a variety of
# architectures, toolchains, kernel configurations, and make targets.
#
# TuxMake supports the concept of runtimes.
# See https://docs.tuxmake.org/runtimes/, for that to work it requires
# that you install podman or docker on your system.
#
# To install tuxmake on your system globally:
# sudo pip3 install -U tuxmake
#
# See https://docs.tuxmake.org/ for complete documentation.


tuxmake --runtime podman --target-arch arm64 --toolchain gcc-9
--kconfig defconfig --kconfig-add
https://builds.tuxbuild.com/1pYCSoc1oGtPWlPgLAJxbHx07kL/config

Build link,
https://builds.tuxbuild.com/1pYCSoc1oGtPWlPgLAJxbHx07kL/


-- 
Linaro LKFT
https://lkft.linaro.org

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
@ 2021-03-10  7:48     ` Naresh Kamboju
  0 siblings, 0 replies; 13+ messages in thread
From: Naresh Kamboju @ 2021-03-10  7:48 UTC (permalink / raw)
  To: Peter Xu, Linux-Next Mailing List
  Cc: open list, linux-mm, Andrea Arcangeli, Axel Rasmussen,
	Mike Rapoport, Kirill A . Shutemov, Andrew Morton,
	Matthew Wilcox, Mike Kravetz, lkft-triage, Arnd Bergmann,
	Stephen Rothwell

Hi Peter,

On Fri, 19 Feb 2021 at 04:43, Peter Xu <peterx@redhat.com> wrote:
>
> Huge pmd sharing could bring problem to userfaultfd.  The thing is that
> userfaultfd is running its logic based on the special bits on page table
> entries, however the huge pmd sharing could potentially share page table
> entries for different address ranges.  That could cause issues on either:
>
>   - When sharing huge pmd page tables for an uffd write protected range, the
>     newly mapped huge pmd range will also be write protected unexpectedly, or,
>
>   - When we try to write protect a range of huge pmd shared range, we'll first
>     do huge_pmd_unshare() in hugetlb_change_protection(), however that also
>     means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
>     region, which could lead to data loss.
>
> Since at it, a few other things are done altogether:
>
>   - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
>     that's definitely something that arch code would like to use too
>
>   - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
>     trying to share huge pmd.  Switch to the want_pmd_share() helper.
>
> Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().
>
> Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
> Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  arch/arm64/mm/hugetlbpage.c   |  3 +--
>  include/linux/hugetlb.h       |  2 ++
>  include/linux/userfaultfd_k.h |  9 +++++++++
>  mm/hugetlb.c                  | 20 ++++++++++++++------
>  4 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 6e3bcffe2837..58987a98e179 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
>                  */
>                 ptep = pte_alloc_map(mm, pmdp, addr);
>         } else if (sz == PMD_SIZE) {
> -               if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
> -                   pud_none(READ_ONCE(*pudp)))
> +               if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))

While building Linux next 20210310 tag for arm64 architecture with

  - CONFIG_ARM64_64K_PAGES=y

enabled the build failed due to below errors / warnings

make --silent --keep-going --jobs=8
O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
'HOSTCC=sccache gcc'
aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
aarch64-linux-gnu-ld: arch/arm64/mm/hugetlbpage.o: in function `huge_pte_alloc':
hugetlbpage.c:(.text+0x7d8): undefined reference to `want_pmd_share'

Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>

Steps to reproduce:
----------------------------
# TuxMake is a command line tool and Python library that provides
# portable and repeatable Linux kernel builds across a variety of
# architectures, toolchains, kernel configurations, and make targets.
#
# TuxMake supports the concept of runtimes.
# See https://docs.tuxmake.org/runtimes/, for that to work it requires
# that you install podman or docker on your system.
#
# To install tuxmake on your system globally:
# sudo pip3 install -U tuxmake
#
# See https://docs.tuxmake.org/ for complete documentation.


tuxmake --runtime podman --target-arch arm64 --toolchain gcc-9
--kconfig defconfig --kconfig-add
https://builds.tuxbuild.com/1pYCSoc1oGtPWlPgLAJxbHx07kL/config

Build link,
https://builds.tuxbuild.com/1pYCSoc1oGtPWlPgLAJxbHx07kL/


-- 
Linaro LKFT
https://lkft.linaro.org


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
  2021-03-10  7:48     ` Naresh Kamboju
  (?)
@ 2021-03-10 16:57     ` Peter Xu
  2021-03-10 18:09         ` Naresh Kamboju
  -1 siblings, 1 reply; 13+ messages in thread
From: Peter Xu @ 2021-03-10 16:57 UTC (permalink / raw)
  To: Naresh Kamboju
  Cc: Linux-Next Mailing List, open list, linux-mm, Andrea Arcangeli,
	Axel Rasmussen, Mike Rapoport, Kirill A . Shutemov,
	Andrew Morton, Matthew Wilcox, Mike Kravetz, lkft-triage,
	Arnd Bergmann, Stephen Rothwell

[-- Attachment #1: Type: text/plain, Size: 3289 bytes --]

On Wed, Mar 10, 2021 at 01:18:42PM +0530, Naresh Kamboju wrote:
> Hi Peter,

Hi, Naresh,

> 
> On Fri, 19 Feb 2021 at 04:43, Peter Xu <peterx@redhat.com> wrote:
> >
> > Huge pmd sharing could bring problem to userfaultfd.  The thing is that
> > userfaultfd is running its logic based on the special bits on page table
> > entries, however the huge pmd sharing could potentially share page table
> > entries for different address ranges.  That could cause issues on either:
> >
> >   - When sharing huge pmd page tables for an uffd write protected range, the
> >     newly mapped huge pmd range will also be write protected unexpectedly, or,
> >
> >   - When we try to write protect a range of huge pmd shared range, we'll first
> >     do huge_pmd_unshare() in hugetlb_change_protection(), however that also
> >     means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
> >     region, which could lead to data loss.
> >
> > Since at it, a few other things are done altogether:
> >
> >   - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
> >     that's definitely something that arch code would like to use too
> >
> >   - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
> >     trying to share huge pmd.  Switch to the want_pmd_share() helper.
> >
> > Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().
> >
> > Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
> > Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  arch/arm64/mm/hugetlbpage.c   |  3 +--
> >  include/linux/hugetlb.h       |  2 ++
> >  include/linux/userfaultfd_k.h |  9 +++++++++
> >  mm/hugetlb.c                  | 20 ++++++++++++++------
> >  4 files changed, 26 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> > index 6e3bcffe2837..58987a98e179 100644
> > --- a/arch/arm64/mm/hugetlbpage.c
> > +++ b/arch/arm64/mm/hugetlbpage.c
> > @@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
> >                  */
> >                 ptep = pte_alloc_map(mm, pmdp, addr);
> >         } else if (sz == PMD_SIZE) {
> > -               if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
> > -                   pud_none(READ_ONCE(*pudp)))
> > +               if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))
> 
> While building Linux next 20210310 tag for arm64 architecture with
> 
>   - CONFIG_ARM64_64K_PAGES=y
> 
> enabled the build failed due to below errors / warnings
> 
> make --silent --keep-going --jobs=8
> O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm64
> CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
> 'HOSTCC=sccache gcc'
> aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
> aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
> aarch64-linux-gnu-ld: arch/arm64/mm/hugetlbpage.o: in function `huge_pte_alloc':
> hugetlbpage.c:(.text+0x7d8): undefined reference to `want_pmd_share'
> 
> Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>

Sorry for the issue & thanks for the report.  Would you please check whether
the patch attached could fix the issue?

-- 
Peter Xu

[-- Attachment #2: 0001-mm-hugetlb-Fix-build-with-ARCH_WANT_HUGE_PMD_SHARE.patch --]
[-- Type: text/plain, Size: 1671 bytes --]

From 4072042b415d1f78ac1ab017671e345b414ca6ab Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Wed, 10 Mar 2021 11:48:56 -0500
Subject: [PATCH] mm/hugetlb: Fix build with !ARCH_WANT_HUGE_PMD_SHARE

want_pmd_share() is undefined with !ARCH_WANT_HUGE_PMD_SHARE since it's put
by accident into a "#ifdef ARCH_WANT_HUGE_PMD_SHARE" block.  Moving it out
won't work either since vma_shareable() is only defined within the block.
Define it for !ARCH_WANT_HUGE_PMD_SHARE instead.

Fixes: 5b109cc1cdcc ("hugetlb/userfaultfd: forbid huge pmd sharing when uffd enabled")
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 mm/hugetlb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index d58f1456fe27..8dda7e034477 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5469,9 +5469,6 @@ static bool vma_shareable(struct vm_area_struct *vma, unsigned long addr)
 
 bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr)
 {
-#ifndef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
-	return false;
-#endif
 #ifdef CONFIG_USERFAULTFD
 	if (uffd_disable_huge_pmd_share(vma))
 		return false;
@@ -5616,6 +5613,11 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
 				unsigned long *start, unsigned long *end)
 {
 }
+
+bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr)
+{
+	return false;
+}
 #endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
 
 #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
  2021-03-10 16:57     ` Peter Xu
@ 2021-03-10 18:09         ` Naresh Kamboju
  0 siblings, 0 replies; 13+ messages in thread
From: Naresh Kamboju @ 2021-03-10 18:09 UTC (permalink / raw)
  To: Peter Xu
  Cc: Linux-Next Mailing List, open list, linux-mm, Andrea Arcangeli,
	Axel Rasmussen, Mike Rapoport, Kirill A . Shutemov,
	Andrew Morton, Matthew Wilcox, Mike Kravetz, lkft-triage,
	Arnd Bergmann, Stephen Rothwell

On Wed, 10 Mar 2021 at 22:27, Peter Xu <peterx@redhat.com> wrote:
>
> On Wed, Mar 10, 2021 at 01:18:42PM +0530, Naresh Kamboju wrote:
> > Hi Peter,
>
> Hi, Naresh,
>
> >
> > On Fri, 19 Feb 2021 at 04:43, Peter Xu <peterx@redhat.com> wrote:
> > >
> > > Huge pmd sharing could bring problem to userfaultfd.  The thing is that
> > > userfaultfd is running its logic based on the special bits on page table
> > > entries, however the huge pmd sharing could potentially share page table
> > > entries for different address ranges.  That could cause issues on either:
> > >
> > >   - When sharing huge pmd page tables for an uffd write protected range, the
> > >     newly mapped huge pmd range will also be write protected unexpectedly, or,
> > >
> > >   - When we try to write protect a range of huge pmd shared range, we'll first
> > >     do huge_pmd_unshare() in hugetlb_change_protection(), however that also
> > >     means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
> > >     region, which could lead to data loss.
> > >
> > > Since at it, a few other things are done altogether:
> > >
> > >   - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
> > >     that's definitely something that arch code would like to use too
> > >
> > >   - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
> > >     trying to share huge pmd.  Switch to the want_pmd_share() helper.
> > >
> > > Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().
> > >
> > > Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
> > > Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
> > > Signed-off-by: Peter Xu <peterx@redhat.com>
> > > ---
> > >  arch/arm64/mm/hugetlbpage.c   |  3 +--
> > >  include/linux/hugetlb.h       |  2 ++
> > >  include/linux/userfaultfd_k.h |  9 +++++++++
> > >  mm/hugetlb.c                  | 20 ++++++++++++++------
> > >  4 files changed, 26 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> > > index 6e3bcffe2837..58987a98e179 100644
> > > --- a/arch/arm64/mm/hugetlbpage.c
> > > +++ b/arch/arm64/mm/hugetlbpage.c
> > > @@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
> > >                  */
> > >                 ptep = pte_alloc_map(mm, pmdp, addr);
> > >         } else if (sz == PMD_SIZE) {
> > > -               if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
> > > -                   pud_none(READ_ONCE(*pudp)))
> > > +               if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))
> >
> > While building Linux next 20210310 tag for arm64 architecture with
> >
> >   - CONFIG_ARM64_64K_PAGES=y
> >
> > enabled the build failed due to below errors / warnings
> >
> > make --silent --keep-going --jobs=8
> > O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm64
> > CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
> > 'HOSTCC=sccache gcc'
> > aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
> > aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
> > aarch64-linux-gnu-ld: arch/arm64/mm/hugetlbpage.o: in function `huge_pte_alloc':
> > hugetlbpage.c:(.text+0x7d8): undefined reference to `want_pmd_share'
> >
> > Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
>
> Sorry for the issue & thanks for the report.  Would you please check whether
> the patch attached could fix the issue?

The attached patch build tested and build pass for arm64
including 64k pages config.

 CONFIG_ARM64_64K_PAGES=y

- Naresh

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled
@ 2021-03-10 18:09         ` Naresh Kamboju
  0 siblings, 0 replies; 13+ messages in thread
From: Naresh Kamboju @ 2021-03-10 18:09 UTC (permalink / raw)
  To: Peter Xu
  Cc: Linux-Next Mailing List, open list, linux-mm, Andrea Arcangeli,
	Axel Rasmussen, Mike Rapoport, Kirill A . Shutemov,
	Andrew Morton, Matthew Wilcox, Mike Kravetz, lkft-triage,
	Arnd Bergmann, Stephen Rothwell

On Wed, 10 Mar 2021 at 22:27, Peter Xu <peterx@redhat.com> wrote:
>
> On Wed, Mar 10, 2021 at 01:18:42PM +0530, Naresh Kamboju wrote:
> > Hi Peter,
>
> Hi, Naresh,
>
> >
> > On Fri, 19 Feb 2021 at 04:43, Peter Xu <peterx@redhat.com> wrote:
> > >
> > > Huge pmd sharing could bring problem to userfaultfd.  The thing is that
> > > userfaultfd is running its logic based on the special bits on page table
> > > entries, however the huge pmd sharing could potentially share page table
> > > entries for different address ranges.  That could cause issues on either:
> > >
> > >   - When sharing huge pmd page tables for an uffd write protected range, the
> > >     newly mapped huge pmd range will also be write protected unexpectedly, or,
> > >
> > >   - When we try to write protect a range of huge pmd shared range, we'll first
> > >     do huge_pmd_unshare() in hugetlb_change_protection(), however that also
> > >     means the UFFDIO_WRITEPROTECT could be silently skipped for the shared
> > >     region, which could lead to data loss.
> > >
> > > Since at it, a few other things are done altogether:
> > >
> > >   - Move want_pmd_share() from mm/hugetlb.c into linux/hugetlb.h, because
> > >     that's definitely something that arch code would like to use too
> > >
> > >   - ARM64 currently directly check against CONFIG_ARCH_WANT_HUGE_PMD_SHARE when
> > >     trying to share huge pmd.  Switch to the want_pmd_share() helper.
> > >
> > > Since at it, move vma_shareable() from huge_pmd_share() into want_pmd_share().
> > >
> > > Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
> > > Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
> > > Signed-off-by: Peter Xu <peterx@redhat.com>
> > > ---
> > >  arch/arm64/mm/hugetlbpage.c   |  3 +--
> > >  include/linux/hugetlb.h       |  2 ++
> > >  include/linux/userfaultfd_k.h |  9 +++++++++
> > >  mm/hugetlb.c                  | 20 ++++++++++++++------
> > >  4 files changed, 26 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> > > index 6e3bcffe2837..58987a98e179 100644
> > > --- a/arch/arm64/mm/hugetlbpage.c
> > > +++ b/arch/arm64/mm/hugetlbpage.c
> > > @@ -284,8 +284,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
> > >                  */
> > >                 ptep = pte_alloc_map(mm, pmdp, addr);
> > >         } else if (sz == PMD_SIZE) {
> > > -               if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
> > > -                   pud_none(READ_ONCE(*pudp)))
> > > +               if (want_pmd_share(vma, addr) && pud_none(READ_ONCE(*pudp)))
> >
> > While building Linux next 20210310 tag for arm64 architecture with
> >
> >   - CONFIG_ARM64_64K_PAGES=y
> >
> > enabled the build failed due to below errors / warnings
> >
> > make --silent --keep-going --jobs=8
> > O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm64
> > CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
> > 'HOSTCC=sccache gcc'
> > aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
> > aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
> > aarch64-linux-gnu-ld: arch/arm64/mm/hugetlbpage.o: in function `huge_pte_alloc':
> > hugetlbpage.c:(.text+0x7d8): undefined reference to `want_pmd_share'
> >
> > Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
>
> Sorry for the issue & thanks for the report.  Would you please check whether
> the patch attached could fix the issue?

The attached patch build tested and build pass for arm64
including 64k pages config.

 CONFIG_ARM64_64K_PAGES=y

- Naresh


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-03-10 18:10 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-18 23:06 [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu
2021-02-18 23:06 ` [PATCH v4 1/4] hugetlb: Pass vma into huge_pte_alloc() and huge_pmd_share() Peter Xu
2021-03-04 16:31   ` kernel test robot
2021-03-04 16:46     ` Peter Xu
2021-02-18 23:12 ` [PATCH v4 2/4] hugetlb/userfaultfd: Forbid huge pmd sharing when uffd enabled Peter Xu
2021-03-10  7:48   ` Naresh Kamboju
2021-03-10  7:48     ` Naresh Kamboju
2021-03-10 16:57     ` Peter Xu
2021-03-10 18:09       ` Naresh Kamboju
2021-03-10 18:09         ` Naresh Kamboju
2021-02-18 23:12 ` [PATCH v4 3/4] mm/hugetlb: Move flush_hugetlb_tlb_range() into hugetlb.h Peter Xu
2021-02-18 23:12 ` [PATCH v4 4/4] hugetlb/userfaultfd: Unshare all pmds for hugetlbfs when register wp Peter Xu
2021-03-01 14:20 ` [PATCH v4 0/4] hugetlb: Disable huge pmd unshare for uffd-wp Peter Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.