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
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); }
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 */
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
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
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
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
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
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
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-d6288156595...
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
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
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
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)) {
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
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
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));
Hi,
Thanks for your patch.
FYI: kernel test robot notices the stable kernel rule is not satisfied.
The check is based on https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html/#opt...
Rule: add the tag "Cc: stable@vger.kernel.org" in the sign-off area to have the patch automatically included in the stable tree. Subject: [PATCH v1 4/8] s390: hugetlb: Convert set_huge_pte_at() to take vma Link: https://lore.kernel.org/stable/20230921162007.1630149-5-ryan.roberts%40arm.c...
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) {
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; }
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
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); }
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);
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)) {
return; }for (i = 0; i < ncontig; i++, ptep++, addr += pgsize) set_pte_at(mm, addr, ptep, pte);
@@ -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);
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);
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);
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
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
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?
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.
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.
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.
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
linux-stable-mirror@lists.linaro.org