linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
@ 2023-09-21 16:19 Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 1/8] parisc: hugetlb: Convert set_huge_pte_at() to take vma Ryan Roberts
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:19 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

Hi All,

This series fixes a bug in arm64's implementation of set_huge_pte_at(), which
can result in an unprivileged user causing a kernel panic. The problem was
triggered when running the new uffd poison mm selftest for HUGETLB memory. This
test (and the uffd poison feature) was merged for v6.6-rc1. However, upon
inspection there are multiple other pre-existing paths that can trigger this
bug.

Ideally, I'd like to get this fix in for v6.6 if possible? And I guess it should
be backported too, given there are call sites where this can theoretically
happen that pre-date v6.6-rc1 (I've cc'ed stable@vger.kernel.org).


Description of Bug
------------------

arm64's huge pte implementation supports multiple huge page sizes, some of which
are implemented in the page table with contiguous mappings. So set_huge_pte_at()
needs to work out how big the logical pte is, so that it can also work out how
many physical ptes (or pmds) need to be written. It does this by grabbing the
folio out of the pte and querying its size.

However, there are cases when the pte being set is actually a swap entry. But
this also used to work fine, because for huge ptes, we only ever saw migration
entries and hwpoison entries. And both of these types of swap entries have a PFN
embedded, so the code would grab that and everything still worked out.

But over time, more calls to set_huge_pte_at() have been added that set swap
entry types that do not embed a PFN. And this causes the code to go bang. The
triggering case is for the uffd poison test, commit 99aa77215ad0 ("selftests/mm:
add uffd unit test for UFFDIO_POISON"), which sets a PTE_MARKER_POISONED swap
entry. But review shows there are other places too (PTE_MARKER_UFFD_WP).

If CONFIG_DEBUG_VM is enabled, we do at least get a BUG(), but otherwise, it
will dereference a bad pointer in page_folio():

    static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
    {
        VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));

        return page_folio(pfn_to_page(swp_offset_pfn(entry)));
    }

So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
set_huge_swap_pte_at()"), which aimed to simplify the interface to the core code
by removing set_huge_swap_pte_at() (which took a page size parameter) and
replacing it with calls to set_huge_swap_pte_at() where the size was inferred
from the folio, as descibed above. While that commit didn't break anything at
the time, it did break the interface because it couldn't handle swap entries
without PFNs. And since then new callers have come along which rely on this
working.


Fix
---

The simplest fix would have been to revert the dodgy cleanup commit, but since
things have moved on, this would have required an audit of all the new
set_huge_pte_at() call sites to see if they should be converted to
set_huge_swap_pte_at(). As per the original intent of the change, it would also
leave us open to future bugs when people invariably get it wrong and call the
wrong helper.

So instead, I've converted the first parameter of set_huge_pte_at() to be a vma
rather than an mm. This means that the arm64 code can easily recover the huge
page size in all cases. It's a bigger change, due to needing to touch the arches
that implement the function, but it is entirely mechanical, so in my view, low
risk.

I've compile-tested all touched arches; arm64, parisc, powerpc, riscv, s390 (and
additionally x86_64). I've additionally booted and run mm selftests against
arm64, where I observe the uffd poison test is fixed, and there are no other
regressions.


Patches
-------

patches 1-7: Convert core mm and arches to pass vma instead of mm
patch: 8: Fixes the arm64 bug

Patches based on v6.6-rc2.


Thanks,
Ryan


Ryan Roberts (8):
  parisc: hugetlb: Convert set_huge_pte_at() to take vma
  powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  riscv: hugetlb: Convert set_huge_pte_at() to take vma
  s390: hugetlb: Convert set_huge_pte_at() to take vma
  sparc: hugetlb: Convert set_huge_pte_at() to take vma
  mm: hugetlb: Convert set_huge_pte_at() to take vma
  arm64: hugetlb: Convert set_huge_pte_at() to take vma
  arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries

 arch/arm64/include/asm/hugetlb.h              |  2 +-
 arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
 arch/parisc/include/asm/hugetlb.h             |  2 +-
 arch/parisc/mm/hugetlbpage.c                  |  4 +--
 .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
 arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
 arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
 arch/powerpc/mm/nohash/8xx.c                  |  2 +-
 arch/powerpc/mm/pgtable.c                     |  7 ++++-
 arch/riscv/include/asm/hugetlb.h              |  2 +-
 arch/riscv/mm/hugetlbpage.c                   |  3 +-
 arch/s390/include/asm/hugetlb.h               |  8 +++--
 arch/s390/mm/hugetlbpage.c                    |  8 ++++-
 arch/sparc/include/asm/hugetlb.h              |  8 +++--
 arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
 include/asm-generic/hugetlb.h                 |  6 ++--
 include/linux/hugetlb.h                       |  6 ++--
 mm/damon/vaddr.c                              |  2 +-
 mm/hugetlb.c                                  | 30 +++++++++----------
 mm/migrate.c                                  |  2 +-
 mm/rmap.c                                     | 10 +++----
 mm/vmalloc.c                                  |  5 +++-
 22 files changed, 80 insertions(+), 64 deletions(-)

--
2.25.1



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

* [PATCH v1 1/8] parisc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 2/8] powerpc: " Ryan Roberts
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required parisc modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/parisc/include/asm/hugetlb.h | 2 +-
 arch/parisc/mm/hugetlbpage.c      | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
index f7f078c2872c..29ba631862c5 100644
--- a/arch/parisc/include/asm/hugetlb.h
+++ b/arch/parisc/include/asm/hugetlb.h
@@ -5,7 +5,7 @@
 #include <asm/page.h>
 
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
 #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index a8a1a7c1e16e..fc5e1ad8e5e8 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -139,10 +139,10 @@ static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	purge_tlb_entries_huge(mm, addr_start);
 }
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 		     pte_t *ptep, pte_t entry)
 {
-	__set_huge_pte_at(mm, addr, ptep, entry);
+	__set_huge_pte_at(vma->vm_mm, addr, ptep, entry);
 }
 
 
-- 
2.25.1



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

