diff mbox series

[1/3] mm: Make arch_get_unmapped_area() take vm_flags by default

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

Commit Message

Mark Brown Sept. 2, 2024, 7:08 p.m. UTC
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(-)

Comments

Lorenzo Stoakes Sept. 3, 2024, 5:43 p.m. UTC | #1
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
>
Liam R. Howlett Sept. 3, 2024, 7:35 p.m. UTC | #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
>
Helge Deller Sept. 3, 2024, 7:50 p.m. UTC | #3
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 mbox series

Patch

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);