Message ID | 20240902-mm-generic-shadow-stack-guard-v1-1-9acda38b3dd3@kernel.org |
---|---|
State | New |
Headers | show |
Series | mm: Care about shadow stack guard gap when getting an unmapped area | expand |
On Mon, Sep 02, 2024 at 08:08:13PM GMT, Mark Brown wrote: > When we introduced arch_get_unmapped_area_vmflags() in 961148704acd > ("mm: introduce arch_get_unmapped_area_vmflags()") we did so as part of > properly supporting guard pages for shadow stacks on x86_64, which uses > a custom arch_get_unmapped_area(). Equivalent features are also present > on both arm64 and RISC-V, both of which use the generic implementation > of arch_get_unmapped_area() and will require equivalent modification > there. Rather than continue to deal with having two versions of the > functions let's bite the bullet and have all implementations of > arch_get_unmapped_area() take vm_flags as a parameter. > > The new parameter is currently ignored by all implementations other than > x86. The only caller that doesn't have a vm_flags available is > mm_get_unmapped_area(), as for the x86 implementation and the wrapper used > on other architectures this is modified to supply no flags. > > No functional changes. > > Signed-off-by: Mark Brown <broonie@kernel.org> mm/mmap.c bit looks reasonable to me! Nice cleanup! :) Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> (for mm/mmap.c part) > --- > arch/alpha/kernel/osf_sys.c | 2 +- > arch/arc/mm/mmap.c | 3 ++- > arch/arm/mm/mmap.c | 7 ++++--- > arch/csky/abiv1/mmap.c | 3 ++- > arch/loongarch/mm/mmap.c | 5 +++-- > arch/mips/mm/mmap.c | 2 +- > arch/parisc/kernel/sys_parisc.c | 5 +++-- > arch/parisc/mm/hugetlbpage.c | 2 +- > arch/powerpc/mm/book3s64/slice.c | 6 ++++-- > arch/s390/mm/mmap.c | 4 ++-- > arch/sh/mm/mmap.c | 5 +++-- > arch/sparc/kernel/sys_sparc_32.c | 2 +- > arch/sparc/kernel/sys_sparc_64.c | 4 ++-- > arch/x86/include/asm/pgtable_64.h | 1 - > arch/x86/kernel/sys_x86_64.c | 21 +++------------------ > arch/xtensa/kernel/syscall.c | 3 ++- > include/linux/sched/mm.h | 23 ++++++++--------------- > mm/mmap.c | 31 +++++++------------------------ > 18 files changed, 49 insertions(+), 80 deletions(-) > > diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c > index e5f881bc8288..8886ab539273 100644 > --- a/arch/alpha/kernel/osf_sys.c > +++ b/arch/alpha/kernel/osf_sys.c > @@ -1229,7 +1229,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len, > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > unsigned long limit; > > diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c > index 69a915297155..2185afe8d59f 100644 > --- a/arch/arc/mm/mmap.c > +++ b/arch/arc/mm/mmap.c > @@ -23,7 +23,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c > index d65d0e6ed10a..3dbb383c26d5 100644 > --- a/arch/arm/mm/mmap.c > +++ b/arch/arm/mm/mmap.c > @@ -28,7 +28,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -78,8 +79,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > - const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long len, const unsigned long pgoff, > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c > index 7f826331d409..1047865e82a9 100644 > --- a/arch/csky/abiv1/mmap.c > +++ b/arch/csky/abiv1/mmap.c > @@ -23,7 +23,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c > index 889030985135..914e82ff3f65 100644 > --- a/arch/loongarch/mm/mmap.c > +++ b/arch/loongarch/mm/mmap.c > @@ -89,7 +89,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, UP); > @@ -101,7 +102,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > */ > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr0, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, DOWN); > diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c > index 7e11d7b58761..02bf5353efbd 100644 > --- a/arch/mips/mm/mmap.c > +++ b/arch/mips/mm/mmap.c > @@ -110,7 +110,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > */ > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr0, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, DOWN); > diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c > index f7722451276e..f852fe274abe 100644 > --- a/arch/parisc/kernel/sys_parisc.c > +++ b/arch/parisc/kernel/sys_parisc.c > @@ -167,7 +167,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr, len, pgoff, flags, UP); > @@ -175,7 +176,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr, len, pgoff, flags, DOWN); > diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c > index 0356199bd9e7..aa664f7ddb63 100644 > --- a/arch/parisc/mm/hugetlbpage.c > +++ b/arch/parisc/mm/hugetlbpage.c > @@ -40,7 +40,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, > addr = ALIGN(addr, huge_page_size(h)); > > /* we need to make sure the colouring is OK */ > - return arch_get_unmapped_area(file, addr, len, pgoff, flags); > + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); > } > > > diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c > index ef3ce37f1bb3..ada6bf896ef8 100644 > --- a/arch/powerpc/mm/book3s64/slice.c > +++ b/arch/powerpc/mm/book3s64/slice.c > @@ -637,7 +637,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, > unsigned long addr, > unsigned long len, > unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, > + vm_flags_t vm_flags) > { > if (radix_enabled()) > return generic_get_unmapped_area(filp, addr, len, pgoff, flags); > @@ -650,7 +651,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, > const unsigned long addr0, > const unsigned long len, > const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, > + vm_flags_t vm_flags) > { > if (radix_enabled()) > return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags); > diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c > index 206756946589..96efa061ce01 100644 > --- a/arch/s390/mm/mmap.c > +++ b/arch/s390/mm/mmap.c > @@ -82,7 +82,7 @@ static int get_align_mask(struct file *filp, unsigned long flags) > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -117,7 +117,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c > index bee329d4149a..c442734d9b0c 100644 > --- a/arch/sh/mm/mmap.c > +++ b/arch/sh/mm/mmap.c > @@ -52,7 +52,8 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -99,7 +100,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c > index 08a19727795c..80822f922e76 100644 > --- a/arch/sparc/kernel/sys_sparc_32.c > +++ b/arch/sparc/kernel/sys_sparc_32.c > @@ -39,7 +39,7 @@ SYSCALL_DEFINE0(getpagesize) > return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ > } > > -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) > +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct vm_unmapped_area_info info = {}; > > diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c > index d9c3b34ca744..acade309dc2f 100644 > --- a/arch/sparc/kernel/sys_sparc_64.c > +++ b/arch/sparc/kernel/sys_sparc_64.c > @@ -87,7 +87,7 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr, > return base + off; > } > > -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) > +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct * vma; > @@ -146,7 +146,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h > index 3c4407271d08..7e9db77231ac 100644 > --- a/arch/x86/include/asm/pgtable_64.h > +++ b/arch/x86/include/asm/pgtable_64.h > @@ -245,7 +245,6 @@ extern void cleanup_highmap(void); > > #define HAVE_ARCH_UNMAPPED_AREA > #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN > -#define HAVE_ARCH_UNMAPPED_AREA_VMFLAGS > > #define PAGE_AGP PAGE_KERNEL_NOCACHE > #define HAVE_PAGE_AGP 1 > diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c > index 01d7cd85ef97..87f8c9a71c49 100644 > --- a/arch/x86/kernel/sys_x86_64.c > +++ b/arch/x86/kernel/sys_x86_64.c > @@ -121,7 +121,7 @@ static inline unsigned long stack_guard_placement(vm_flags_t vm_flags) > } > > unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, > +arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > @@ -158,7 +158,7 @@ arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned l > } > > unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, > +arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, > unsigned long len, unsigned long pgoff, > unsigned long flags, vm_flags_t vm_flags) > { > @@ -228,20 +228,5 @@ arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, > * can happen with large stack limits and large mmap() > * allocations. > */ > - return arch_get_unmapped_area(filp, addr0, len, pgoff, flags); > -} > - > -unsigned long > -arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > -{ > - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0); > -} > - > -unsigned long > -arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, > - const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > -{ > - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, flags, 0); > + return arch_get_unmapped_area(filp, addr0, len, pgoff, flags, 0); > } > diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c > index b3c2450d6f23..7f048d368dba 100644 > --- a/arch/xtensa/kernel/syscall.c > +++ b/arch/xtensa/kernel/syscall.c > @@ -55,7 +55,8 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, > > #ifdef CONFIG_MMU > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flgs_t vm_flags) > { > struct vm_area_struct *vmm; > struct vma_iterator vmi; > diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h > index 91546493c43d..c4d34abc45d4 100644 > --- a/include/linux/sched/mm.h > +++ b/include/linux/sched/mm.h > @@ -179,27 +179,20 @@ static inline void mm_update_next_owner(struct mm_struct *mm) > > extern void arch_pick_mmap_layout(struct mm_struct *mm, > struct rlimit *rlim_stack); > -extern unsigned long > -arch_get_unmapped_area(struct file *, unsigned long, unsigned long, > - unsigned long, unsigned long); > -extern unsigned long > + > +unsigned long > +arch_get_unmapped_area(struct file *filp, unsigned long addr, > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags); > +unsigned long > arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags); > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t); > > unsigned long mm_get_unmapped_area(struct mm_struct *mm, struct file *filp, > unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags); > > -unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t vm_flags); > -unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t); > - > unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, > struct file *filp, > unsigned long addr, > diff --git a/mm/mmap.c b/mm/mmap.c > index d0dfc85b209b..7528146f886f 100644 > --- a/mm/mmap.c > +++ b/mm/mmap.c > @@ -1821,7 +1821,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return generic_get_unmapped_area(filp, addr, len, pgoff, flags); > } > @@ -1885,38 +1885,21 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); > } > #endif > > -#ifndef HAVE_ARCH_UNMAPPED_AREA_VMFLAGS > -unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, > - unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > -{ > - return arch_get_unmapped_area(filp, addr, len, pgoff, flags); > -} > - > -unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t vm_flags) > -{ > - return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); > -} > -#endif > - > unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, struct file *filp, > unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags, > vm_flags_t vm_flags) > { > if (test_bit(MMF_TOPDOWN, &mm->flags)) > - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, > - flags, vm_flags); > - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, vm_flags); > + return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, > + flags, vm_flags); > + return arch_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags); > } Kind of a pity to keep the _vmflags() variants when in similarly-named arch_get_unmapped...() functions we drop it, but I guess it would get churny to try to change mm_get_unmapped_area() as I see that being called in various places. > > unsigned long > @@ -1978,8 +1961,8 @@ mm_get_unmapped_area(struct mm_struct *mm, struct file *file, > unsigned long pgoff, unsigned long flags) > { > if (test_bit(MMF_TOPDOWN, &mm->flags)) > - return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags); > - return arch_get_unmapped_area(file, addr, len, pgoff, flags); > + return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags, 0); > + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); > } > EXPORT_SYMBOL(mm_get_unmapped_area); > > > -- > 2.39.2 >
* Mark Brown <broonie@kernel.org> [240902 15:09]: > When we introduced arch_get_unmapped_area_vmflags() in 961148704acd > ("mm: introduce arch_get_unmapped_area_vmflags()") we did so as part of > properly supporting guard pages for shadow stacks on x86_64, which uses > a custom arch_get_unmapped_area(). Equivalent features are also present > on both arm64 and RISC-V, both of which use the generic implementation > of arch_get_unmapped_area() and will require equivalent modification > there. Rather than continue to deal with having two versions of the > functions let's bite the bullet and have all implementations of > arch_get_unmapped_area() take vm_flags as a parameter. > > The new parameter is currently ignored by all implementations other than > x86. The only caller that doesn't have a vm_flags available is > mm_get_unmapped_area(), as for the x86 implementation and the wrapper used > on other architectures this is modified to supply no flags. > > No functional changes. > > Signed-off-by: Mark Brown <broonie@kernel.org> I don't love sparc32/sparc64 requires a wide screen monitor, but it already broke the 80 char limit. Reviewed-by: Liam R. Howlett <Liam.Howlett@Oracle.com> > --- > arch/alpha/kernel/osf_sys.c | 2 +- > arch/arc/mm/mmap.c | 3 ++- > arch/arm/mm/mmap.c | 7 ++++--- > arch/csky/abiv1/mmap.c | 3 ++- > arch/loongarch/mm/mmap.c | 5 +++-- > arch/mips/mm/mmap.c | 2 +- > arch/parisc/kernel/sys_parisc.c | 5 +++-- > arch/parisc/mm/hugetlbpage.c | 2 +- > arch/powerpc/mm/book3s64/slice.c | 6 ++++-- > arch/s390/mm/mmap.c | 4 ++-- > arch/sh/mm/mmap.c | 5 +++-- > arch/sparc/kernel/sys_sparc_32.c | 2 +- > arch/sparc/kernel/sys_sparc_64.c | 4 ++-- > arch/x86/include/asm/pgtable_64.h | 1 - > arch/x86/kernel/sys_x86_64.c | 21 +++------------------ > arch/xtensa/kernel/syscall.c | 3 ++- > include/linux/sched/mm.h | 23 ++++++++--------------- > mm/mmap.c | 31 +++++++------------------------ > 18 files changed, 49 insertions(+), 80 deletions(-) > > diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c > index e5f881bc8288..8886ab539273 100644 > --- a/arch/alpha/kernel/osf_sys.c > +++ b/arch/alpha/kernel/osf_sys.c > @@ -1229,7 +1229,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len, > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > unsigned long limit; > > diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c > index 69a915297155..2185afe8d59f 100644 > --- a/arch/arc/mm/mmap.c > +++ b/arch/arc/mm/mmap.c > @@ -23,7 +23,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c > index d65d0e6ed10a..3dbb383c26d5 100644 > --- a/arch/arm/mm/mmap.c > +++ b/arch/arm/mm/mmap.c > @@ -28,7 +28,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -78,8 +79,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > - const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long len, const unsigned long pgoff, > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c > index 7f826331d409..1047865e82a9 100644 > --- a/arch/csky/abiv1/mmap.c > +++ b/arch/csky/abiv1/mmap.c > @@ -23,7 +23,8 @@ > */ > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c > index 889030985135..914e82ff3f65 100644 > --- a/arch/loongarch/mm/mmap.c > +++ b/arch/loongarch/mm/mmap.c > @@ -89,7 +89,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, UP); > @@ -101,7 +102,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > */ > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr0, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, DOWN); > diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c > index 7e11d7b58761..02bf5353efbd 100644 > --- a/arch/mips/mm/mmap.c > +++ b/arch/mips/mm/mmap.c > @@ -110,7 +110,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, > */ > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr0, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr0, len, pgoff, flags, DOWN); > diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c > index f7722451276e..f852fe274abe 100644 > --- a/arch/parisc/kernel/sys_parisc.c > +++ b/arch/parisc/kernel/sys_parisc.c > @@ -167,7 +167,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr, len, pgoff, flags, UP); > @@ -175,7 +176,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long arch_get_unmapped_area_topdown(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return arch_get_unmapped_area_common(filp, > addr, len, pgoff, flags, DOWN); > diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c > index 0356199bd9e7..aa664f7ddb63 100644 > --- a/arch/parisc/mm/hugetlbpage.c > +++ b/arch/parisc/mm/hugetlbpage.c > @@ -40,7 +40,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, > addr = ALIGN(addr, huge_page_size(h)); > > /* we need to make sure the colouring is OK */ > - return arch_get_unmapped_area(file, addr, len, pgoff, flags); > + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); > } > > > diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c > index ef3ce37f1bb3..ada6bf896ef8 100644 > --- a/arch/powerpc/mm/book3s64/slice.c > +++ b/arch/powerpc/mm/book3s64/slice.c > @@ -637,7 +637,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, > unsigned long addr, > unsigned long len, > unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, > + vm_flags_t vm_flags) > { > if (radix_enabled()) > return generic_get_unmapped_area(filp, addr, len, pgoff, flags); > @@ -650,7 +651,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, > const unsigned long addr0, > const unsigned long len, > const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, > + vm_flags_t vm_flags) > { > if (radix_enabled()) > return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags); > diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c > index 206756946589..96efa061ce01 100644 > --- a/arch/s390/mm/mmap.c > +++ b/arch/s390/mm/mmap.c > @@ -82,7 +82,7 @@ static int get_align_mask(struct file *filp, unsigned long flags) > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -117,7 +117,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > > unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c > index bee329d4149a..c442734d9b0c 100644 > --- a/arch/sh/mm/mmap.c > +++ b/arch/sh/mm/mmap.c > @@ -52,7 +52,8 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr, > } > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > @@ -99,7 +100,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c > index 08a19727795c..80822f922e76 100644 > --- a/arch/sparc/kernel/sys_sparc_32.c > +++ b/arch/sparc/kernel/sys_sparc_32.c > @@ -39,7 +39,7 @@ SYSCALL_DEFINE0(getpagesize) > return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ > } > > -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) > +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct vm_unmapped_area_info info = {}; > > diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c > index d9c3b34ca744..acade309dc2f 100644 > --- a/arch/sparc/kernel/sys_sparc_64.c > +++ b/arch/sparc/kernel/sys_sparc_64.c > @@ -87,7 +87,7 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr, > return base + off; > } > > -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) > +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > struct vm_area_struct * vma; > @@ -146,7 +146,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > + const unsigned long flags, vm_flags_t vm_flags) > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h > index 3c4407271d08..7e9db77231ac 100644 > --- a/arch/x86/include/asm/pgtable_64.h > +++ b/arch/x86/include/asm/pgtable_64.h > @@ -245,7 +245,6 @@ extern void cleanup_highmap(void); > > #define HAVE_ARCH_UNMAPPED_AREA > #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN > -#define HAVE_ARCH_UNMAPPED_AREA_VMFLAGS > > #define PAGE_AGP PAGE_KERNEL_NOCACHE > #define HAVE_PAGE_AGP 1 > diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c > index 01d7cd85ef97..87f8c9a71c49 100644 > --- a/arch/x86/kernel/sys_x86_64.c > +++ b/arch/x86/kernel/sys_x86_64.c > @@ -121,7 +121,7 @@ static inline unsigned long stack_guard_placement(vm_flags_t vm_flags) > } > > unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, > +arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > { > struct mm_struct *mm = current->mm; > @@ -158,7 +158,7 @@ arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned l > } > > unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, > +arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, > unsigned long len, unsigned long pgoff, > unsigned long flags, vm_flags_t vm_flags) > { > @@ -228,20 +228,5 @@ arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, > * can happen with large stack limits and large mmap() > * allocations. > */ > - return arch_get_unmapped_area(filp, addr0, len, pgoff, flags); > -} > - > -unsigned long > -arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > -{ > - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0); > -} > - > -unsigned long > -arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, > - const unsigned long len, const unsigned long pgoff, > - const unsigned long flags) > -{ > - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, flags, 0); > + return arch_get_unmapped_area(filp, addr0, len, pgoff, flags, 0); > } > diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c > index b3c2450d6f23..7f048d368dba 100644 > --- a/arch/xtensa/kernel/syscall.c > +++ b/arch/xtensa/kernel/syscall.c > @@ -55,7 +55,8 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, > > #ifdef CONFIG_MMU > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, unsigned long flags) > + unsigned long len, unsigned long pgoff, unsigned long flags, > + vm_flgs_t vm_flags) > { > struct vm_area_struct *vmm; > struct vma_iterator vmi; > diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h > index 91546493c43d..c4d34abc45d4 100644 > --- a/include/linux/sched/mm.h > +++ b/include/linux/sched/mm.h > @@ -179,27 +179,20 @@ static inline void mm_update_next_owner(struct mm_struct *mm) > > extern void arch_pick_mmap_layout(struct mm_struct *mm, > struct rlimit *rlim_stack); > -extern unsigned long > -arch_get_unmapped_area(struct file *, unsigned long, unsigned long, > - unsigned long, unsigned long); > -extern unsigned long > + > +unsigned long > +arch_get_unmapped_area(struct file *filp, unsigned long addr, > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t vm_flags); > +unsigned long > arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags); > + unsigned long len, unsigned long pgoff, > + unsigned long flags, vm_flags_t); > > unsigned long mm_get_unmapped_area(struct mm_struct *mm, struct file *filp, > unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags); > > -unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t vm_flags); > -unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t); > - > unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, > struct file *filp, > unsigned long addr, > diff --git a/mm/mmap.c b/mm/mmap.c > index d0dfc85b209b..7528146f886f 100644 > --- a/mm/mmap.c > +++ b/mm/mmap.c > @@ -1821,7 +1821,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return generic_get_unmapped_area(filp, addr, len, pgoff, flags); > } > @@ -1885,38 +1885,21 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long > arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > unsigned long len, unsigned long pgoff, > - unsigned long flags) > + unsigned long flags, vm_flags_t vm_flags) > { > return generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); > } > #endif > > -#ifndef HAVE_ARCH_UNMAPPED_AREA_VMFLAGS > -unsigned long > -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, > - unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) > -{ > - return arch_get_unmapped_area(filp, addr, len, pgoff, flags); > -} > - > -unsigned long > -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, > - unsigned long len, unsigned long pgoff, > - unsigned long flags, vm_flags_t vm_flags) > -{ > - return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); > -} > -#endif > - > unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, struct file *filp, > unsigned long addr, unsigned long len, > unsigned long pgoff, unsigned long flags, > vm_flags_t vm_flags) > { > if (test_bit(MMF_TOPDOWN, &mm->flags)) > - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, > - flags, vm_flags); > - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, vm_flags); > + return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, > + flags, vm_flags); > + return arch_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags); > } > > unsigned long > @@ -1978,8 +1961,8 @@ mm_get_unmapped_area(struct mm_struct *mm, struct file *file, > unsigned long pgoff, unsigned long flags) > { > if (test_bit(MMF_TOPDOWN, &mm->flags)) > - return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags); > - return arch_get_unmapped_area(file, addr, len, pgoff, flags); > + return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags, 0); > + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); > } > EXPORT_SYMBOL(mm_get_unmapped_area); > > > -- > 2.39.2 >
On 9/2/24 21:08, Mark Brown wrote: > When we introduced arch_get_unmapped_area_vmflags() in 961148704acd > ("mm: introduce arch_get_unmapped_area_vmflags()") we did so as part of > properly supporting guard pages for shadow stacks on x86_64, which uses > a custom arch_get_unmapped_area(). Equivalent features are also present > on both arm64 and RISC-V, both of which use the generic implementation > of arch_get_unmapped_area() and will require equivalent modification > there. Rather than continue to deal with having two versions of the > functions let's bite the bullet and have all implementations of > arch_get_unmapped_area() take vm_flags as a parameter. > > The new parameter is currently ignored by all implementations other than > x86. The only caller that doesn't have a vm_flags available is > mm_get_unmapped_area(), as for the x86 implementation and the wrapper used > on other architectures this is modified to supply no flags. > > No functional changes. > > Signed-off-by: Mark Brown <broonie@kernel.org> > --- > arch/alpha/kernel/osf_sys.c | 2 +- > arch/arc/mm/mmap.c | 3 ++- > arch/arm/mm/mmap.c | 7 ++++--- > arch/csky/abiv1/mmap.c | 3 ++- > arch/loongarch/mm/mmap.c | 5 +++-- > arch/mips/mm/mmap.c | 2 +- > arch/parisc/kernel/sys_parisc.c | 5 +++-- > arch/parisc/mm/hugetlbpage.c | 2 +- Acked-by: Helge Deller <deller@gmx.de> # parisc Helge
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index e5f881bc8288..8886ab539273 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1229,7 +1229,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len, unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { unsigned long limit; diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c index 69a915297155..2185afe8d59f 100644 --- a/arch/arc/mm/mmap.c +++ b/arch/arc/mm/mmap.c @@ -23,7 +23,8 @@ */ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, + unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index d65d0e6ed10a..3dbb383c26d5 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -28,7 +28,8 @@ */ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, + unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -78,8 +79,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - const unsigned long len, const unsigned long pgoff, - const unsigned long flags) + const unsigned long len, const unsigned long pgoff, + const unsigned long flags, vm_flags_t vm_flags) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c index 7f826331d409..1047865e82a9 100644 --- a/arch/csky/abiv1/mmap.c +++ b/arch/csky/abiv1/mmap.c @@ -23,7 +23,8 @@ */ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, + unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c index 889030985135..914e82ff3f65 100644 --- a/arch/loongarch/mm/mmap.c +++ b/arch/loongarch/mm/mmap.c @@ -89,7 +89,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, } unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, unsigned long flags, + vm_flags_t vm_flags) { return arch_get_unmapped_area_common(filp, addr0, len, pgoff, flags, UP); @@ -101,7 +102,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, */ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { return arch_get_unmapped_area_common(filp, addr0, len, pgoff, flags, DOWN); diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 7e11d7b58761..02bf5353efbd 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -110,7 +110,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, */ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { return arch_get_unmapped_area_common(filp, addr0, len, pgoff, flags, DOWN); diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index f7722451276e..f852fe274abe 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -167,7 +167,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, } unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, unsigned long flags, + vm_flags_t vm_flags) { return arch_get_unmapped_area_common(filp, addr, len, pgoff, flags, UP); @@ -175,7 +176,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { return arch_get_unmapped_area_common(filp, addr, len, pgoff, flags, DOWN); diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c index 0356199bd9e7..aa664f7ddb63 100644 --- a/arch/parisc/mm/hugetlbpage.c +++ b/arch/parisc/mm/hugetlbpage.c @@ -40,7 +40,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, addr = ALIGN(addr, huge_page_size(h)); /* we need to make sure the colouring is OK */ - return arch_get_unmapped_area(file, addr, len, pgoff, flags); + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); } diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c index ef3ce37f1bb3..ada6bf896ef8 100644 --- a/arch/powerpc/mm/book3s64/slice.c +++ b/arch/powerpc/mm/book3s64/slice.c @@ -637,7 +637,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, + vm_flags_t vm_flags) { if (radix_enabled()) return generic_get_unmapped_area(filp, addr, len, pgoff, flags); @@ -650,7 +651,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, - const unsigned long flags) + const unsigned long flags, + vm_flags_t vm_flags) { if (radix_enabled()) return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags); diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 206756946589..96efa061ce01 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -82,7 +82,7 @@ static int get_align_mask(struct file *filp, unsigned long flags) unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -117,7 +117,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c index bee329d4149a..c442734d9b0c 100644 --- a/arch/sh/mm/mmap.c +++ b/arch/sh/mm/mmap.c @@ -52,7 +52,8 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr, } unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, unsigned long flags, + vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -99,7 +100,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, - const unsigned long flags) + const unsigned long flags, vm_flags_t vm_flags) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 08a19727795c..80822f922e76 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -39,7 +39,7 @@ SYSCALL_DEFINE0(getpagesize) return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ } -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { struct vm_unmapped_area_info info = {}; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index d9c3b34ca744..acade309dc2f 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -87,7 +87,7 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr, return base + off; } -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; struct vm_area_struct * vma; @@ -146,7 +146,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, - const unsigned long flags) + const unsigned long flags, vm_flags_t vm_flags) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 3c4407271d08..7e9db77231ac 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -245,7 +245,6 @@ extern void cleanup_highmap(void); #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN -#define HAVE_ARCH_UNMAPPED_AREA_VMFLAGS #define PAGE_AGP PAGE_KERNEL_NOCACHE #define HAVE_PAGE_AGP 1 diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 01d7cd85ef97..87f8c9a71c49 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -121,7 +121,7 @@ static inline unsigned long stack_guard_placement(vm_flags_t vm_flags) } unsigned long -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, +arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; @@ -158,7 +158,7 @@ arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned l } unsigned long -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, +arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { @@ -228,20 +228,5 @@ arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0, * can happen with large stack limits and large mmap() * allocations. */ - return arch_get_unmapped_area(filp, addr0, len, pgoff, flags); -} - -unsigned long -arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) -{ - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0); -} - -unsigned long -arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, - const unsigned long len, const unsigned long pgoff, - const unsigned long flags) -{ - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, flags, 0); + return arch_get_unmapped_area(filp, addr0, len, pgoff, flags, 0); } diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index b3c2450d6f23..7f048d368dba 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -55,7 +55,8 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, #ifdef CONFIG_MMU unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, unsigned long flags, + vm_flgs_t vm_flags) { struct vm_area_struct *vmm; struct vma_iterator vmi; diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 91546493c43d..c4d34abc45d4 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -179,27 +179,20 @@ static inline void mm_update_next_owner(struct mm_struct *mm) extern void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack); -extern unsigned long -arch_get_unmapped_area(struct file *, unsigned long, unsigned long, - unsigned long, unsigned long); -extern unsigned long + +unsigned long +arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags, vm_flags_t vm_flags); +unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, - unsigned long flags); + unsigned long len, unsigned long pgoff, + unsigned long flags, vm_flags_t); unsigned long mm_get_unmapped_area(struct mm_struct *mm, struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -unsigned long -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t vm_flags); -unsigned long -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t); - unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, struct file *filp, unsigned long addr, diff --git a/mm/mmap.c b/mm/mmap.c index d0dfc85b209b..7528146f886f 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1821,7 +1821,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { return generic_get_unmapped_area(filp, addr, len, pgoff, flags); } @@ -1885,38 +1885,21 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) + unsigned long flags, vm_flags_t vm_flags) { return generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); } #endif -#ifndef HAVE_ARCH_UNMAPPED_AREA_VMFLAGS -unsigned long -arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len, - unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) -{ - return arch_get_unmapped_area(filp, addr, len, pgoff, flags); -} - -unsigned long -arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t vm_flags) -{ - return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); -} -#endif - unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm, struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { if (test_bit(MMF_TOPDOWN, &mm->flags)) - return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, - flags, vm_flags); - return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, vm_flags); + return arch_get_unmapped_area_topdown(filp, addr, len, pgoff, + flags, vm_flags); + return arch_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags); } unsigned long @@ -1978,8 +1961,8 @@ mm_get_unmapped_area(struct mm_struct *mm, struct file *file, unsigned long pgoff, unsigned long flags) { if (test_bit(MMF_TOPDOWN, &mm->flags)) - return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags); - return arch_get_unmapped_area(file, addr, len, pgoff, flags); + return arch_get_unmapped_area_topdown(file, addr, len, pgoff, flags, 0); + return arch_get_unmapped_area(file, addr, len, pgoff, flags, 0); } EXPORT_SYMBOL(mm_get_unmapped_area);
When we introduced arch_get_unmapped_area_vmflags() in 961148704acd ("mm: introduce arch_get_unmapped_area_vmflags()") we did so as part of properly supporting guard pages for shadow stacks on x86_64, which uses a custom arch_get_unmapped_area(). Equivalent features are also present on both arm64 and RISC-V, both of which use the generic implementation of arch_get_unmapped_area() and will require equivalent modification there. Rather than continue to deal with having two versions of the functions let's bite the bullet and have all implementations of arch_get_unmapped_area() take vm_flags as a parameter. The new parameter is currently ignored by all implementations other than x86. The only caller that doesn't have a vm_flags available is mm_get_unmapped_area(), as for the x86 implementation and the wrapper used on other architectures this is modified to supply no flags. No functional changes. Signed-off-by: Mark Brown <broonie@kernel.org> --- arch/alpha/kernel/osf_sys.c | 2 +- arch/arc/mm/mmap.c | 3 ++- arch/arm/mm/mmap.c | 7 ++++--- arch/csky/abiv1/mmap.c | 3 ++- arch/loongarch/mm/mmap.c | 5 +++-- arch/mips/mm/mmap.c | 2 +- arch/parisc/kernel/sys_parisc.c | 5 +++-- arch/parisc/mm/hugetlbpage.c | 2 +- arch/powerpc/mm/book3s64/slice.c | 6 ++++-- arch/s390/mm/mmap.c | 4 ++-- arch/sh/mm/mmap.c | 5 +++-- arch/sparc/kernel/sys_sparc_32.c | 2 +- arch/sparc/kernel/sys_sparc_64.c | 4 ++-- arch/x86/include/asm/pgtable_64.h | 1 - arch/x86/kernel/sys_x86_64.c | 21 +++------------------ arch/xtensa/kernel/syscall.c | 3 ++- include/linux/sched/mm.h | 23 ++++++++--------------- mm/mmap.c | 31 +++++++------------------------ 18 files changed, 49 insertions(+), 80 deletions(-)