* [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 1/8] parisc: hugetlb: Convert set_huge_pte_at() to take vma Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-21 18:43   ` Christophe Leroy
  2023-09-22  6:56   ` Christophe Leroy
  2023-09-21 16:20 ` [PATCH v1 3/8] riscv: " Ryan Roberts
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required powerpc modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 3 ++-
 arch/powerpc/mm/book3s64/hugetlbpage.c           | 2 +-
 arch/powerpc/mm/book3s64/radix_hugetlbpage.c     | 2 +-
 arch/powerpc/mm/nohash/8xx.c                     | 2 +-
 arch/powerpc/mm/pgtable.c                        | 7 ++++++-
 5 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index de092b04ee1a..fff8cd726bc7 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift)
 }
 
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte);
+void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
 
 #define __HAVE_ARCH_HUGE_PTE_CLEAR
 static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
index 3bc0eb21b2a0..ae7fd7c90eb8 100644
--- a/arch/powerpc/mm/book3s64/hugetlbpage.c
+++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
@@ -147,7 +147,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
 	if (radix_enabled())
 		return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
 							   old_pte, pte);
-	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+	set_huge_pte_at(vma, addr, ptep, pte);
 }
 
 void __init hugetlbpage_init_defaultsize(void)
diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
index 17075c78d4bc..7cd40a334c3a 100644
--- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
+++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
@@ -58,5 +58,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 	    atomic_read(&mm->context.copros) > 0)
 		radix__flush_hugetlb_page(vma, addr);
 
-	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+	set_huge_pte_at(vma, addr, ptep, pte);
 }
diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
index dbbfe897455d..650a7a8496b6 100644
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -91,7 +91,7 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
 	if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
 		return -EINVAL;
 
-	set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
+	__set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
 
 	return 0;
 }
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 3f86fd217690..9cbcb561a4d8 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -288,7 +288,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 }
 
 #if defined(CONFIG_PPC_8xx)
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
 {
 	pmd_t *pmd = pmd_off(mm, addr);
 	pte_basic_t val;
@@ -310,6 +310,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
 	for (i = 0; i < num; i++, entry++, val += SZ_4K)
 		*entry = val;
 }
+
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+}
 #endif
 #endif /* CONFIG_HUGETLB_PAGE */
 
-- 
2.25.1



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

* [PATCH v1 3/8] riscv: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 1/8] parisc: hugetlb: Convert set_huge_pte_at() to take vma Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 2/8] powerpc: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-22  7:54   ` Alexandre Ghiti
  2023-09-21 16:20 ` [PATCH v1 4/8] s390: " Ryan Roberts
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required riscv modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/riscv/include/asm/hugetlb.h | 2 +-
 arch/riscv/mm/hugetlbpage.c      | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
index 34e24f078cc1..be1ac8582bc2 100644
--- a/arch/riscv/include/asm/hugetlb.h
+++ b/arch/riscv/include/asm/hugetlb.h
@@ -17,7 +17,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 		    pte_t *ptep, unsigned long sz);
 
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-void set_huge_pte_at(struct mm_struct *mm,
+void set_huge_pte_at(struct vm_area_struct *vma,
 		     unsigned long addr, pte_t *ptep, pte_t pte);
 
 #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index 96225a8533ad..7cdbf0960772 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -177,11 +177,12 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
 	return entry;
 }
 
-void set_huge_pte_at(struct mm_struct *mm,
+void set_huge_pte_at(struct vm_area_struct *vma,
 		     unsigned long addr,
 		     pte_t *ptep,
 		     pte_t pte)
 {
+	struct mm_struct *mm = vma->vm_mm;
 	int i, pte_num;
 
 	if (!pte_napot(pte)) {
-- 
2.25.1



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

* [PATCH v1 4/8] s390: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (2 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 3/8] riscv: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 5/8] sparc: " Ryan Roberts
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required s390 modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/s390/include/asm/hugetlb.h | 8 +++++---
 arch/s390/mm/hugetlbpage.c      | 8 +++++++-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index f07267875a19..da7f43b1871f 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -15,7 +15,9 @@
 #define hugetlb_free_pgd_range			free_pgd_range
 #define hugepages_supported()			(MACHINE_HAS_EDAT1)
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
+		     pte_t *ptep, pte_t pte);
+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,
@@ -65,7 +67,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 	int changed = !pte_same(huge_ptep_get(ptep), pte);
 	if (changed) {
 		huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
-		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+		__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 	}
 	return changed;
 }
@@ -74,7 +76,7 @@ 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);
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
+	__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
 }
 
 static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index c718f2a0de94..d69e2dc6e508 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -142,7 +142,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
 		__storage_key_init_range(paddr, paddr + size - 1);
 }
 
-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)
 {
 	unsigned long rste;
@@ -163,6 +163,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte(ptep, __pte(rste));
 }
 
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
+		     pte_t *ptep, pte_t pte)
+{
+	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+}
+
 pte_t huge_ptep_get(pte_t *ptep)
 {
 	return __rste_to_pte(pte_val(*ptep));
-- 
2.25.1



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

* [PATCH v1 5/8] sparc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (3 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 4/8] s390: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 6/8] mm: " Ryan Roberts
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required sparc modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/sparc/include/asm/hugetlb.h | 8 +++++---
 arch/sparc/mm/hugetlbpage.c      | 8 +++++++-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index 0a26cca24232..14a71b735bb8 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -13,7 +13,9 @@ extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_end;
 #endif
 
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
+		     pte_t *ptep, pte_t pte);
+void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
 #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
@@ -32,7 +34,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 					   unsigned long addr, pte_t *ptep)
 {
 	pte_t old_pte = *ptep;
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+	__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
 }
 
 #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS
@@ -42,7 +44,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 {
 	int changed = !pte_same(*ptep, pte);
 	if (changed) {
-		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+		__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 		flush_tlb_page(vma, addr);
 	}
 	return changed;
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index d7018823206c..05267b72103f 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -328,7 +328,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
 	return pte_offset_huge(pmd, addr);
 }
 
-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 entry)
 {
 	unsigned int nptes, orig_shift, shift;
@@ -364,6 +364,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 				    orig_shift);
 }
 
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
+		     pte_t *ptep, pte_t entry)
+{
+	__set_huge_pte_at(vma->vm_mm, addr, ptep, entry);
+}
+
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep)
 {
-- 
2.25.1



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

* [PATCH v1 6/8] mm: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (4 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 5/8] sparc: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-22  1:37   ` SeongJae Park
  2023-09-21 16:20 ` [PATCH v1 7/8] arm64: " Ryan Roberts
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required modifications to the core mm. Separate
commits update the arches, before the actual bug is fixed in arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 include/asm-generic/hugetlb.h |  6 +++---
 include/linux/hugetlb.h       |  6 +++---
 mm/damon/vaddr.c              |  2 +-
 mm/hugetlb.c                  | 30 +++++++++++++++---------------
 mm/migrate.c                  |  2 +-
 mm/rmap.c                     | 10 +++++-----
 mm/vmalloc.c                  |  5 ++++-
 7 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 4da02798a00b..515e4777fb65 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -75,10 +75,10 @@ static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
 #endif
 
 #ifndef __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
-		pte_t *ptep, pte_t pte)
+static inline void set_huge_pte_at(struct vm_area_struct *vma,
+		unsigned long addr, pte_t *ptep, pte_t pte)
 {
-	set_pte_at(mm, addr, ptep, pte);
+	set_pte_at(vma->vm_mm, addr, ptep, pte);
 }
 #endif
 
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 5b2626063f4f..08184f32430c 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -984,7 +984,7 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 						unsigned long addr, pte_t *ptep,
 						pte_t old_pte, pte_t pte)
 {
-	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+	set_huge_pte_at(vma, addr, ptep, pte);
 }
 #endif
 
@@ -1172,8 +1172,8 @@ static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
 #endif
 }
 
-static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
-				   pte_t *ptep, pte_t pte)
+static inline void set_huge_pte_at(struct vm_area_struct *vma,
+				   unsigned long addr, pte_t *ptep, pte_t pte)
 {
 }
 
diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
index 4c81a9dbd044..55da8cee8fbc 100644
--- a/mm/damon/vaddr.c
+++ b/mm/damon/vaddr.c
@@ -347,7 +347,7 @@ static void damon_hugetlb_mkold(pte_t *pte, struct mm_struct *mm,
 	if (pte_young(entry)) {
 		referenced = true;
 		entry = pte_mkold(entry);
-		set_huge_pte_at(mm, addr, pte, entry);
+		set_huge_pte_at(vma, addr, pte, entry);
 	}
 
 #ifdef CONFIG_MMU_NOTIFIER
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ba6d39b71cb1..bcc30cd62586 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4988,7 +4988,7 @@ hugetlb_install_folio(struct vm_area_struct *vma, pte_t *ptep, unsigned long add
 	hugepage_add_new_anon_rmap(new_folio, vma, addr);
 	if (userfaultfd_wp(vma) && huge_pte_uffd_wp(old))
 		newpte = huge_pte_mkuffd_wp(newpte);
-	set_huge_pte_at(vma->vm_mm, addr, ptep, newpte);
+	set_huge_pte_at(vma, addr, ptep, newpte);
 	hugetlb_count_add(pages_per_huge_page(hstate_vma(vma)), vma->vm_mm);
 	folio_set_hugetlb_migratable(new_folio);
 }
@@ -5065,7 +5065,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 		} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) {
 			if (!userfaultfd_wp(dst_vma))
 				entry = huge_pte_clear_uffd_wp(entry);
-			set_huge_pte_at(dst, addr, dst_pte, entry);
+			set_huge_pte_at(dst_vma, addr, dst_pte, entry);
 		} else if (unlikely(is_hugetlb_entry_migration(entry))) {
 			swp_entry_t swp_entry = pte_to_swp_entry(entry);
 			bool uffd_wp = pte_swp_uffd_wp(entry);
@@ -5080,17 +5080,17 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 				entry = swp_entry_to_pte(swp_entry);
 				if (userfaultfd_wp(src_vma) && uffd_wp)
 					entry = pte_swp_mkuffd_wp(entry);
-				set_huge_pte_at(src, addr, src_pte, entry);
+				set_huge_pte_at(src_vma, addr, src_pte, entry);
 			}
 			if (!userfaultfd_wp(dst_vma))
 				entry = huge_pte_clear_uffd_wp(entry);
-			set_huge_pte_at(dst, addr, dst_pte, entry);
+			set_huge_pte_at(dst_vma, addr, dst_pte, entry);
 		} else if (unlikely(is_pte_marker(entry))) {
 			pte_marker marker = copy_pte_marker(
 				pte_to_swp_entry(entry), dst_vma);
 
 			if (marker)
-				set_huge_pte_at(dst, addr, dst_pte,
+				set_huge_pte_at(dst_vma, addr, dst_pte,
 						make_pte_marker(marker));
 		} else {
 			entry = huge_ptep_get(src_pte);
@@ -5166,7 +5166,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			if (!userfaultfd_wp(dst_vma))
 				entry = huge_pte_clear_uffd_wp(entry);
 
-			set_huge_pte_at(dst, addr, dst_pte, entry);
+			set_huge_pte_at(dst_vma, addr, dst_pte, entry);
 			hugetlb_count_add(npages, dst);
 		}
 		spin_unlock(src_ptl);
@@ -5202,7 +5202,7 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
 		spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
 
 	pte = huge_ptep_get_and_clear(mm, old_addr, src_pte);
-	set_huge_pte_at(mm, new_addr, dst_pte, pte);
+	set_huge_pte_at(vma, new_addr, dst_pte, pte);
 
 	if (src_ptl != dst_ptl)
 		spin_unlock(src_ptl);
@@ -5336,7 +5336,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
 			 */
 			if (pte_swp_uffd_wp_any(pte) &&
 			    !(zap_flags & ZAP_FLAG_DROP_MARKER))
-				set_huge_pte_at(mm, address, ptep,
+				set_huge_pte_at(vma, address, ptep,
 						make_pte_marker(PTE_MARKER_UFFD_WP));
 			else
 				huge_pte_clear(mm, address, ptep, sz);
@@ -5370,7 +5370,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
 		/* Leave a uffd-wp pte marker if needed */
 		if (huge_pte_uffd_wp(pte) &&
 		    !(zap_flags & ZAP_FLAG_DROP_MARKER))
-			set_huge_pte_at(mm, address, ptep,
+			set_huge_pte_at(vma, address, ptep,
 					make_pte_marker(PTE_MARKER_UFFD_WP));
 		hugetlb_count_sub(pages_per_huge_page(h), mm);
 		page_remove_rmap(page, vma, true);
@@ -5676,7 +5676,7 @@ static vm_fault_t hugetlb_wp(struct mm_struct *mm, struct vm_area_struct *vma,
 		hugepage_add_new_anon_rmap(new_folio, vma, haddr);
 		if (huge_pte_uffd_wp(pte))
 			newpte = huge_pte_mkuffd_wp(newpte);
-		set_huge_pte_at(mm, haddr, ptep, newpte);
+		set_huge_pte_at(vma, haddr, ptep, newpte);
 		folio_set_hugetlb_migratable(new_folio);
 		/* Make the old page be freed below */
 		new_folio = old_folio;
@@ -5972,7 +5972,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
 	 */
 	if (unlikely(pte_marker_uffd_wp(old_pte)))
 		new_pte = huge_pte_mkuffd_wp(new_pte);
-	set_huge_pte_at(mm, haddr, ptep, new_pte);
+	set_huge_pte_at(vma, haddr, ptep, new_pte);
 
 	hugetlb_count_add(pages_per_huge_page(h), mm);
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
@@ -6261,7 +6261,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
 		}
 
 		_dst_pte = make_pte_marker(PTE_MARKER_POISONED);
-		set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte);
+		set_huge_pte_at(dst_vma, dst_addr, dst_pte, _dst_pte);
 
 		/* No need to invalidate - it was non-present before */
 		update_mmu_cache(dst_vma, dst_addr, dst_pte);
@@ -6412,7 +6412,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
 	if (wp_enabled)
 		_dst_pte = huge_pte_mkuffd_wp(_dst_pte);
 
-	set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte);
+	set_huge_pte_at(dst_vma, dst_addr, dst_pte, _dst_pte);
 
 	hugetlb_count_add(pages_per_huge_page(h), dst_mm);
 
@@ -6598,7 +6598,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma,
 			else if (uffd_wp_resolve)
 				newpte = pte_swp_clear_uffd_wp(newpte);
 			if (!pte_same(pte, newpte))
-				set_huge_pte_at(mm, address, ptep, newpte);
+				set_huge_pte_at(vma, address, ptep, newpte);
 		} else if (unlikely(is_pte_marker(pte))) {
 			/* No other markers apply for now. */
 			WARN_ON_ONCE(!pte_marker_uffd_wp(pte));
@@ -6622,7 +6622,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma,
 			/* None pte */
 			if (unlikely(uffd_wp))
 				/* Safe to modify directly (none->non-present). */
-				set_huge_pte_at(mm, address, ptep,
+				set_huge_pte_at(vma, address, ptep,
 						make_pte_marker(PTE_MARKER_UFFD_WP));
 		}
 		spin_unlock(ptl);
diff --git a/mm/migrate.c b/mm/migrate.c
index b7fa020003f3..6aa752984f32 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -251,7 +251,7 @@ static bool remove_migration_pte(struct folio *folio,
 						       rmap_flags);
 			else
 				page_dup_file_rmap(new, true);
-			set_huge_pte_at(vma->vm_mm, pvmw.address, pvmw.pte, pte);
+			set_huge_pte_at(vma, pvmw.address, pvmw.pte, pte);
 		} else
 #endif
 		{
diff --git a/mm/rmap.c b/mm/rmap.c
index ec7f8e6c9e48..a6353a0c67e8 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1628,7 +1628,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
 			pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
 			if (folio_test_hugetlb(folio)) {
 				hugetlb_count_sub(folio_nr_pages(folio), mm);
-				set_huge_pte_at(mm, address, pvmw.pte, pteval);
+				set_huge_pte_at(vma, address, pvmw.pte, pteval);
 			} else {
 				dec_mm_counter(mm, mm_counter(&folio->page));
 				set_pte_at(mm, address, pvmw.pte, pteval);
@@ -2020,7 +2020,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
 			pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
 			if (folio_test_hugetlb(folio)) {
 				hugetlb_count_sub(folio_nr_pages(folio), mm);
-				set_huge_pte_at(mm, address, pvmw.pte, pteval);
+				set_huge_pte_at(vma, address, pvmw.pte, pteval);
 			} else {
 				dec_mm_counter(mm, mm_counter(&folio->page));
 				set_pte_at(mm, address, pvmw.pte, pteval);
@@ -2044,7 +2044,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
 
 			if (arch_unmap_one(mm, vma, address, pteval) < 0) {
 				if (folio_test_hugetlb(folio))
-					set_huge_pte_at(mm, address, pvmw.pte, pteval);
+					set_huge_pte_at(vma, address, pvmw.pte, pteval);
 				else
 					set_pte_at(mm, address, pvmw.pte, pteval);
 				ret = false;
@@ -2058,7 +2058,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
 			if (anon_exclusive &&
 			    page_try_share_anon_rmap(subpage)) {
 				if (folio_test_hugetlb(folio))
-					set_huge_pte_at(mm, address, pvmw.pte, pteval);
+					set_huge_pte_at(vma, address, pvmw.pte, pteval);
 				else
 					set_pte_at(mm, address, pvmw.pte, pteval);
 				ret = false;
@@ -2090,7 +2090,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
 			if (pte_uffd_wp(pteval))
 				swp_pte = pte_swp_mkuffd_wp(swp_pte);
 			if (folio_test_hugetlb(folio))
-				set_huge_pte_at(mm, address, pvmw.pte, swp_pte);
+				set_huge_pte_at(vma, address, pvmw.pte, swp_pte);
 			else
 				set_pte_at(mm, address, pvmw.pte, swp_pte);
 			trace_set_migration_pte(address, pte_val(swp_pte),
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index ef8599d394fd..10fa40222f30 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -94,6 +94,9 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 			phys_addr_t phys_addr, pgprot_t prot,
 			unsigned int max_page_shift, pgtbl_mod_mask *mask)
 {
+#ifdef CONFIG_HUGETLB_PAGE
+	struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
+#endif
 	pte_t *pte;
 	u64 pfn;
 	unsigned long size = PAGE_SIZE;
@@ -111,7 +114,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 			pte_t entry = pfn_pte(pfn, prot);
 
 			entry = arch_make_huge_pte(entry, ilog2(size), 0);
-			set_huge_pte_at(&init_mm, addr, pte, entry);
+			set_huge_pte_at(&vma, addr, pte, entry);
 			pfn += PFN_DOWN(size);
 			continue;
 		}
-- 
2.25.1



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

* [PATCH v1 7/8] arm64: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (5 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 6/8] mm: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-21 16:20 ` [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries Ryan Roberts
  2023-09-21 16:30 ` [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Andrew Morton
  8 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

In order to fix a bug, arm64 needs access to the vma inside it's
implementation of set_huge_pte_at(). Provide for this by converting the
mm parameter to be a vma. Any implementations that require the mm can
access it via vma->vm_mm.

This commit makes the required arm64 modifications. Separate commits
update the other arches and core code, before the actual bug is fixed in
arm64.

No behavioral changes intended.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
 arch/arm64/include/asm/hugetlb.h | 2 +-
 arch/arm64/mm/hugetlbpage.c      | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index f43a38ac1779..efc9025b9d27 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -27,7 +27,7 @@ static inline void arch_clear_hugepage_flags(struct page *page)
 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
 #define arch_make_huge_pte arch_make_huge_pte
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
-extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+extern void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 			    pte_t *ptep, pte_t pte);
 #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS
 extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 9c52718ea750..844832511c1e 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -248,9 +248,10 @@ static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
 	return page_folio(pfn_to_page(swp_offset_pfn(entry)));
 }
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 			    pte_t *ptep, pte_t pte)
 {
+	struct mm_struct *mm = vma->vm_mm;
 	size_t pgsize;
 	int i;
 	int ncontig;
@@ -571,5 +572,5 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
 void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
 				  pte_t old_pte, pte_t pte)
 {
-	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+	set_huge_pte_at(vma, addr, ptep, pte);
 }
-- 
2.25.1



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

* [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (6 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 7/8] arm64: " Ryan Roberts
@ 2023-09-21 16:20 ` Ryan Roberts
  2023-09-22  2:54   ` Qi Zheng
  2023-09-21 16:30 ` [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Andrew Morton
  8 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:20 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: Ryan Roberts, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

When called with a swap entry that does not embed a PFN (e.g.
PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
of set_huge_pte_at() would either cause a BUG() to fire (if
CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
and subsequent panic.

arm64's huge pte implementation supports multiple huge page sizes, some
of which are implemented in the page table with contiguous mappings. So
set_huge_pte_at() needs to work out how big the logical pte is, so that
it can also work out how many physical ptes (or pmds) need to be
written. It does this by grabbing the folio out of the pte and querying
its size.

However, there are cases when the pte being set is actually a swap
entry. But this also used to work fine, because for huge ptes, we only
ever saw migration entries and hwpoison entries. And both of these types
of swap entries have a PFN embedded, so the code would grab that and
everything still worked out.

But over time, more calls to set_huge_pte_at() have been added that set
swap entry types that do not embed a PFN. And this causes the code to go
bang. The triggering case is for the uffd poison test, commit
99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
which sets a PTE_MARKER_POISONED swap entry. But review shows there are
other places too (PTE_MARKER_UFFD_WP).

So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
set_huge_swap_pte_at()"), which aimed to simplify the interface to the
core code by removing set_huge_swap_pte_at() (which took a page size
parameter) and replacing it with calls to set_huge_swap_pte_at() where
the size was inferred from the folio, as descibed above. While that
commit didn't break anything at the time, it did break the interface
because it couldn't handle swap entries without PFNs. And since then new
callers have come along which rely on this working.

Now that we have modified the set_huge_pte_at() interface to pass the
vma, we can extract the huge page size from it and fix this issue.

I'm tagging the commit that added the uffd poison feature, since that is
what exposed the problem, as well as the original change that broke the
interface. Hopefully this is valuable for people doing bisect.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Fixes: 18f3962953e4 ("mm: hugetlb: kill set_huge_swap_pte_at()")
Fixes: 8a13897fb0da ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs")
---
 arch/arm64/mm/hugetlbpage.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 844832511c1e..a08601a14689 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -241,13 +241,6 @@ static void clear_flush(struct mm_struct *mm,
 	flush_tlb_range(&vma, saddr, addr);
 }
 
-static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
-{
-	VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
-
-	return page_folio(pfn_to_page(swp_offset_pfn(entry)));
-}
-
 void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 			    pte_t *ptep, pte_t pte)
 {
@@ -258,13 +251,10 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 	unsigned long pfn, dpfn;
 	pgprot_t hugeprot;
 
-	if (!pte_present(pte)) {
-		struct folio *folio;
-
-		folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
-		ncontig = num_contig_ptes(folio_size(folio), &pgsize);
+	ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize);
 
-		for (i = 0; i < ncontig; i++, ptep++)
+	if (!pte_present(pte)) {
+		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
 			set_pte_at(mm, addr, ptep, pte);
 		return;
 	}
@@ -274,7 +264,6 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
 		return;
 	}
 
-	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
 	pfn = pte_pfn(pte);
 	dpfn = pgsize >> PAGE_SHIFT;
 	hugeprot = pte_pgprot(pte);
-- 
2.25.1



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

* Re: [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
  2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
                   ` (7 preceding siblings ...)
  2023-09-21 16:20 ` [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries Ryan Roberts
@ 2023-09-21 16:30 ` Andrew Morton
  2023-09-21 16:35   ` Ryan Roberts
  8 siblings, 1 reply; 31+ messages in thread
From: Andrew Morton @ 2023-09-21 16:30 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, Anshuman Khandual, Peter Xu, Axel Rasmussen,
	Qi Zheng, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable, Greg Kroah-Hartman

On Thu, 21 Sep 2023 17:19:59 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:

> Hi All,
> 
> This series fixes a bug in arm64's implementation of set_huge_pte_at(), which
> can result in an unprivileged user causing a kernel panic. The problem was
> triggered when running the new uffd poison mm selftest for HUGETLB memory. This
> test (and the uffd poison feature) was merged for v6.6-rc1. However, upon
> inspection there are multiple other pre-existing paths that can trigger this
> bug.
> 
> Ideally, I'd like to get this fix in for v6.6 if possible? And I guess it should
> be backported too, given there are call sites where this can theoretically
> happen that pre-date v6.6-rc1 (I've cc'ed stable@vger.kernel.org).

This gets you a naggygram from Greg.  The way to request a backport is
to add cc:stable to all the changelogs.  I'll make that change to my copy.


> Ryan Roberts (8):
>   parisc: hugetlb: Convert set_huge_pte_at() to take vma
>   powerpc: hugetlb: Convert set_huge_pte_at() to take vma
>   riscv: hugetlb: Convert set_huge_pte_at() to take vma
>   s390: hugetlb: Convert set_huge_pte_at() to take vma
>   sparc: hugetlb: Convert set_huge_pte_at() to take vma
>   mm: hugetlb: Convert set_huge_pte_at() to take vma
>   arm64: hugetlb: Convert set_huge_pte_at() to take vma
>   arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
> 
>  arch/arm64/include/asm/hugetlb.h              |  2 +-
>  arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
>  arch/parisc/include/asm/hugetlb.h             |  2 +-
>  arch/parisc/mm/hugetlbpage.c                  |  4 +--
>  .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
>  arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
>  arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
>  arch/powerpc/mm/nohash/8xx.c                  |  2 +-
>  arch/powerpc/mm/pgtable.c                     |  7 ++++-
>  arch/riscv/include/asm/hugetlb.h              |  2 +-
>  arch/riscv/mm/hugetlbpage.c                   |  3 +-
>  arch/s390/include/asm/hugetlb.h               |  8 +++--
>  arch/s390/mm/hugetlbpage.c                    |  8 ++++-
>  arch/sparc/include/asm/hugetlb.h              |  8 +++--
>  arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
>  include/asm-generic/hugetlb.h                 |  6 ++--
>  include/linux/hugetlb.h                       |  6 ++--
>  mm/damon/vaddr.c                              |  2 +-
>  mm/hugetlb.c                                  | 30 +++++++++----------
>  mm/migrate.c                                  |  2 +-
>  mm/rmap.c                                     | 10 +++----
>  mm/vmalloc.c                                  |  5 +++-
>  22 files changed, 80 insertions(+), 64 deletions(-)

Looks scary but it's actually a fairly modest patchset.  It could
easily be all rolled into a single patch for ease of backporting. 
Maybe Greg has an opinion?



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

* Re: [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
  2023-09-21 16:30 ` [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Andrew Morton
@ 2023-09-21 16:35   ` Ryan Roberts
  2023-09-21 17:38     ` Catalin Marinas
  2023-09-22  9:23     ` Greg Kroah-Hartman
  0 siblings, 2 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-21 16:35 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, Anshuman Khandual, Peter Xu, Axel Rasmussen,
	Qi Zheng, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable, Greg Kroah-Hartman

On 21/09/2023 17:30, Andrew Morton wrote:
> On Thu, 21 Sep 2023 17:19:59 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:
> 
>> Hi All,
>>
>> This series fixes a bug in arm64's implementation of set_huge_pte_at(), which
>> can result in an unprivileged user causing a kernel panic. The problem was
>> triggered when running the new uffd poison mm selftest for HUGETLB memory. This
>> test (and the uffd poison feature) was merged for v6.6-rc1. However, upon
>> inspection there are multiple other pre-existing paths that can trigger this
>> bug.
>>
>> Ideally, I'd like to get this fix in for v6.6 if possible? And I guess it should
>> be backported too, given there are call sites where this can theoretically
>> happen that pre-date v6.6-rc1 (I've cc'ed stable@vger.kernel.org).
> 
> This gets you a naggygram from Greg.  The way to request a backport is
> to add cc:stable to all the changelogs.  I'll make that change to my copy.

Ahh, sorry about that... I just got the same moan from the kernel test robot too.

> 
> 
>> Ryan Roberts (8):
>>   parisc: hugetlb: Convert set_huge_pte_at() to take vma
>>   powerpc: hugetlb: Convert set_huge_pte_at() to take vma
>>   riscv: hugetlb: Convert set_huge_pte_at() to take vma
>>   s390: hugetlb: Convert set_huge_pte_at() to take vma
>>   sparc: hugetlb: Convert set_huge_pte_at() to take vma
>>   mm: hugetlb: Convert set_huge_pte_at() to take vma
>>   arm64: hugetlb: Convert set_huge_pte_at() to take vma
>>   arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
>>
>>  arch/arm64/include/asm/hugetlb.h              |  2 +-
>>  arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
>>  arch/parisc/include/asm/hugetlb.h             |  2 +-
>>  arch/parisc/mm/hugetlbpage.c                  |  4 +--
>>  .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
>>  arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
>>  arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
>>  arch/powerpc/mm/nohash/8xx.c                  |  2 +-
>>  arch/powerpc/mm/pgtable.c                     |  7 ++++-
>>  arch/riscv/include/asm/hugetlb.h              |  2 +-
>>  arch/riscv/mm/hugetlbpage.c                   |  3 +-
>>  arch/s390/include/asm/hugetlb.h               |  8 +++--
>>  arch/s390/mm/hugetlbpage.c                    |  8 ++++-
>>  arch/sparc/include/asm/hugetlb.h              |  8 +++--
>>  arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
>>  include/asm-generic/hugetlb.h                 |  6 ++--
>>  include/linux/hugetlb.h                       |  6 ++--
>>  mm/damon/vaddr.c                              |  2 +-
>>  mm/hugetlb.c                                  | 30 +++++++++----------
>>  mm/migrate.c                                  |  2 +-
>>  mm/rmap.c                                     | 10 +++----
>>  mm/vmalloc.c                                  |  5 +++-
>>  22 files changed, 80 insertions(+), 64 deletions(-)
> 
> Looks scary but it's actually a fairly modest patchset.  It could
> easily be all rolled into a single patch for ease of backporting. 
> Maybe Greg has an opinion?

Yes, I thought about doing that; or perhaps 2 patches - one for the interface
change across all arches and core code, and one for the actual bug fix?

But I thought the arch people might prefer to see exactly what's going on in
each arch. Let me know the preference and I can repost if necessary.

> 



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

* Re: [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
  2023-09-21 16:35   ` Ryan Roberts
@ 2023-09-21 17:38     ` Catalin Marinas
  2023-09-22  7:41       ` Ryan Roberts
  2023-09-22  9:23     ` Greg Kroah-Hartman
  1 sibling, 1 reply; 31+ messages in thread
From: Catalin Marinas @ 2023-09-21 17:38 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Andrew Morton, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, Anshuman Khandual, Peter Xu, Axel Rasmussen,
	Qi Zheng, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable, Greg Kroah-Hartman

On Thu, Sep 21, 2023 at 05:35:54PM +0100, Ryan Roberts wrote:
> On 21/09/2023 17:30, Andrew Morton wrote:
> > On Thu, 21 Sep 2023 17:19:59 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:
> >> Ryan Roberts (8):
> >>   parisc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   powerpc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   riscv: hugetlb: Convert set_huge_pte_at() to take vma
> >>   s390: hugetlb: Convert set_huge_pte_at() to take vma
> >>   sparc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   mm: hugetlb: Convert set_huge_pte_at() to take vma
> >>   arm64: hugetlb: Convert set_huge_pte_at() to take vma
> >>   arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
> >>
> >>  arch/arm64/include/asm/hugetlb.h              |  2 +-
> >>  arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
> >>  arch/parisc/include/asm/hugetlb.h             |  2 +-
> >>  arch/parisc/mm/hugetlbpage.c                  |  4 +--
> >>  .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
> >>  arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
> >>  arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
> >>  arch/powerpc/mm/nohash/8xx.c                  |  2 +-
> >>  arch/powerpc/mm/pgtable.c                     |  7 ++++-
> >>  arch/riscv/include/asm/hugetlb.h              |  2 +-
> >>  arch/riscv/mm/hugetlbpage.c                   |  3 +-
> >>  arch/s390/include/asm/hugetlb.h               |  8 +++--
> >>  arch/s390/mm/hugetlbpage.c                    |  8 ++++-
> >>  arch/sparc/include/asm/hugetlb.h              |  8 +++--
> >>  arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
> >>  include/asm-generic/hugetlb.h                 |  6 ++--
> >>  include/linux/hugetlb.h                       |  6 ++--
> >>  mm/damon/vaddr.c                              |  2 +-
> >>  mm/hugetlb.c                                  | 30 +++++++++----------
> >>  mm/migrate.c                                  |  2 +-
> >>  mm/rmap.c                                     | 10 +++----
> >>  mm/vmalloc.c                                  |  5 +++-
> >>  22 files changed, 80 insertions(+), 64 deletions(-)
> > 
> > Looks scary but it's actually a fairly modest patchset.  It could
> > easily be all rolled into a single patch for ease of backporting. 
> > Maybe Greg has an opinion?
> 
> Yes, I thought about doing that; or perhaps 2 patches - one for the interface
> change across all arches and core code, and one for the actual bug fix?

I think this would make more sense, especially if we want to backport
it. The first patch would have no functional change, only an interface
change, followed by the arm64 fix.

-- 
Catalin


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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:20 ` [PATCH v1 2/8] powerpc: " Ryan Roberts
@ 2023-09-21 18:43   ` Christophe Leroy
  2023-09-22  6:44     ` Christophe Leroy
  2023-09-22  6:56   ` Christophe Leroy
  1 sibling, 1 reply; 31+ messages in thread
From: Christophe Leroy @ 2023-09-21 18:43 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable



Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
> In order to fix a bug, arm64 needs access to the vma inside it's
> implementation of set_huge_pte_at(). Provide for this by converting the
> mm parameter to be a vma. Any implementations that require the mm can
> access it via vma->vm_mm.
> 
> This commit makes the required powerpc modifications. Separate commits
> update the other arches and core code, before the actual bug is fixed in
> arm64.
> 
> No behavioral changes intended.

This patch doesn't build, allthough I have also applied patch 1. Is 
something missing ?

   CALL    scripts/checksyscalls.sh
   CC      arch/powerpc/kernel/setup-common.o
In file included from arch/powerpc/kernel/setup-common.c:37:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: 
arch/powerpc/kernel/setup-common.o] Error 1
make[4]: Target 'arch/powerpc/kernel/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: arch/powerpc/kernel] Error 2
   CC      arch/powerpc/mm/fault.o
In file included from arch/powerpc/mm/fault.c:33:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: arch/powerpc/mm/fault.o] Error 1
   CC      arch/powerpc/mm/pgtable.o
In file included from arch/powerpc/mm/pgtable.c:25:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: arch/powerpc/mm/pgtable.o] Error 1
   CC      arch/powerpc/mm/init_32.o
In file included from arch/powerpc/mm/init_32.c:30:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: arch/powerpc/mm/init_32.o] Error 1
   CC      arch/powerpc/mm/pgtable-frag.o
In file included from arch/powerpc/mm/pgtable-frag.c:13:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: 
arch/powerpc/mm/pgtable-frag.o] Error 1
   CC      arch/powerpc/mm/nohash/tlb.o
In file included from arch/powerpc/mm/nohash/tlb.c:35:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[5]: *** [scripts/Makefile.build:243: arch/powerpc/mm/nohash/tlb.o] 
Error 1
   CC      arch/powerpc/mm/nohash/8xx.o
In file included from arch/powerpc/mm/nohash/8xx.c:11:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[5]: *** [scripts/Makefile.build:243: arch/powerpc/mm/nohash/8xx.o] 
Error 1
make[5]: Target 'arch/powerpc/mm/nohash/' not remade because of errors.
make[4]: *** [scripts/Makefile.build:480: arch/powerpc/mm/nohash] Error 2
   CC      arch/powerpc/mm/hugetlbpage.o
In file included from arch/powerpc/mm/hugetlbpage.c:14:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: arch/powerpc/mm/hugetlbpage.o] 
Error 1
make[4]: Target 'arch/powerpc/mm/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: arch/powerpc/mm] Error 2
make[3]: Target 'arch/powerpc/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: arch/powerpc] Error 2
   CC      kernel/fork.o
In file included from kernel/fork.c:52:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: kernel/fork.o] Error 1
   CC      kernel/sysctl.o
In file included from kernel/sysctl.c:45:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: kernel/sysctl.o] Error 1
   CC      kernel/events/core.o
In file included from kernel/events/core.c:31:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: kernel/events/core.o] Error 1
make[4]: Target 'kernel/events/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: kernel/events] Error 2
make[3]: Target 'kernel/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: kernel] Error 2
   CC      mm/filemap.o
In file included from mm/filemap.c:37:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/filemap.o] Error 1
   CC      mm/folio-compat.o
In file included from ./include/linux/migrate.h:8,
                  from mm/folio-compat.c:7:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/folio-compat.o] Error 1
   CC      mm/swap.o
In file included from mm/swap.c:36:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/swap.o] Error 1
   CC      mm/vmscan.o
In file included from ./include/linux/migrate.h:8,
                  from mm/vmscan.c:43:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/vmscan.o] Error 1
   CC      mm/shmem.o
In file included from mm/shmem.c:39:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/shmem.o] Error 1
   CC      mm/util.o
In file included from mm/util.c:16:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/util.o] Error 1
   CC      mm/compaction.o
In file included from ./include/linux/migrate.h:8,
                  from mm/compaction.c:13:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/compaction.o] Error 1
   CC      mm/show_mem.o
In file included from mm/show_mem.c:12:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/show_mem.o] Error 1
   CC      mm/debug.o
In file included from ./include/linux/migrate.h:8,
                  from mm/debug.c:14:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/debug.o] Error 1
   CC      mm/gup.o
In file included from mm/gup.c:17:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/gup.o] Error 1
   CC      mm/memory.o
In file included from mm/memory.c:49:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/memory.o] Error 1
   CC      mm/mincore.o
In file included from mm/mincore.c:19:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/mincore.o] Error 1
   CC      mm/mlock.o
In file included from mm/mlock.c:24:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/mlock.o] Error 1
   CC      mm/mmap.o
In file included from mm/mmap.c:28:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/mmap.o] Error 1
   CC      mm/mprotect.o
In file included from mm/mprotect.c:13:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/mprotect.o] Error 1
   CC      mm/mremap.o
In file included from mm/mremap.c:13:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/mremap.o] Error 1
   CC      mm/page_vma_mapped.o
In file included from mm/page_vma_mapped.c:4:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/page_vma_mapped.o] Error 1
   CC      mm/pagewalk.o
In file included from mm/pagewalk.c:5:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/pagewalk.o] Error 1
   CC      mm/pgtable-generic.o
In file included from mm/pgtable-generic.c:11:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/pgtable-generic.o] Error 1
   CC      mm/rmap.o
In file included from ./include/linux/migrate.h:8,
                  from mm/rmap.c:70:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/rmap.c: In function 'try_to_unmap_one':
mm/rmap.c:1631:49: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
  1631 |                                 set_huge_pte_at(mm, address, 
pvmw.pte, pteval);
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/rmap.c: In function 'try_to_migrate_one':
mm/rmap.c:2023:49: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
  2023 |                                 set_huge_pte_at(mm, address, 
pvmw.pte, pteval);
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/rmap.c:2047:57: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
  2047 |                                         set_huge_pte_at(mm, 
address, pvmw.pte, pteval);
       |                                                         ^~
       |                                                         |
       |                                                         struct 
mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/rmap.c:2061:57: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
  2061 |                                         set_huge_pte_at(mm, 
address, pvmw.pte, pteval);
       |                                                         ^~
       |                                                         |
       |                                                         struct 
mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/rmap.c:2093:49: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
  2093 |                                 set_huge_pte_at(mm, address, 
pvmw.pte, swp_pte);
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/rmap.o] Error 1
   CC      mm/vmalloc.o
In file included from mm/vmalloc.c:41:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/vmalloc.c: In function 'vmap_pte_range':
mm/vmalloc.c:114:41: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
   114 |                         set_huge_pte_at(&init_mm, addr, pte, 
entry);
       |                                         ^~~~~~~~
       |                                         |
       |                                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/vmalloc.o] Error 1
   CC      mm/page_alloc.o
In file included from ./include/linux/migrate.h:8,
                  from mm/page_alloc.c:45:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/page_alloc.o] Error 1
   CC      mm/madvise.o
In file included from mm/madvise.c:16:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/madvise.o] Error 1
   CC      mm/hugetlb.o
In file included from ./include/linux/migrate.h:8,
                  from mm/hugetlb.c:33:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'hugetlb_install_folio':
mm/hugetlb.c:4991:28: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  4991 |         set_huge_pte_at(vma->vm_mm, addr, ptep, newpte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'copy_hugetlb_page_range':
mm/hugetlb.c:5068:41: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5068 |                         set_huge_pte_at(dst, addr, dst_pte, entry);
       |                                         ^~~
       |                                         |
       |                                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:5083:49: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5083 |                                 set_huge_pte_at(src, addr, 
src_pte, entry);
       |                                                 ^~~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:5087:41: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5087 |                         set_huge_pte_at(dst, addr, dst_pte, entry);
       |                                         ^~~
       |                                         |
       |                                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:5093:49: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5093 |                                 set_huge_pte_at(dst, addr, dst_pte,
       |                                                 ^~~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:5169:41: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5169 |                         set_huge_pte_at(dst, addr, dst_pte, entry);
       |                                         ^~~
       |                                         |
       |                                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'move_huge_pte':
mm/hugetlb.c:5205:25: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5205 |         set_huge_pte_at(mm, new_addr, dst_pte, pte);
       |                         ^~
       |                         |
       |                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function '__unmap_hugepage_range':
mm/hugetlb.c:5339:49: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5339 |                                 set_huge_pte_at(mm, address, ptep,
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:5373:41: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5373 |                         set_huge_pte_at(mm, address, ptep,
       |                                         ^~
       |                                         |
       |                                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'hugetlb_wp':
mm/hugetlb.c:5679:33: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5679 |                 set_huge_pte_at(mm, haddr, ptep, newpte);
       |                                 ^~
       |                                 |
       |                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'hugetlb_no_page':
mm/hugetlb.c:5975:25: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  5975 |         set_huge_pte_at(mm, haddr, ptep, new_pte);
       |                         ^~
       |                         |
       |                         struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c: In function 'hugetlb_change_protection':
mm/hugetlb.c:6601:49: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  6601 |                                 set_huge_pte_at(mm, address, 
ptep, newpte);
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/hugetlb.c:6625:49: error: passing argument 1 of 'set_huge_pte_at' 
from incompatible pointer type [-Werror=incompatible-pointer-types]
  6625 |                                 set_huge_pte_at(mm, address, ptep,
       |                                                 ^~
       |                                                 |
       |                                                 struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/hugetlb.o] Error 1
   CC      mm/migrate.o
In file included from ./include/linux/migrate.h:8,
                  from mm/migrate.c:16:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
mm/migrate.c: In function 'remove_migration_pte':
mm/migrate.c:254:44: error: passing argument 1 of 'set_huge_pte_at' from 
incompatible pointer type [-Werror=incompatible-pointer-types]
   254 |                         set_huge_pte_at(vma->vm_mm, 
pvmw.address, pvmw.pte, pte);
       |                                         ~~~^~~~~~~
       |                                            |
       |                                            struct mm_struct *
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/migrate.o] Error 1
   CC      mm/debug_vm_pgtable.o
In file included from mm/debug_vm_pgtable.c:15:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/debug_vm_pgtable.o] Error 1
   CC      mm/memfd.o
In file included from mm/memfd.c:18:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: mm/memfd.o] Error 1
make[3]: Target 'mm/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: mm] Error 2
   CC      fs/aio.o
In file included from ./include/linux/migrate.h:8,
                  from fs/aio.c:40:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: fs/aio.o] Error 1
   CC      fs/binfmt_elf.o
In file included from fs/binfmt_elf.c:31:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: fs/binfmt_elf.o] Error 1
   CC      fs/iomap/buffered-io.o
In file included from ./include/linux/migrate.h:8,
                  from fs/iomap/buffered-io.c:19:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/iomap/buffered-io.o] Error 1
make[4]: Target 'fs/iomap/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: fs/iomap] Error 2
   CC      fs/proc/task_mmu.o
In file included from fs/proc/task_mmu.c:4:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/proc/task_mmu.o] Error 1
   CC      fs/proc/array.o
In file included from fs/proc/array.c:74:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/proc/array.o] Error 1
   CC      fs/proc/meminfo.o
In file included from fs/proc/meminfo.c:6:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/proc/meminfo.o] Error 1
   CC      fs/proc/page.o
In file included from fs/proc/page.c:12:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/proc/page.o] Error 1
make[4]: Target 'fs/proc/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: fs/proc] Error 2
   CC      fs/hugetlbfs/inode.o
In file included from fs/hugetlbfs/inode.c:27:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/hugetlbfs/inode.o] Error 1
make[4]: Target 'fs/hugetlbfs/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: fs/hugetlbfs] Error 2
   CC      fs/nfs/write.o
In file included from ./include/linux/migrate.h:8,
                  from fs/nfs/write.c:17:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: fs/nfs/write.o] Error 1
make[4]: Target 'fs/nfs/' not remade because of errors.
make[3]: *** [scripts/Makefile.build:480: fs/nfs] Error 2
make[3]: Target 'fs/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: fs] Error 2
   CC      ipc/shm.o
In file included from ipc/shm.c:30:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: ipc/shm.o] Error 1
make[3]: Target 'ipc/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: ipc] Error 2
   CC      security/commoncap.o
In file included from security/commoncap.c:19:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: security/commoncap.o] Error 1
make[3]: Target 'security/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: security] Error 2
   CC      io_uring/rsrc.o
In file included from io_uring/rsrc.c:9:
./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
./include/linux/hugetlb.h:987:28: error: passing argument 1 of 
'set_huge_pte_at' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
   987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
       |                         ~~~^~~~~~~
       |                            |
       |                            struct mm_struct *
In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
                  from ./include/linux/hugetlb.h:815:
./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected 
'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
    49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long 
addr, pte_t *ptep, pte_t pte);
       |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: io_uring/rsrc.o] Error 1
make[3]: Target 'io_uring/' not remade because of errors.
make[2]: *** [scripts/Makefile.build:480: io_uring] Error 2
make[2]: Target './' not remade because of errors.
make[1]: *** [/home/chleroy/linux-powerpc/Makefile:1913: .] Error 2
make[1]: Target 'vmlinux' not remade because of errors.
make: *** [Makefile:234: __sub-make] Error 2
make: Target 'vmlinux' not remade because of errors.

Christophe

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

* Re: [PATCH v1 6/8] mm: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:20 ` [PATCH v1 6/8] mm: " Ryan Roberts
@ 2023-09-22  1:37   ` SeongJae Park
  0 siblings, 0 replies; 31+ messages in thread
From: SeongJae Park @ 2023-09-22  1:37 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Will Deacon, James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Christophe Leroy, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng, linux-arm-kernel, linux-kernel,
	linux-parisc, linuxppc-dev, linux-riscv, linux-s390, sparclinux,
	linux-mm, stable

Hi Ryan,

On Thu, 21 Sep 2023 17:20:05 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:

> In order to fix a bug, arm64 needs access to the vma inside it's
> implementation of set_huge_pte_at(). Provide for this by converting the
> mm parameter to be a vma. Any implementations that require the mm can
> access it via vma->vm_mm.
> 
> This commit makes the required modifications to the core mm. Separate
> commits update the arches, before the actual bug is fixed in arm64.
> 
> No behavioral changes intended.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>

For mm/damon/ part change,

Reviewed-by: SeongJae Park <sj@kernel.org>


Thanks,
SJ


> ---
>  include/asm-generic/hugetlb.h |  6 +++---
>  include/linux/hugetlb.h       |  6 +++---
>  mm/damon/vaddr.c              |  2 +-
>  mm/hugetlb.c                  | 30 +++++++++++++++---------------
>  mm/migrate.c                  |  2 +-
>  mm/rmap.c                     | 10 +++++-----
>  mm/vmalloc.c                  |  5 ++++-
>  7 files changed, 32 insertions(+), 29 deletions(-)
> 
> diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
> index 4da02798a00b..515e4777fb65 100644
> --- a/include/asm-generic/hugetlb.h
> +++ b/include/asm-generic/hugetlb.h
> @@ -75,10 +75,10 @@ static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
>  #endif
>  
>  #ifndef __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
> -static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> -		pte_t *ptep, pte_t pte)
> +static inline void set_huge_pte_at(struct vm_area_struct *vma,
> +		unsigned long addr, pte_t *ptep, pte_t pte)
>  {
> -	set_pte_at(mm, addr, ptep, pte);
> +	set_pte_at(vma->vm_mm, addr, ptep, pte);
>  }
>  #endif
>  
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 5b2626063f4f..08184f32430c 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -984,7 +984,7 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
>  						unsigned long addr, pte_t *ptep,
>  						pte_t old_pte, pte_t pte)
>  {
> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> +	set_huge_pte_at(vma, addr, ptep, pte);
>  }
>  #endif
>  
> @@ -1172,8 +1172,8 @@ static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
>  #endif
>  }
>  
> -static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> -				   pte_t *ptep, pte_t pte)
> +static inline void set_huge_pte_at(struct vm_area_struct *vma,
> +				   unsigned long addr, pte_t *ptep, pte_t pte)
>  {
>  }
>  
> diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
> index 4c81a9dbd044..55da8cee8fbc 100644
> --- a/mm/damon/vaddr.c
> +++ b/mm/damon/vaddr.c
> @@ -347,7 +347,7 @@ static void damon_hugetlb_mkold(pte_t *pte, struct mm_struct *mm,
>  	if (pte_young(entry)) {
>  		referenced = true;
>  		entry = pte_mkold(entry);
> -		set_huge_pte_at(mm, addr, pte, entry);
> +		set_huge_pte_at(vma, addr, pte, entry);
>  	}
>  
>  #ifdef CONFIG_MMU_NOTIFIER
[...]


Thanks,
SJ


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

* Re: [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-21 16:20 ` [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries Ryan Roberts
@ 2023-09-22  2:54   ` Qi Zheng
  2023-09-22  7:40     ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Qi Zheng @ 2023-09-22  2:54 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng, linux-arm-kernel, linux-kernel,
	linux-parisc, linuxppc-dev, linux-riscv, linux-s390, sparclinux,
	linux-mm, stable

Hi Ryan,

On 2023/9/22 00:20, Ryan Roberts wrote:
> When called with a swap entry that does not embed a PFN (e.g.
> PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
> of set_huge_pte_at() would either cause a BUG() to fire (if
> CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
> and subsequent panic.
> 
> arm64's huge pte implementation supports multiple huge page sizes, some
> of which are implemented in the page table with contiguous mappings. So
> set_huge_pte_at() needs to work out how big the logical pte is, so that
> it can also work out how many physical ptes (or pmds) need to be
> written. It does this by grabbing the folio out of the pte and querying
> its size.
> 
> However, there are cases when the pte being set is actually a swap
> entry. But this also used to work fine, because for huge ptes, we only
> ever saw migration entries and hwpoison entries. And both of these types
> of swap entries have a PFN embedded, so the code would grab that and
> everything still worked out.
> 
> But over time, more calls to set_huge_pte_at() have been added that set
> swap entry types that do not embed a PFN. And this causes the code to go
> bang. The triggering case is for the uffd poison test, commit
> 99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
> which sets a PTE_MARKER_POISONED swap entry. But review shows there are
> other places too (PTE_MARKER_UFFD_WP).
> 
> So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
> set_huge_swap_pte_at()"), which aimed to simplify the interface to the
> core code by removing set_huge_swap_pte_at() (which took a page size
> parameter) and replacing it with calls to set_huge_swap_pte_at() where
> the size was inferred from the folio, as descibed above. While that
> commit didn't break anything at the time, 

If it didn't break anything at that time, then shouldn't the Fixes tag
be added to this commit?

> it did break the interface
> because it couldn't handle swap entries without PFNs. And since then new
> callers have come along which rely on this working.

So the Fixes tag should be added only to the commit that introduces the
first new callers?

Other than that, LGTM.

Thanks,
Qi

> 
> Now that we have modified the set_huge_pte_at() interface to pass the
> vma, we can extract the huge page size from it and fix this issue.
> 
> I'm tagging the commit that added the uffd poison feature, since that is
> what exposed the problem, as well as the original change that broke the
> interface. Hopefully this is valuable for people doing bisect.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> Fixes: 18f3962953e4 ("mm: hugetlb: kill set_huge_swap_pte_at()")
> Fixes: 8a13897fb0da ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs")
> ---
>   arch/arm64/mm/hugetlbpage.c | 17 +++--------------
>   1 file changed, 3 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 844832511c1e..a08601a14689 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -241,13 +241,6 @@ static void clear_flush(struct mm_struct *mm,
>   	flush_tlb_range(&vma, saddr, addr);
>   }
>   
> -static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
> -{
> -	VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
> -
> -	return page_folio(pfn_to_page(swp_offset_pfn(entry)));
> -}
> -
>   void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
>   			    pte_t *ptep, pte_t pte)
>   {
> @@ -258,13 +251,10 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
>   	unsigned long pfn, dpfn;
>   	pgprot_t hugeprot;
>   
> -	if (!pte_present(pte)) {
> -		struct folio *folio;
> -
> -		folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
> -		ncontig = num_contig_ptes(folio_size(folio), &pgsize);
> +	ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize);
>   
> -		for (i = 0; i < ncontig; i++, ptep++)
> +	if (!pte_present(pte)) {
> +		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
>   			set_pte_at(mm, addr, ptep, pte);
>   		return;
>   	}
> @@ -274,7 +264,6 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
>   		return;
>   	}
>   
> -	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
>   	pfn = pte_pfn(pte);
>   	dpfn = pgsize >> PAGE_SHIFT;
>   	hugeprot = pte_pgprot(pte);


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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 18:43   ` Christophe Leroy
@ 2023-09-22  6:44     ` Christophe Leroy
  2023-09-22  7:19       ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Christophe Leroy @ 2023-09-22  6:44 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable



Le 21/09/2023 à 20:43, Christophe Leroy a écrit :
> 
> 
> Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
>> In order to fix a bug, arm64 needs access to the vma inside it's
>> implementation of set_huge_pte_at(). Provide for this by converting the
>> mm parameter to be a vma. Any implementations that require the mm can
>> access it via vma->vm_mm.
>>
>> This commit makes the required powerpc modifications. Separate commits
>> update the other arches and core code, before the actual bug is fixed in
>> arm64.
>>
>> No behavioral changes intended.
> 
> This patch doesn't build, allthough I have also applied patch 1. Is
> something missing ?
> 
>     CALL    scripts/checksyscalls.sh
>     CC      arch/powerpc/kernel/setup-common.o
> In file included from arch/powerpc/kernel/setup-common.c:37:
> ./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
> ./include/linux/hugetlb.h:987:28: error: passing argument 1 of
> 'set_huge_pte_at' from incompatible pointer type
> [-Werror=incompatible-pointer-types]
>     987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>         |                         ~~~^~~~~~~
>         |                            |
>         |                            struct mm_struct *
> In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
>                    from ./include/linux/hugetlb.h:815:
> ./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected
> 'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
>      49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long
> addr, pte_t *ptep, pte_t pte);
>         |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
> cc1: all warnings being treated as errors
> make[4]: *** [scripts/Makefile.build:243:

Oh, I realised that it requires patch 6 to build properly. This is not 
good. Your series should be bisectable, that means it must build and run 
successfully after each patch. Therefore you have to squash patches 1 to 
7 all togethers.

I'll send you comments on the powerpc part in another mail.

Christophe

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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:20 ` [PATCH v1 2/8] powerpc: " Ryan Roberts
  2023-09-21 18:43   ` Christophe Leroy
@ 2023-09-22  6:56   ` Christophe Leroy
  2023-09-22  7:33     ` Ryan Roberts
  1 sibling, 1 reply; 31+ messages in thread
From: Christophe Leroy @ 2023-09-22  6:56 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable



Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
> In order to fix a bug, arm64 needs access to the vma inside it's
> implementation of set_huge_pte_at(). Provide for this by converting the
> mm parameter to be a vma. Any implementations that require the mm can
> access it via vma->vm_mm.
> 
> This commit makes the required powerpc modifications. Separate commits
> update the other arches and core code, before the actual bug is fixed in
> arm64.
> 
> No behavioral changes intended.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> ---
>   arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 3 ++-
>   arch/powerpc/mm/book3s64/hugetlbpage.c           | 2 +-
>   arch/powerpc/mm/book3s64/radix_hugetlbpage.c     | 2 +-
>   arch/powerpc/mm/nohash/8xx.c                     | 2 +-
>   arch/powerpc/mm/pgtable.c                        | 7 ++++++-
>   5 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> index de092b04ee1a..fff8cd726bc7 100644
> --- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift)
>   }
>   
>   #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte);
> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);

Don't add the burden of an additional function, see below

>   
>   #define __HAVE_ARCH_HUGE_PTE_CLEAR
>   static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
> diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
> index 3bc0eb21b2a0..ae7fd7c90eb8 100644
> --- a/arch/powerpc/mm/book3s64/hugetlbpage.c
> +++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
> @@ -147,7 +147,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
>   	if (radix_enabled())
>   		return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
>   							   old_pte, pte);
> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> +	set_huge_pte_at(vma, addr, ptep, pte);
>   }
>   
>   void __init hugetlbpage_init_defaultsize(void)
> diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
> index 17075c78d4bc..7cd40a334c3a 100644
> --- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
> +++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
> @@ -58,5 +58,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
>   	    atomic_read(&mm->context.copros) > 0)
>   		radix__flush_hugetlb_page(vma, addr);
>   
> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> +	set_huge_pte_at(vma, addr, ptep, pte);
>   }
> diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
> index dbbfe897455d..650a7a8496b6 100644
> --- a/arch/powerpc/mm/nohash/8xx.c
> +++ b/arch/powerpc/mm/nohash/8xx.c
> @@ -91,7 +91,7 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
>   	if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
>   		return -EINVAL;
>   
> -	set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
> +	__set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));

Call set_huge_pte_at() with a NULL vma instead.

>   
>   	return 0;
>   }
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index 3f86fd217690..9cbcb561a4d8 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -288,7 +288,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>   }
>   
>   #if defined(CONFIG_PPC_8xx)
> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)

Keep it as set_huge_pte_at() with vma argument.

>   {
>   	pmd_t *pmd = pmd_off(mm, addr);

Change to:

	pmd_t *pmd = vma ? pmd_off(vma->vm_mm, addr) : pmd_off_k(addr);

>   	pte_basic_t val;
> @@ -310,6 +310,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
>   	for (i = 0; i < num; i++, entry++, val += SZ_4K)
>   		*entry = val;
>   }
> +
> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte)
> +{
> +	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> +}

Remove this burden.

>   #endif
>   #endif /* CONFIG_HUGETLB_PAGE */
>   


Christophe

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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  6:44     ` Christophe Leroy
@ 2023-09-22  7:19       ` Ryan Roberts
  0 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  7:19 UTC (permalink / raw)
  To: Christophe Leroy, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens,
	Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
	Sven Schnelle, Gerald Schaefer, David S. Miller, Arnd Bergmann,
	Mike Kravetz, Muchun Song, SeongJae Park, Andrew Morton,
	Uladzislau Rezki, Christoph Hellwig, Lorenzo Stoakes,
	Anshuman Khandual, Peter Xu, Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

On 22/09/2023 07:44, Christophe Leroy wrote:
> 
> 
> Le 21/09/2023 à 20:43, Christophe Leroy a écrit :
>>
>>
>> Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
>>> In order to fix a bug, arm64 needs access to the vma inside it's
>>> implementation of set_huge_pte_at(). Provide for this by converting the
>>> mm parameter to be a vma. Any implementations that require the mm can
>>> access it via vma->vm_mm.
>>>
>>> This commit makes the required powerpc modifications. Separate commits
>>> update the other arches and core code, before the actual bug is fixed in
>>> arm64.
>>>
>>> No behavioral changes intended.
>>
>> This patch doesn't build, allthough I have also applied patch 1. Is
>> something missing ?
>>
>>     CALL    scripts/checksyscalls.sh
>>     CC      arch/powerpc/kernel/setup-common.o
>> In file included from arch/powerpc/kernel/setup-common.c:37:
>> ./include/linux/hugetlb.h: In function 'huge_ptep_modify_prot_commit':
>> ./include/linux/hugetlb.h:987:28: error: passing argument 1 of
>> 'set_huge_pte_at' from incompatible pointer type
>> [-Werror=incompatible-pointer-types]
>>     987 |         set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>         |                         ~~~^~~~~~~
>>         |                            |
>>         |                            struct mm_struct *
>> In file included from ./arch/powerpc/include/asm/hugetlb.h:13,
>>                    from ./include/linux/hugetlb.h:815:
>> ./arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h:49:45: note: expected
>> 'struct vm_area_struct *' but argument is of type 'struct mm_struct *'
>>      49 | void set_huge_pte_at(struct vm_area_struct *vma, unsigned long
>> addr, pte_t *ptep, pte_t pte);
>>         |                      ~~~~~~~~~~~~~~~~~~~~~~~^~~
>> cc1: all warnings being treated as errors
>> make[4]: *** [scripts/Makefile.build:243:
> 
> Oh, I realised that it requires patch 6 to build properly. This is not 
> good. Your series should be bisectable, that means it must build and run 
> successfully after each patch. Therefore you have to squash patches 1 to 
> 7 all togethers.

Yeah my bad - sorry about that. I thought it would be better to separate the
changes for each arch. But as already suggested by Andrew and Catalin, I'll
squash the first 7 patches into 1 for v2.

> 
> I'll send you comments on the powerpc part in another mail.
> 
> Christophe



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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  6:56   ` Christophe Leroy
@ 2023-09-22  7:33     ` Ryan Roberts
  2023-09-22  8:10       ` Christophe Leroy
  0 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  7:33 UTC (permalink / raw)
  To: Christophe Leroy, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens,
	Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
	Sven Schnelle, Gerald Schaefer, David S. Miller, Arnd Bergmann,
	Mike Kravetz, Muchun Song, SeongJae Park, Andrew Morton,
	Uladzislau Rezki, Christoph Hellwig, Lorenzo Stoakes,
	Anshuman Khandual, Peter Xu, Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

On 22/09/2023 07:56, Christophe Leroy wrote:
> 
> 
> Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
>> In order to fix a bug, arm64 needs access to the vma inside it's
>> implementation of set_huge_pte_at(). Provide for this by converting the
>> mm parameter to be a vma. Any implementations that require the mm can
>> access it via vma->vm_mm.
>>
>> This commit makes the required powerpc modifications. Separate commits
>> update the other arches and core code, before the actual bug is fixed in
>> arm64.
>>
>> No behavioral changes intended.
>>
>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>> ---
>>   arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 3 ++-
>>   arch/powerpc/mm/book3s64/hugetlbpage.c           | 2 +-
>>   arch/powerpc/mm/book3s64/radix_hugetlbpage.c     | 2 +-
>>   arch/powerpc/mm/nohash/8xx.c                     | 2 +-
>>   arch/powerpc/mm/pgtable.c                        | 7 ++++++-
>>   5 files changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>> index de092b04ee1a..fff8cd726bc7 100644
>> --- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>> +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>> @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift)
>>   }
>>   
>>   #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte);
>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
> 
> Don't add the burden of an additional function, see below
> 
>>   
>>   #define __HAVE_ARCH_HUGE_PTE_CLEAR
>>   static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>> diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
>> index 3bc0eb21b2a0..ae7fd7c90eb8 100644
>> --- a/arch/powerpc/mm/book3s64/hugetlbpage.c
>> +++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
>> @@ -147,7 +147,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
>>   	if (radix_enabled())
>>   		return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
>>   							   old_pte, pte);
>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>   }
>>   
>>   void __init hugetlbpage_init_defaultsize(void)
>> diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>> index 17075c78d4bc..7cd40a334c3a 100644
>> --- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>> +++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>> @@ -58,5 +58,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
>>   	    atomic_read(&mm->context.copros) > 0)
>>   		radix__flush_hugetlb_page(vma, addr);
>>   
>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>   }
>> diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
>> index dbbfe897455d..650a7a8496b6 100644
>> --- a/arch/powerpc/mm/nohash/8xx.c
>> +++ b/arch/powerpc/mm/nohash/8xx.c
>> @@ -91,7 +91,7 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
>>   	if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
>>   		return -EINVAL;
>>   
>> -	set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
>> +	__set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
> 
> Call set_huge_pte_at() with a NULL vma instead.

I'm happy to take your proposed approach if that's your preference. Another
option is to use a dummy VMA, as I have done in the core code, for the one call
site that calls set_huge_pte_at() with init_mm:

struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);

This is an existing macro that creates a dummy vma with vma->vm_mm filled in.
Then I pass &vma to the function.

Or yet another option would be to keep the mm param as is in set_huge_pte_at(),
and add a size param to the function. But then all call sites have the burden of
figuring out the size of the huge pte (although I think most know already).

Thanks,
Ryan

> 
>>   
>>   	return 0;
>>   }
>> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
>> index 3f86fd217690..9cbcb561a4d8 100644
>> --- a/arch/powerpc/mm/pgtable.c
>> +++ b/arch/powerpc/mm/pgtable.c
>> @@ -288,7 +288,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>>   }
>>   
>>   #if defined(CONFIG_PPC_8xx)
>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
> 
> Keep it as set_huge_pte_at() with vma argument.
> 
>>   {
>>   	pmd_t *pmd = pmd_off(mm, addr);
> 
> Change to:
> 
> 	pmd_t *pmd = vma ? pmd_off(vma->vm_mm, addr) : pmd_off_k(addr);
> 
>>   	pte_basic_t val;
>> @@ -310,6 +310,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
>>   	for (i = 0; i < num; i++, entry++, val += SZ_4K)
>>   		*entry = val;
>>   }
>> +
>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte)
>> +{
>> +	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>> +}
> 
> Remove this burden.
> 
>>   #endif
>>   #endif /* CONFIG_HUGETLB_PAGE */
>>   
> 
> 
> Christophe



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

* Re: [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-22  2:54   ` Qi Zheng
@ 2023-09-22  7:40     ` Ryan Roberts
  2023-09-22  7:54       ` Qi Zheng
  0 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  7:40 UTC (permalink / raw)
  To: Qi Zheng
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

On 22/09/2023 03:54, Qi Zheng wrote:
> Hi Ryan,
> 
> On 2023/9/22 00:20, Ryan Roberts wrote:
>> When called with a swap entry that does not embed a PFN (e.g.
>> PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
>> of set_huge_pte_at() would either cause a BUG() to fire (if
>> CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
>> and subsequent panic.
>>
>> arm64's huge pte implementation supports multiple huge page sizes, some
>> of which are implemented in the page table with contiguous mappings. So
>> set_huge_pte_at() needs to work out how big the logical pte is, so that
>> it can also work out how many physical ptes (or pmds) need to be
>> written. It does this by grabbing the folio out of the pte and querying
>> its size.
>>
>> However, there are cases when the pte being set is actually a swap
>> entry. But this also used to work fine, because for huge ptes, we only
>> ever saw migration entries and hwpoison entries. And both of these types
>> of swap entries have a PFN embedded, so the code would grab that and
>> everything still worked out.
>>
>> But over time, more calls to set_huge_pte_at() have been added that set
>> swap entry types that do not embed a PFN. And this causes the code to go
>> bang. The triggering case is for the uffd poison test, commit
>> 99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
>> which sets a PTE_MARKER_POISONED swap entry. But review shows there are
>> other places too (PTE_MARKER_UFFD_WP).
>>
>> So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
>> set_huge_swap_pte_at()"), which aimed to simplify the interface to the
>> core code by removing set_huge_swap_pte_at() (which took a page size
>> parameter) and replacing it with calls to set_huge_swap_pte_at() where
>> the size was inferred from the folio, as descibed above. While that
>> commit didn't break anything at the time, 
> 
> If it didn't break anything at that time, then shouldn't the Fixes tag
> be added to this commit?
> 
>> it did break the interface
>> because it couldn't handle swap entries without PFNs. And since then new
>> callers have come along which rely on this working.
> 
> So the Fixes tag should be added only to the commit that introduces the
> first new callers?

Well I guess it's a matter of point of view; My view is that 18f3962953e4 is the
buggy change because it broke the interface to not be able to handle swap
entries which do not contain PFNs. The fact that there were no callers that used
the interface in this way at the time of the commit is irrelevant in my view.
But I already added 2 fixes tags; one for the buggy commit, and the other for
the commit containing the new user of the interface.

> 
> Other than that, LGTM.

Thanks!

> 
> Thanks,
> Qi
> 
>>
>> Now that we have modified the set_huge_pte_at() interface to pass the
>> vma, we can extract the huge page size from it and fix this issue.
>>
>> I'm tagging the commit that added the uffd poison feature, since that is
>> what exposed the problem, as well as the original change that broke the
>> interface. Hopefully this is valuable for people doing bisect.
>>
>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>> Fixes: 18f3962953e4 ("mm: hugetlb: kill set_huge_swap_pte_at()")
>> Fixes: 8a13897fb0da ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs")
>> ---
>>   arch/arm64/mm/hugetlbpage.c | 17 +++--------------
>>   1 file changed, 3 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
>> index 844832511c1e..a08601a14689 100644
>> --- a/arch/arm64/mm/hugetlbpage.c
>> +++ b/arch/arm64/mm/hugetlbpage.c
>> @@ -241,13 +241,6 @@ static void clear_flush(struct mm_struct *mm,
>>       flush_tlb_range(&vma, saddr, addr);
>>   }
>>   -static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
>> -{
>> -    VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
>> -
>> -    return page_folio(pfn_to_page(swp_offset_pfn(entry)));
>> -}
>> -
>>   void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
>>                   pte_t *ptep, pte_t pte)
>>   {
>> @@ -258,13 +251,10 @@ void set_huge_pte_at(struct vm_area_struct *vma,
>> unsigned long addr,
>>       unsigned long pfn, dpfn;
>>       pgprot_t hugeprot;
>>   -    if (!pte_present(pte)) {
>> -        struct folio *folio;
>> -
>> -        folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
>> -        ncontig = num_contig_ptes(folio_size(folio), &pgsize);
>> +    ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize);
>>   -        for (i = 0; i < ncontig; i++, ptep++)
>> +    if (!pte_present(pte)) {
>> +        for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
>>               set_pte_at(mm, addr, ptep, pte);
>>           return;
>>       }
>> @@ -274,7 +264,6 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned
>> long addr,
>>           return;
>>       }
>>   -    ncontig = find_num_contig(mm, addr, ptep, &pgsize);
>>       pfn = pte_pfn(pte);
>>       dpfn = pgsize >> PAGE_SHIFT;
>>       hugeprot = pte_pgprot(pte);



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

* Re: [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
  2023-09-21 17:38     ` Catalin Marinas
@ 2023-09-22  7:41       ` Ryan Roberts
  0 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  7:41 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andrew Morton, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, Anshuman Khandual, Peter Xu, Axel Rasmussen,
	Qi Zheng, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable, Greg Kroah-Hartman

On 21/09/2023 18:38, Catalin Marinas wrote:
> On Thu, Sep 21, 2023 at 05:35:54PM +0100, Ryan Roberts wrote:
>> On 21/09/2023 17:30, Andrew Morton wrote:
>>> On Thu, 21 Sep 2023 17:19:59 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:
>>>> Ryan Roberts (8):
>>>>   parisc: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   powerpc: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   riscv: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   s390: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   sparc: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   mm: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   arm64: hugetlb: Convert set_huge_pte_at() to take vma
>>>>   arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
>>>>
>>>>  arch/arm64/include/asm/hugetlb.h              |  2 +-
>>>>  arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
>>>>  arch/parisc/include/asm/hugetlb.h             |  2 +-
>>>>  arch/parisc/mm/hugetlbpage.c                  |  4 +--
>>>>  .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
>>>>  arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
>>>>  arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
>>>>  arch/powerpc/mm/nohash/8xx.c                  |  2 +-
>>>>  arch/powerpc/mm/pgtable.c                     |  7 ++++-
>>>>  arch/riscv/include/asm/hugetlb.h              |  2 +-
>>>>  arch/riscv/mm/hugetlbpage.c                   |  3 +-
>>>>  arch/s390/include/asm/hugetlb.h               |  8 +++--
>>>>  arch/s390/mm/hugetlbpage.c                    |  8 ++++-
>>>>  arch/sparc/include/asm/hugetlb.h              |  8 +++--
>>>>  arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
>>>>  include/asm-generic/hugetlb.h                 |  6 ++--
>>>>  include/linux/hugetlb.h                       |  6 ++--
>>>>  mm/damon/vaddr.c                              |  2 +-
>>>>  mm/hugetlb.c                                  | 30 +++++++++----------
>>>>  mm/migrate.c                                  |  2 +-
>>>>  mm/rmap.c                                     | 10 +++----
>>>>  mm/vmalloc.c                                  |  5 +++-
>>>>  22 files changed, 80 insertions(+), 64 deletions(-)
>>>
>>> Looks scary but it's actually a fairly modest patchset.  It could
>>> easily be all rolled into a single patch for ease of backporting. 
>>> Maybe Greg has an opinion?
>>
>> Yes, I thought about doing that; or perhaps 2 patches - one for the interface
>> change across all arches and core code, and one for the actual bug fix?
> 
> I think this would make more sense, especially if we want to backport
> it. The first patch would have no functional change, only an interface
> change, followed by the arm64 fix.

OK I'll do it like this for v2.

> 



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

* Re: [PATCH v1 3/8] riscv: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-21 16:20 ` [PATCH v1 3/8] riscv: " Ryan Roberts
@ 2023-09-22  7:54   ` Alexandre Ghiti
  2023-09-22  8:36     ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Alexandre Ghiti @ 2023-09-22  7:54 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Christophe Leroy, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Heiko Carstens, Vasily Gorbik,
	Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
	Gerald Schaefer, David S. Miller, Arnd Bergmann, Mike Kravetz,
	Muchun Song, SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

Hi Ryan,

On 21/09/2023 18:20, Ryan Roberts wrote:
> In order to fix a bug, arm64 needs access to the vma inside it's
> implementation of set_huge_pte_at(). Provide for this by converting the
> mm parameter to be a vma. Any implementations that require the mm can
> access it via vma->vm_mm.
>
> This commit makes the required riscv modifications. Separate commits
> update the other arches and core code, before the actual bug is fixed in
> arm64.
>
> No behavioral changes intended.
>
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> ---
>   arch/riscv/include/asm/hugetlb.h | 2 +-
>   arch/riscv/mm/hugetlbpage.c      | 3 ++-
>   2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
> index 34e24f078cc1..be1ac8582bc2 100644
> --- a/arch/riscv/include/asm/hugetlb.h
> +++ b/arch/riscv/include/asm/hugetlb.h
> @@ -17,7 +17,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>   		    pte_t *ptep, unsigned long sz);
>   
>   #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
> -void set_huge_pte_at(struct mm_struct *mm,
> +void set_huge_pte_at(struct vm_area_struct *vma,
>   		     unsigned long addr, pte_t *ptep, pte_t pte);
>   
>   #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
> diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
> index 96225a8533ad..7cdbf0960772 100644
> --- a/arch/riscv/mm/hugetlbpage.c
> +++ b/arch/riscv/mm/hugetlbpage.c
> @@ -177,11 +177,12 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
>   	return entry;
>   }
>   
> -void set_huge_pte_at(struct mm_struct *mm,
> +void set_huge_pte_at(struct vm_area_struct *vma,
>   		     unsigned long addr,
>   		     pte_t *ptep,
>   		     pte_t pte)
>   {
> +	struct mm_struct *mm = vma->vm_mm;
>   	int i, pte_num;
>   
>   	if (!pte_napot(pte)) {


You can add:

Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>

I realize that we may have the same issue with our contig pte 
implementation (called napot in riscv) as we don't handle swap/migration 
entries at all. So I guess we need something similar, and I'll implement 
it (unless you want to do it of course, but I guess it's easier for me 
to test). One (maybe stupid) question though: wouldn't it be possible to 
extract the contig pte size from the value of ptep instead of using a vma?

Thanks,

Alex



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

* Re: [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-22  7:40     ` Ryan Roberts
@ 2023-09-22  7:54       ` Qi Zheng
  2023-09-22  9:35         ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Qi Zheng @ 2023-09-22  7:54 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

Hi Ryan,

On 2023/9/22 15:40, Ryan Roberts wrote:
> On 22/09/2023 03:54, Qi Zheng wrote:
>> Hi Ryan,
>>
>> On 2023/9/22 00:20, Ryan Roberts wrote:
>>> When called with a swap entry that does not embed a PFN (e.g.
>>> PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
>>> of set_huge_pte_at() would either cause a BUG() to fire (if
>>> CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
>>> and subsequent panic.
>>>
>>> arm64's huge pte implementation supports multiple huge page sizes, some
>>> of which are implemented in the page table with contiguous mappings. So
>>> set_huge_pte_at() needs to work out how big the logical pte is, so that
>>> it can also work out how many physical ptes (or pmds) need to be
>>> written. It does this by grabbing the folio out of the pte and querying
>>> its size.
>>>
>>> However, there are cases when the pte being set is actually a swap
>>> entry. But this also used to work fine, because for huge ptes, we only
>>> ever saw migration entries and hwpoison entries. And both of these types
>>> of swap entries have a PFN embedded, so the code would grab that and
>>> everything still worked out.
>>>
>>> But over time, more calls to set_huge_pte_at() have been added that set
>>> swap entry types that do not embed a PFN. And this causes the code to go
>>> bang. The triggering case is for the uffd poison test, commit
>>> 99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
>>> which sets a PTE_MARKER_POISONED swap entry. But review shows there are
>>> other places too (PTE_MARKER_UFFD_WP).
>>>
>>> So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
>>> set_huge_swap_pte_at()"), which aimed to simplify the interface to the
>>> core code by removing set_huge_swap_pte_at() (which took a page size
>>> parameter) and replacing it with calls to set_huge_swap_pte_at() where
>>> the size was inferred from the folio, as descibed above. While that
>>> commit didn't break anything at the time,
>>
>> If it didn't break anything at that time, then shouldn't the Fixes tag
>> be added to this commit?
>>
>>> it did break the interface
>>> because it couldn't handle swap entries without PFNs. And since then new
>>> callers have come along which rely on this working.
>>
>> So the Fixes tag should be added only to the commit that introduces the
>> first new callers?
> 
> Well I guess it's a matter of point of view; My view is that 18f3962953e4 is the
> buggy change because it broke the interface to not be able to handle swap
> entries which do not contain PFNs. The fact that there were no callers that used
> the interface in this way at the time of the commit is irrelevant in my view.

I understand your point of view.

But IIUC, the Fixes tag is used to indicate the version that needs to
backport, but the version where the commit 18f3962953e4 is located
does not need to backport this bugfix patch.

> But I already added 2 fixes tags; one for the buggy commit, and the other for
> the commit containing the new user of the interface.

I think 2 fixes tags will cause inconvenience to the maintainers.

Thanks,
Qi

> 
>>
>> Other than that, LGTM.
> 
> Thanks!
> 
>>
>> Thanks,
>> Qi
>>
>>>
>>> Now that we have modified the set_huge_pte_at() interface to pass the
>>> vma, we can extract the huge page size from it and fix this issue.
>>>
>>> I'm tagging the commit that added the uffd poison feature, since that is
>>> what exposed the problem, as well as the original change that broke the
>>> interface. Hopefully this is valuable for people doing bisect.
>>>
>>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>>> Fixes: 18f3962953e4 ("mm: hugetlb: kill set_huge_swap_pte_at()")
>>> Fixes: 8a13897fb0da ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs")
>>> ---
>>>    arch/arm64/mm/hugetlbpage.c | 17 +++--------------
>>>    1 file changed, 3 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
>>> index 844832511c1e..a08601a14689 100644
>>> --- a/arch/arm64/mm/hugetlbpage.c
>>> +++ b/arch/arm64/mm/hugetlbpage.c
>>> @@ -241,13 +241,6 @@ static void clear_flush(struct mm_struct *mm,
>>>        flush_tlb_range(&vma, saddr, addr);
>>>    }
>>>    -static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
>>> -{
>>> -    VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
>>> -
>>> -    return page_folio(pfn_to_page(swp_offset_pfn(entry)));
>>> -}
>>> -
>>>    void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr,
>>>                    pte_t *ptep, pte_t pte)
>>>    {
>>> @@ -258,13 +251,10 @@ void set_huge_pte_at(struct vm_area_struct *vma,
>>> unsigned long addr,
>>>        unsigned long pfn, dpfn;
>>>        pgprot_t hugeprot;
>>>    -    if (!pte_present(pte)) {
>>> -        struct folio *folio;
>>> -
>>> -        folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
>>> -        ncontig = num_contig_ptes(folio_size(folio), &pgsize);
>>> +    ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize);
>>>    -        for (i = 0; i < ncontig; i++, ptep++)
>>> +    if (!pte_present(pte)) {
>>> +        for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
>>>                set_pte_at(mm, addr, ptep, pte);
>>>            return;
>>>        }
>>> @@ -274,7 +264,6 @@ void set_huge_pte_at(struct vm_area_struct *vma, unsigned
>>> long addr,
>>>            return;
>>>        }
>>>    -    ncontig = find_num_contig(mm, addr, ptep, &pgsize);
>>>        pfn = pte_pfn(pte);
>>>        dpfn = pgsize >> PAGE_SHIFT;
>>>        hugeprot = pte_pgprot(pte);
> 


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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  7:33     ` Ryan Roberts
@ 2023-09-22  8:10       ` Christophe Leroy
  2023-09-22  8:41         ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Christophe Leroy @ 2023-09-22  8:10 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable



Le 22/09/2023 à 09:33, Ryan Roberts a écrit :
> On 22/09/2023 07:56, Christophe Leroy wrote:
>>
>>
>> Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
>>> In order to fix a bug, arm64 needs access to the vma inside it's
>>> implementation of set_huge_pte_at(). Provide for this by converting the
>>> mm parameter to be a vma. Any implementations that require the mm can
>>> access it via vma->vm_mm.
>>>
>>> This commit makes the required powerpc modifications. Separate commits
>>> update the other arches and core code, before the actual bug is fixed in
>>> arm64.
>>>
>>> No behavioral changes intended.
>>>
>>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>>> ---
>>>    arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 3 ++-
>>>    arch/powerpc/mm/book3s64/hugetlbpage.c           | 2 +-
>>>    arch/powerpc/mm/book3s64/radix_hugetlbpage.c     | 2 +-
>>>    arch/powerpc/mm/nohash/8xx.c                     | 2 +-
>>>    arch/powerpc/mm/pgtable.c                        | 7 ++++++-
>>>    5 files changed, 11 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>> index de092b04ee1a..fff8cd726bc7 100644
>>> --- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>> +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>> @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift)
>>>    }
>>>    
>>>    #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
>>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
>>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte);
>>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
>>
>> Don't add the burden of an additional function, see below
>>
>>>    
>>>    #define __HAVE_ARCH_HUGE_PTE_CLEAR
>>>    static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>>> diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
>>> index 3bc0eb21b2a0..ae7fd7c90eb8 100644
>>> --- a/arch/powerpc/mm/book3s64/hugetlbpage.c
>>> +++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
>>> @@ -147,7 +147,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
>>>    	if (radix_enabled())
>>>    		return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
>>>    							   old_pte, pte);
>>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>>    }
>>>    
>>>    void __init hugetlbpage_init_defaultsize(void)
>>> diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>> index 17075c78d4bc..7cd40a334c3a 100644
>>> --- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>> +++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>> @@ -58,5 +58,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
>>>    	    atomic_read(&mm->context.copros) > 0)
>>>    		radix__flush_hugetlb_page(vma, addr);
>>>    
>>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>>    }
>>> diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
>>> index dbbfe897455d..650a7a8496b6 100644
>>> --- a/arch/powerpc/mm/nohash/8xx.c
>>> +++ b/arch/powerpc/mm/nohash/8xx.c
>>> @@ -91,7 +91,7 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
>>>    	if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
>>>    		return -EINVAL;
>>>    
>>> -	set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
>>> +	__set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
>>
>> Call set_huge_pte_at() with a NULL vma instead.
> 
> I'm happy to take your proposed approach if that's your preference. Another
> option is to use a dummy VMA, as I have done in the core code, for the one call
> site that calls set_huge_pte_at() with init_mm:
> 
> struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
> 
> This is an existing macro that creates a dummy vma with vma->vm_mm filled in.
> Then I pass &vma to the function.

I don't like that, I prefer the solution I proposed. We already have a 
couple places where powerpc do things based on whether vma is NULL or not.

> 
> Or yet another option would be to keep the mm param as is in set_huge_pte_at(),
> and add a size param to the function. But then all call sites have the burden of
> figuring out the size of the huge pte (although I think most know already).

Indeed.

arch_make_huge_pte() used to take a vma until commit 79c1c594f49a 
("mm/hugetlb: change parameters of arch_make_huge_pte()").

Should we try and have the same approach ? Or is it irrelevant ?

Christophe

> 
> Thanks,
> Ryan
> 
>>
>>>    
>>>    	return 0;
>>>    }
>>> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
>>> index 3f86fd217690..9cbcb561a4d8 100644
>>> --- a/arch/powerpc/mm/pgtable.c
>>> +++ b/arch/powerpc/mm/pgtable.c
>>> @@ -288,7 +288,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>>>    }
>>>    
>>>    #if defined(CONFIG_PPC_8xx)
>>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
>>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
>>
>> Keep it as set_huge_pte_at() with vma argument.
>>
>>>    {
>>>    	pmd_t *pmd = pmd_off(mm, addr);
>>
>> Change to:
>>
>> 	pmd_t *pmd = vma ? pmd_off(vma->vm_mm, addr) : pmd_off_k(addr);
>>
>>>    	pte_basic_t val;
>>> @@ -310,6 +310,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
>>>    	for (i = 0; i < num; i++, entry++, val += SZ_4K)
>>>    		*entry = val;
>>>    }
>>> +
>>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte)
>>> +{
>>> +	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>> +}
>>
>> Remove this burden.
>>
>>>    #endif
>>>    #endif /* CONFIG_HUGETLB_PAGE */
>>>    
>>
>>
>> Christophe
> 

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

* Re: [PATCH v1 3/8] riscv: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  7:54   ` Alexandre Ghiti
@ 2023-09-22  8:36     ` Ryan Roberts
  0 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  8:36 UTC (permalink / raw)
  To: Alexandre Ghiti, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Christophe Leroy, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

On 22/09/2023 08:54, Alexandre Ghiti wrote:
> Hi Ryan,
> 
> On 21/09/2023 18:20, Ryan Roberts wrote:
>> In order to fix a bug, arm64 needs access to the vma inside it's
>> implementation of set_huge_pte_at(). Provide for this by converting the
>> mm parameter to be a vma. Any implementations that require the mm can
>> access it via vma->vm_mm.
>>
>> This commit makes the required riscv modifications. Separate commits
>> update the other arches and core code, before the actual bug is fixed in
>> arm64.
>>
>> No behavioral changes intended.
>>
>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>> ---
>>   arch/riscv/include/asm/hugetlb.h | 2 +-
>>   arch/riscv/mm/hugetlbpage.c      | 3 ++-
>>   2 files changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
>> index 34e24f078cc1..be1ac8582bc2 100644
>> --- a/arch/riscv/include/asm/hugetlb.h
>> +++ b/arch/riscv/include/asm/hugetlb.h
>> @@ -17,7 +17,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>>               pte_t *ptep, unsigned long sz);
>>     #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
>> -void set_huge_pte_at(struct mm_struct *mm,
>> +void set_huge_pte_at(struct vm_area_struct *vma,
>>                unsigned long addr, pte_t *ptep, pte_t pte);
>>     #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
>> diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
>> index 96225a8533ad..7cdbf0960772 100644
>> --- a/arch/riscv/mm/hugetlbpage.c
>> +++ b/arch/riscv/mm/hugetlbpage.c
>> @@ -177,11 +177,12 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int
>> shift, vm_flags_t flags)
>>       return entry;
>>   }
>>   -void set_huge_pte_at(struct mm_struct *mm,
>> +void set_huge_pte_at(struct vm_area_struct *vma,
>>                unsigned long addr,
>>                pte_t *ptep,
>>                pte_t pte)
>>   {
>> +    struct mm_struct *mm = vma->vm_mm;
>>       int i, pte_num;
>>         if (!pte_napot(pte)) {
> 
> 
> You can add:
> 
> Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>

Thanks!

> 
> I realize that we may have the same issue with our contig pte implementation
> (called napot in riscv) as we don't handle swap/migration entries at all. So I
> guess we need something similar, and I'll implement it (unless you want to do it
> of course, but I guess it's easier for me to test). 

Yes -I'll leave you to do the riscv part.

> One (maybe stupid) question
> though: wouldn't it be possible to extract the contig pte size from the value of
> ptep instead of using a vma?

Not for arm64: We support contpmd, pmd and contpte entries as backing for the
logical huge pte, depending on size. So without the size, we can't distinguish
between a coincidentally-aligned pmd entry vs a contpmd entry (which is just a
fixed size block of pmd entries).

Discussion with Christophe on the powerpc patch triggered some thinking; There
is theoretical problem with my current approach because there is one call site
in the core code that calls set_huge_pte_at(&init_mm). I've changed that to:

  struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
  set_huge_pte_at(&vma);

knowing that this will never actually get called for arm64 because we return
PAGE_SIZE for arch_vmap_pte_range_map_size() and all other arches just take the
mm and ignore the rest of the vma. So it's safe, but fragile.

But it looks like riscv overrides arch_vmap_pte_range_map_size() and therefore
the call will be made there. And if riscv also needs to determine the size from
the vma, then bang.

So I'm going to rework it to continue to pass the mm in, but also add a size
parameter. Then it's totally safe. Will post a v2 later today.

Thanks,
Ryan

> 
> Thanks,
> 
> Alex
> 



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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  8:10       ` Christophe Leroy
@ 2023-09-22  8:41         ` Ryan Roberts
  2023-09-22  9:14           ` Christophe Leroy
  0 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  8:41 UTC (permalink / raw)
  To: Christophe Leroy, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens,
	Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
	Sven Schnelle, Gerald Schaefer, David S. Miller, Arnd Bergmann,
	Mike Kravetz, Muchun Song, SeongJae Park, Andrew Morton,
	Uladzislau Rezki, Christoph Hellwig, Lorenzo Stoakes,
	Anshuman Khandual, Peter Xu, Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

On 22/09/2023 09:10, Christophe Leroy wrote:
> 
> 
> Le 22/09/2023 à 09:33, Ryan Roberts a écrit :
>> On 22/09/2023 07:56, Christophe Leroy wrote:
>>>
>>>
>>> Le 21/09/2023 à 18:20, Ryan Roberts a écrit :
>>>> In order to fix a bug, arm64 needs access to the vma inside it's
>>>> implementation of set_huge_pte_at(). Provide for this by converting the
>>>> mm parameter to be a vma. Any implementations that require the mm can
>>>> access it via vma->vm_mm.
>>>>
>>>> This commit makes the required powerpc modifications. Separate commits
>>>> update the other arches and core code, before the actual bug is fixed in
>>>> arm64.
>>>>
>>>> No behavioral changes intended.
>>>>
>>>> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
>>>> ---
>>>>    arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 3 ++-
>>>>    arch/powerpc/mm/book3s64/hugetlbpage.c           | 2 +-
>>>>    arch/powerpc/mm/book3s64/radix_hugetlbpage.c     | 2 +-
>>>>    arch/powerpc/mm/nohash/8xx.c                     | 2 +-
>>>>    arch/powerpc/mm/pgtable.c                        | 7 ++++++-
>>>>    5 files changed, 11 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>>> index de092b04ee1a..fff8cd726bc7 100644
>>>> --- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>>> +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
>>>> @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift)
>>>>    }
>>>>    
>>>>    #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
>>>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
>>>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte);
>>>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
>>>
>>> Don't add the burden of an additional function, see below
>>>
>>>>    
>>>>    #define __HAVE_ARCH_HUGE_PTE_CLEAR
>>>>    static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>>>> diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
>>>> index 3bc0eb21b2a0..ae7fd7c90eb8 100644
>>>> --- a/arch/powerpc/mm/book3s64/hugetlbpage.c
>>>> +++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
>>>> @@ -147,7 +147,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
>>>>    	if (radix_enabled())
>>>>    		return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
>>>>    							   old_pte, pte);
>>>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>>>    }
>>>>    
>>>>    void __init hugetlbpage_init_defaultsize(void)
>>>> diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>>> index 17075c78d4bc..7cd40a334c3a 100644
>>>> --- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>>> +++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
>>>> @@ -58,5 +58,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
>>>>    	    atomic_read(&mm->context.copros) > 0)
>>>>    		radix__flush_hugetlb_page(vma, addr);
>>>>    
>>>> -	set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>>> +	set_huge_pte_at(vma, addr, ptep, pte);
>>>>    }
>>>> diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
>>>> index dbbfe897455d..650a7a8496b6 100644
>>>> --- a/arch/powerpc/mm/nohash/8xx.c
>>>> +++ b/arch/powerpc/mm/nohash/8xx.c
>>>> @@ -91,7 +91,7 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
>>>>    	if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
>>>>    		return -EINVAL;
>>>>    
>>>> -	set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
>>>> +	__set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)));
>>>
>>> Call set_huge_pte_at() with a NULL vma instead.
>>
>> I'm happy to take your proposed approach if that's your preference. Another
>> option is to use a dummy VMA, as I have done in the core code, for the one call
>> site that calls set_huge_pte_at() with init_mm:
>>
>> struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
>>
>> This is an existing macro that creates a dummy vma with vma->vm_mm filled in.
>> Then I pass &vma to the function.
> 
> I don't like that, I prefer the solution I proposed. We already have a 
> couple places where powerpc do things based on whether vma is NULL or not.
> 
>>
>> Or yet another option would be to keep the mm param as is in set_huge_pte_at(),
>> and add a size param to the function. But then all call sites have the burden of
>> figuring out the size of the huge pte (although I think most know already).
> 
> Indeed.
> 
> arch_make_huge_pte() used to take a vma until commit 79c1c594f49a 
> ("mm/hugetlb: change parameters of arch_make_huge_pte()").
> 
> Should we try and have the same approach ? Or is it irrelevant ?

See [1]; I'm going to rework to pass mm + size parameter since the current
approach will break riscv.

[1]
https://lore.kernel.org/linux-arm-kernel/fc85f58e-e8ed-4b24-a3e5-d6288156595e@arm.com/

> 
> Christophe
> 
>>
>> Thanks,
>> Ryan
>>
>>>
>>>>    
>>>>    	return 0;
>>>>    }
>>>> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
>>>> index 3f86fd217690..9cbcb561a4d8 100644
>>>> --- a/arch/powerpc/mm/pgtable.c
>>>> +++ b/arch/powerpc/mm/pgtable.c
>>>> @@ -288,7 +288,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>>>>    }
>>>>    
>>>>    #if defined(CONFIG_PPC_8xx)
>>>> -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
>>>> +void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
>>>
>>> Keep it as set_huge_pte_at() with vma argument.
>>>
>>>>    {
>>>>    	pmd_t *pmd = pmd_off(mm, addr);
>>>
>>> Change to:
>>>
>>> 	pmd_t *pmd = vma ? pmd_off(vma->vm_mm, addr) : pmd_off_k(addr);
>>>
>>>>    	pte_basic_t val;
>>>> @@ -310,6 +310,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
>>>>    	for (i = 0; i < num; i++, entry++, val += SZ_4K)
>>>>    		*entry = val;
>>>>    }
>>>> +
>>>> +void set_huge_pte_at(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte)
>>>> +{
>>>> +	__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
>>>> +}
>>>
>>> Remove this burden.
>>>
>>>>    #endif
>>>>    #endif /* CONFIG_HUGETLB_PAGE */
>>>>    
>>>
>>>
>>> Christophe
>>



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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  8:41         ` Ryan Roberts
@ 2023-09-22  9:14           ` Christophe Leroy
  2023-09-22  9:37             ` Ryan Roberts
  0 siblings, 1 reply; 31+ messages in thread
From: Christophe Leroy @ 2023-09-22  9:14 UTC (permalink / raw)
  To: Ryan Roberts, Catalin Marinas, Will Deacon, James E.J. Bottomley,
	Helge Deller, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable



Le 22/09/2023 à 10:41, Ryan Roberts a écrit :
> On 22/09/2023 09:10, Christophe Leroy wrote:
>>
>>
>>> I'm happy to take your proposed approach if that's your preference. Another
>>> option is to use a dummy VMA, as I have done in the core code, for the one call
>>> site that calls set_huge_pte_at() with init_mm:
>>>
>>> struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
>>>
>>> This is an existing macro that creates a dummy vma with vma->vm_mm filled in.
>>> Then I pass &vma to the function.
>>
>> I don't like that, I prefer the solution I proposed. We already have a
>> couple places where powerpc do things based on whether vma is NULL or not.
>>
>>>
>>> Or yet another option would be to keep the mm param as is in set_huge_pte_at(),
>>> and add a size param to the function. But then all call sites have the burden of
>>> figuring out the size of the huge pte (although I think most know already).
>>
>> Indeed.
>>
>> arch_make_huge_pte() used to take a vma until commit 79c1c594f49a
>> ("mm/hugetlb: change parameters of arch_make_huge_pte()").
>>
>> Should we try and have the same approach ? Or is it irrelevant ?
> 
> See [1]; I'm going to rework to pass mm + size parameter since the current
> approach will break riscv.

Can you pass a shift parameter instead of a size, like 
arch_make_huge_pte() ? As far as I remember it is easier to handle a 
shift than a size.

Christophe

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

* Re: [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64
  2023-09-21 16:35   ` Ryan Roberts
  2023-09-21 17:38     ` Catalin Marinas
@ 2023-09-22  9:23     ` Greg Kroah-Hartman
  1 sibling, 0 replies; 31+ messages in thread
From: Greg Kroah-Hartman @ 2023-09-22  9:23 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Andrew Morton, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Christophe Leroy, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, Anshuman Khandual, Peter Xu, Axel Rasmussen,
	Qi Zheng, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

On Thu, Sep 21, 2023 at 05:35:54PM +0100, Ryan Roberts wrote:
> On 21/09/2023 17:30, Andrew Morton wrote:
> > On Thu, 21 Sep 2023 17:19:59 +0100 Ryan Roberts <ryan.roberts@arm.com> wrote:
> > 
> >> Hi All,
> >>
> >> This series fixes a bug in arm64's implementation of set_huge_pte_at(), which
> >> can result in an unprivileged user causing a kernel panic. The problem was
> >> triggered when running the new uffd poison mm selftest for HUGETLB memory. This
> >> test (and the uffd poison feature) was merged for v6.6-rc1. However, upon
> >> inspection there are multiple other pre-existing paths that can trigger this
> >> bug.
> >>
> >> Ideally, I'd like to get this fix in for v6.6 if possible? And I guess it should
> >> be backported too, given there are call sites where this can theoretically
> >> happen that pre-date v6.6-rc1 (I've cc'ed stable@vger.kernel.org).
> > 
> > This gets you a naggygram from Greg.  The way to request a backport is
> > to add cc:stable to all the changelogs.  I'll make that change to my copy.
> 
> Ahh, sorry about that... I just got the same moan from the kernel test robot too.
> 
> > 
> > 
> >> Ryan Roberts (8):
> >>   parisc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   powerpc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   riscv: hugetlb: Convert set_huge_pte_at() to take vma
> >>   s390: hugetlb: Convert set_huge_pte_at() to take vma
> >>   sparc: hugetlb: Convert set_huge_pte_at() to take vma
> >>   mm: hugetlb: Convert set_huge_pte_at() to take vma
> >>   arm64: hugetlb: Convert set_huge_pte_at() to take vma
> >>   arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
> >>
> >>  arch/arm64/include/asm/hugetlb.h              |  2 +-
> >>  arch/arm64/mm/hugetlbpage.c                   | 22 ++++----------
> >>  arch/parisc/include/asm/hugetlb.h             |  2 +-
> >>  arch/parisc/mm/hugetlbpage.c                  |  4 +--
> >>  .../include/asm/nohash/32/hugetlb-8xx.h       |  3 +-
> >>  arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 +-
> >>  arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  2 +-
> >>  arch/powerpc/mm/nohash/8xx.c                  |  2 +-
> >>  arch/powerpc/mm/pgtable.c                     |  7 ++++-
> >>  arch/riscv/include/asm/hugetlb.h              |  2 +-
> >>  arch/riscv/mm/hugetlbpage.c                   |  3 +-
> >>  arch/s390/include/asm/hugetlb.h               |  8 +++--
> >>  arch/s390/mm/hugetlbpage.c                    |  8 ++++-
> >>  arch/sparc/include/asm/hugetlb.h              |  8 +++--
> >>  arch/sparc/mm/hugetlbpage.c                   |  8 ++++-
> >>  include/asm-generic/hugetlb.h                 |  6 ++--
> >>  include/linux/hugetlb.h                       |  6 ++--
> >>  mm/damon/vaddr.c                              |  2 +-
> >>  mm/hugetlb.c                                  | 30 +++++++++----------
> >>  mm/migrate.c                                  |  2 +-
> >>  mm/rmap.c                                     | 10 +++----
> >>  mm/vmalloc.c                                  |  5 +++-
> >>  22 files changed, 80 insertions(+), 64 deletions(-)
> > 
> > Looks scary but it's actually a fairly modest patchset.  It could
> > easily be all rolled into a single patch for ease of backporting. 
> > Maybe Greg has an opinion?
> 
> Yes, I thought about doing that; or perhaps 2 patches - one for the interface
> change across all arches and core code, and one for the actual bug fix?

I have no issues with taking patch series, or one big patch, into stable
trees, they just have to match up with what is in Linus's tree.

so if it makes more sense to have this as a series (like you did here),
wonderful, make it a patch series.  Do not go out of your way to do
things differently just for stable kernels, that is not necessary or
needed at all.

thanks,

greg k-h


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

* Re: [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-22  7:54       ` Qi Zheng
@ 2023-09-22  9:35         ` Ryan Roberts
  2023-09-22  9:58           ` Qi Zheng
  0 siblings, 1 reply; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  9:35 UTC (permalink / raw)
  To: Qi Zheng
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

On 22/09/2023 08:54, Qi Zheng wrote:
> Hi Ryan,
> 
> On 2023/9/22 15:40, Ryan Roberts wrote:
>> On 22/09/2023 03:54, Qi Zheng wrote:
>>> Hi Ryan,
>>>
>>> On 2023/9/22 00:20, Ryan Roberts wrote:
>>>> When called with a swap entry that does not embed a PFN (e.g.
>>>> PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
>>>> of set_huge_pte_at() would either cause a BUG() to fire (if
>>>> CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
>>>> and subsequent panic.
>>>>
>>>> arm64's huge pte implementation supports multiple huge page sizes, some
>>>> of which are implemented in the page table with contiguous mappings. So
>>>> set_huge_pte_at() needs to work out how big the logical pte is, so that
>>>> it can also work out how many physical ptes (or pmds) need to be
>>>> written. It does this by grabbing the folio out of the pte and querying
>>>> its size.
>>>>
>>>> However, there are cases when the pte being set is actually a swap
>>>> entry. But this also used to work fine, because for huge ptes, we only
>>>> ever saw migration entries and hwpoison entries. And both of these types
>>>> of swap entries have a PFN embedded, so the code would grab that and
>>>> everything still worked out.
>>>>
>>>> But over time, more calls to set_huge_pte_at() have been added that set
>>>> swap entry types that do not embed a PFN. And this causes the code to go
>>>> bang. The triggering case is for the uffd poison test, commit
>>>> 99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
>>>> which sets a PTE_MARKER_POISONED swap entry. But review shows there are
>>>> other places too (PTE_MARKER_UFFD_WP).
>>>>
>>>> So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
>>>> set_huge_swap_pte_at()"), which aimed to simplify the interface to the
>>>> core code by removing set_huge_swap_pte_at() (which took a page size
>>>> parameter) and replacing it with calls to set_huge_swap_pte_at() where
>>>> the size was inferred from the folio, as descibed above. While that
>>>> commit didn't break anything at the time,
>>>
>>> If it didn't break anything at that time, then shouldn't the Fixes tag
>>> be added to this commit?
>>>
>>>> it did break the interface
>>>> because it couldn't handle swap entries without PFNs. And since then new
>>>> callers have come along which rely on this working.
>>>
>>> So the Fixes tag should be added only to the commit that introduces the
>>> first new callers?
>>
>> Well I guess it's a matter of point of view; My view is that 18f3962953e4 is the
>> buggy change because it broke the interface to not be able to handle swap
>> entries which do not contain PFNs. The fact that there were no callers that used
>> the interface in this way at the time of the commit is irrelevant in my view.
> 
> I understand your point of view.
> 
> But IIUC, the Fixes tag is used to indicate the version that needs to
> backport, but the version where the commit 18f3962953e4 is located
> does not need to backport this bugfix patch.
> 
>> But I already added 2 fixes tags; one for the buggy commit, and the other for
>> the commit containing the new user of the interface.
> 
> I think 2 fixes tags will cause inconvenience to the maintainers.
> 

I did some Archaeology:

$ git rev-list --no-walk=sorted --pretty=oneline \
	05e90bd05eea33fc77d6b11e121e2da01fee379f \
	60dfaad65aa97fb6755b9798a6b3c9e79bcd5930 \
	8a13897fb0daa8f56821f263f0c63661e1c6acae \
	18f3962953e40401b7ed98e8524167282c3e626e \
	v6.5 v5.18 v5.17 v5.19 v6.5-rc6 v6.5-rc7

2dde18cd1d8fac735875f2e4987f11817cc0bc2c Linux 6.5
706a741595047797872e669b3101429ab8d378ef Linux 6.5-rc7
8a13897fb0daa8f56821f263f0c63661e1c6acae mm: userfaultfd: support UFFDIO_POISON for hugetlbfs
2ccdd1b13c591d306f0401d98dedc4bdcd02b421 Linux 6.5-rc6
3d7cb6b04c3f3115719235cc6866b10326de34cd Linux 5.19
18f3962953e40401b7ed98e8524167282c3e626e mm: hugetlb: kill set_huge_swap_pte_at()
4b0986a3613c92f4ec1bdc7f60ec66fea135991f Linux 5.18
05e90bd05eea33fc77d6b11e121e2da01fee379f mm/hugetlb: only drop uffd-wp special pte if required
60dfaad65aa97fb6755b9798a6b3c9e79bcd5930 mm/hugetlb: allow uffd wr-protect none ptes
f443e374ae131c168a065ea1748feac6b2e76613 Linux 5.17


So it turns out that the PTE_MARKER_UFFD_WP markers were added first, using 
set_huge_pte_at(). At the time, this should have used set_huge_swap_pte_at(), so 
was arguably buggy for that reason. However, arm64 does not support UFFD_WP so 
none of the call sites that set the PTE_MARKER_UFFD_WP marker to the pte ever 
trigger on arm64.

Then "mm: hugetlb: kill set_huge_swap_pte_at()" came along and "broke" the
interface, but there were no callers relying on the behavoir that was broken.

Then "mm: userfaultfd: support UFFDIO_POISON for hugetlbfs" came along in 
v6.5-rc7 and started relying on the broken behaviour of set_huge_pte_at().

So on that basis, I agree that the first commit where broken behaviour is 
observable is "mm: userfaultfd: support UFFDIO_POISON for hugetlbfs". So I will 
tag that one as "Fixes". (Although if set_huge_pte_at() was an exported symbol, 
then we would want to mark "mm: hugetlb: kill set_huge_swap_pte_at()").

Thanks,
Ryan




> Thanks,
> Qi
> 
>>
>>>
>>> Other than that, LGTM.
>>
>> Thanks!
>>
>>>
>>> Thanks,
>>> Qi
>>>


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

* Re: [PATCH v1 2/8] powerpc: hugetlb: Convert set_huge_pte_at() to take vma
  2023-09-22  9:14           ` Christophe Leroy
@ 2023-09-22  9:37             ` Ryan Roberts
  0 siblings, 0 replies; 31+ messages in thread
From: Ryan Roberts @ 2023-09-22  9:37 UTC (permalink / raw)
  To: Christophe Leroy, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Nicholas Piggin,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens,
	Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
	Sven Schnelle, Gerald Schaefer, David S. Miller, Arnd Bergmann,
	Mike Kravetz, Muchun Song, SeongJae Park, Andrew Morton,
	Uladzislau Rezki, Christoph Hellwig, Lorenzo Stoakes,
	Anshuman Khandual, Peter Xu, Axel Rasmussen, Qi Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
	linux-riscv, linux-s390, sparclinux, linux-mm, stable

On 22/09/2023 10:14, Christophe Leroy wrote:
> 
> 
> Le 22/09/2023 à 10:41, Ryan Roberts a écrit :
>> On 22/09/2023 09:10, Christophe Leroy wrote:
>>>
>>>
>>>> I'm happy to take your proposed approach if that's your preference. Another
>>>> option is to use a dummy VMA, as I have done in the core code, for the one call
>>>> site that calls set_huge_pte_at() with init_mm:
>>>>
>>>> struct vm_area_struct vma = TLB_FLUSH_VMA(&init_mm, 0);
>>>>
>>>> This is an existing macro that creates a dummy vma with vma->vm_mm filled in.
>>>> Then I pass &vma to the function.
>>>
>>> I don't like that, I prefer the solution I proposed. We already have a
>>> couple places where powerpc do things based on whether vma is NULL or not.
>>>
>>>>
>>>> Or yet another option would be to keep the mm param as is in set_huge_pte_at(),
>>>> and add a size param to the function. But then all call sites have the burden of
>>>> figuring out the size of the huge pte (although I think most know already).
>>>
>>> Indeed.
>>>
>>> arch_make_huge_pte() used to take a vma until commit 79c1c594f49a
>>> ("mm/hugetlb: change parameters of arch_make_huge_pte()").
>>>
>>> Should we try and have the same approach ? Or is it irrelevant ?
>>
>> See [1]; I'm going to rework to pass mm + size parameter since the current
>> approach will break riscv.
> 
> Can you pass a shift parameter instead of a size, like 
> arch_make_huge_pte() ? As far as I remember it is easier to handle a 
> shift than a size.

Most of the call sites already have the size, not the shift. And arm64 needs the
size, so it would have do (1UL << shift). So on that basis, I prefer to pass
size. huge_pte_clear() already passes long unsigned sz, so I'd rather follow
that pattern.

> 
> Christophe



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

* Re: [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries
  2023-09-22  9:35         ` Ryan Roberts
@ 2023-09-22  9:58           ` Qi Zheng
  0 siblings, 0 replies; 31+ messages in thread
From: Qi Zheng @ 2023-09-22  9:58 UTC (permalink / raw)
  To: Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	David S. Miller, Arnd Bergmann, Mike Kravetz, Muchun Song,
	SeongJae Park, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, Lorenzo Stoakes, Anshuman Khandual, Peter Xu,
	Axel Rasmussen, linux-arm-kernel, linux-kernel, linux-parisc,
	linuxppc-dev, linux-riscv, linux-s390, sparclinux, linux-mm,
	stable

Hi Ryan,

On 2023/9/22 17:35, Ryan Roberts wrote:
> On 22/09/2023 08:54, Qi Zheng wrote:
>> Hi Ryan,
>>
>> On 2023/9/22 15:40, Ryan Roberts wrote:
>>> On 22/09/2023 03:54, Qi Zheng wrote:
>>>> Hi Ryan,
>>>>
>>>> On 2023/9/22 00:20, Ryan Roberts wrote:
>>>>> When called with a swap entry that does not embed a PFN (e.g.
>>>>> PTE_MARKER_POISONED or PTE_MARKER_UFFD_WP), the previous implementation
>>>>> of set_huge_pte_at() would either cause a BUG() to fire (if
>>>>> CONFIG_DEBUG_VM is enabled) or cause a dereference of an invalid address
>>>>> and subsequent panic.
>>>>>
>>>>> arm64's huge pte implementation supports multiple huge page sizes, some
>>>>> of which are implemented in the page table with contiguous mappings. So
>>>>> set_huge_pte_at() needs to work out how big the logical pte is, so that
>>>>> it can also work out how many physical ptes (or pmds) need to be
>>>>> written. It does this by grabbing the folio out of the pte and querying
>>>>> its size.
>>>>>
>>>>> However, there are cases when the pte being set is actually a swap
>>>>> entry. But this also used to work fine, because for huge ptes, we only
>>>>> ever saw migration entries and hwpoison entries. And both of these types
>>>>> of swap entries have a PFN embedded, so the code would grab that and
>>>>> everything still worked out.
>>>>>
>>>>> But over time, more calls to set_huge_pte_at() have been added that set
>>>>> swap entry types that do not embed a PFN. And this causes the code to go
>>>>> bang. The triggering case is for the uffd poison test, commit
>>>>> 99aa77215ad0 ("selftests/mm: add uffd unit test for UFFDIO_POISON"),
>>>>> which sets a PTE_MARKER_POISONED swap entry. But review shows there are
>>>>> other places too (PTE_MARKER_UFFD_WP).
>>>>>
>>>>> So the root cause is due to commit 18f3962953e4 ("mm: hugetlb: kill
>>>>> set_huge_swap_pte_at()"), which aimed to simplify the interface to the
>>>>> core code by removing set_huge_swap_pte_at() (which took a page size
>>>>> parameter) and replacing it with calls to set_huge_swap_pte_at() where
>>>>> the size was inferred from the folio, as descibed above. While that
>>>>> commit didn't break anything at the time,
>>>>
>>>> If it didn't break anything at that time, then shouldn't the Fixes tag
>>>> be added to this commit?
>>>>
>>>>> it did break the interface
>>>>> because it couldn't handle swap entries without PFNs. And since then new
>>>>> callers have come along which rely on this working.
>>>>
>>>> So the Fixes tag should be added only to the commit that introduces the
>>>> first new callers?
>>>
>>> Well I guess it's a matter of point of view; My view is that 18f3962953e4 is the
>>> buggy change because it broke the interface to not be able to handle swap
>>> entries which do not contain PFNs. The fact that there were no callers that used
>>> the interface in this way at the time of the commit is irrelevant in my view.
>>
>> I understand your point of view.
>>
>> But IIUC, the Fixes tag is used to indicate the version that needs to
>> backport, but the version where the commit 18f3962953e4 is located
>> does not need to backport this bugfix patch.
>>
>>> But I already added 2 fixes tags; one for the buggy commit, and the other for
>>> the commit containing the new user of the interface.
>>
>> I think 2 fixes tags will cause inconvenience to the maintainers.
>>
> 
> I did some Archaeology:

Nice! Thanks for doing this.

> 
> $ git rev-list --no-walk=sorted --pretty=oneline \
> 	05e90bd05eea33fc77d6b11e121e2da01fee379f \
> 	60dfaad65aa97fb6755b9798a6b3c9e79bcd5930 \
> 	8a13897fb0daa8f56821f263f0c63661e1c6acae \
> 	18f3962953e40401b7ed98e8524167282c3e626e \
> 	v6.5 v5.18 v5.17 v5.19 v6.5-rc6 v6.5-rc7
> 
> 2dde18cd1d8fac735875f2e4987f11817cc0bc2c Linux 6.5
> 706a741595047797872e669b3101429ab8d378ef Linux 6.5-rc7
> 8a13897fb0daa8f56821f263f0c63661e1c6acae mm: userfaultfd: support UFFDIO_POISON for hugetlbfs
> 2ccdd1b13c591d306f0401d98dedc4bdcd02b421 Linux 6.5-rc6
> 3d7cb6b04c3f3115719235cc6866b10326de34cd Linux 5.19
> 18f3962953e40401b7ed98e8524167282c3e626e mm: hugetlb: kill set_huge_swap_pte_at()
> 4b0986a3613c92f4ec1bdc7f60ec66fea135991f Linux 5.18
> 05e90bd05eea33fc77d6b11e121e2da01fee379f mm/hugetlb: only drop uffd-wp special pte if required
> 60dfaad65aa97fb6755b9798a6b3c9e79bcd5930 mm/hugetlb: allow uffd wr-protect none ptes
> f443e374ae131c168a065ea1748feac6b2e76613 Linux 5.17
> 
> 
> So it turns out that the PTE_MARKER_UFFD_WP markers were added first, using
> set_huge_pte_at(). At the time, this should have used set_huge_swap_pte_at(), so
> was arguably buggy for that reason. However, arm64 does not support UFFD_WP so
> none of the call sites that set the PTE_MARKER_UFFD_WP marker to the pte ever
> trigger on arm64.
> 
> Then "mm: hugetlb: kill set_huge_swap_pte_at()" came along and "broke" the
> interface, but there were no callers relying on the behavoir that was broken.
> 
> Then "mm: userfaultfd: support UFFDIO_POISON for hugetlbfs" came along in
> v6.5-rc7 and started relying on the broken behaviour of set_huge_pte_at().

Got it.

> 
> So on that basis, I agree that the first commit where broken behaviour is
> observable is "mm: userfaultfd: support UFFDIO_POISON for hugetlbfs". So I will
> tag that one as "Fixes". (Although if set_huge_pte_at() was an exported symbol,
> then we would want to mark "mm: hugetlb: kill set_huge_swap_pte_at()").

Agree. I just checked the time point when 18f3962953e4 was added,
neither set_huge_pte_at() nor set_huge_swap_pte_at() are exported
symbols.

Thanks,
Qi

> 
> Thanks,
> Ryan
> 
> 
> 
> 
>> Thanks,
>> Qi
>>
>>>
>>>>
>>>> Other than that, LGTM.
>>>
>>> Thanks!
>>>
>>>>
>>>> Thanks,
>>>> Qi
>>>>


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

end of thread, other threads:[~2023-09-22  9:58 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-21 16:19 [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 1/8] parisc: hugetlb: Convert set_huge_pte_at() to take vma Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 2/8] powerpc: " Ryan Roberts
2023-09-21 18:43   ` Christophe Leroy
2023-09-22  6:44     ` Christophe Leroy
2023-09-22  7:19       ` Ryan Roberts
2023-09-22  6:56   ` Christophe Leroy
2023-09-22  7:33     ` Ryan Roberts
2023-09-22  8:10       ` Christophe Leroy
2023-09-22  8:41         ` Ryan Roberts
2023-09-22  9:14           ` Christophe Leroy
2023-09-22  9:37             ` Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 3/8] riscv: " Ryan Roberts
2023-09-22  7:54   ` Alexandre Ghiti
2023-09-22  8:36     ` Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 4/8] s390: " Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 5/8] sparc: " Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 6/8] mm: " Ryan Roberts
2023-09-22  1:37   ` SeongJae Park
2023-09-21 16:20 ` [PATCH v1 7/8] arm64: " Ryan Roberts
2023-09-21 16:20 ` [PATCH v1 8/8] arm64: hugetlb: Fix set_huge_pte_at() to work with all swap entries Ryan Roberts
2023-09-22  2:54   ` Qi Zheng
2023-09-22  7:40     ` Ryan Roberts
2023-09-22  7:54       ` Qi Zheng
2023-09-22  9:35         ` Ryan Roberts
2023-09-22  9:58           ` Qi Zheng
2023-09-21 16:30 ` [PATCH v1 0/8] Fix set_huge_pte_at() panic on arm64 Andrew Morton
2023-09-21 16:35   ` Ryan Roberts
2023-09-21 17:38     ` Catalin Marinas
2023-09-22  7:41       ` Ryan Roberts
2023-09-22  9:23     ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox