Both parameters of arch_setup_additional_pages() are currently unused.
commit fc5243d98ac2 ("[S390] arch_setup_additional_pages arguments")
tried to introduce useful arguments, but they still are not used.

Remove old parameters and introduce sysinfo_ehdr argument that will be
used to return vdso address to put as AT_SYSINFO_EHDR tag in auxiliary
vector. The reason to do it is that many architecture have vDSO pointer
saved in their mm->context with the only purpose to use it later
in ARCH_DLINFO. That's the macro for elf loader to setup sysinfo_ehdr
tag.

Return sysinfo_ehdr address that will be later used by ARCH_DLINFO as
an argument. That will allow to drop vDSO pointer from mm.context
and any code responsible to track vDSO position on platforms that
don't use vDSO as a landing in userspace (arm/s390/sparc).

Cc: Albert Ou <a...@eecs.berkeley.edu>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: Palmer Dabbelt <pal...@dabbelt.com>
Cc: Paul Walmsley <paul.walms...@sifive.com>
Cc: linux-fsde...@vger.kernel.org
Signed-off-by: Dmitry Safonov <d...@arista.com>
---
 arch/arm/include/asm/vdso.h        |  6 ++++--
 arch/arm/kernel/process.c          |  4 ++--
 arch/arm/kernel/vdso.c             | 10 +++++++---
 arch/arm64/kernel/vdso.c           | 17 ++++++++--------
 arch/csky/kernel/vdso.c            |  3 ++-
 arch/hexagon/kernel/vdso.c         |  3 ++-
 arch/mips/kernel/vdso.c            |  3 ++-
 arch/nds32/kernel/vdso.c           |  3 ++-
 arch/nios2/mm/init.c               |  2 +-
 arch/powerpc/kernel/vdso.c         |  3 ++-
 arch/riscv/kernel/vdso.c           |  9 +++++----
 arch/s390/kernel/vdso.c            |  3 ++-
 arch/sh/kernel/vsyscall/vsyscall.c |  3 ++-
 arch/sparc/vdso/vma.c              | 15 +++++++-------
 arch/x86/entry/vdso/vma.c          | 32 +++++++++++++++++-------------
 arch/x86/um/vdso/vma.c             |  2 +-
 fs/binfmt_elf.c                    |  3 ++-
 fs/binfmt_elf_fdpic.c              |  3 ++-
 include/linux/elf.h                | 17 +++++++++++-----
 19 files changed, 84 insertions(+), 57 deletions(-)

diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h
index 5b85889f82ee..6b2b3b1fe833 100644
--- a/arch/arm/include/asm/vdso.h
+++ b/arch/arm/include/asm/vdso.h
@@ -10,13 +10,15 @@ struct mm_struct;
 
 #ifdef CONFIG_VDSO
 
-void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr,
+                     unsigned long *sysinfo_ehdr);
 
 extern unsigned int vdso_total_pages;
 
 #else /* CONFIG_VDSO */
 
-static inline void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+static inline void arm_install_vdso(struct mm_struct *mm, unsigned long addr,
+                                   unsigned long *sysinfo_ehdr)
 {
 }
 
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d0220da1d1b1..0e90cba8ac7a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -389,7 +389,7 @@ static const struct vm_special_mapping sigpage_mapping = {
        .mremap = sigpage_mremap,
 };
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
@@ -430,7 +430,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
         * to be fatal to the process, so no error check needed
         * here.
         */
-       arm_install_vdso(mm, addr + PAGE_SIZE);
+       arm_install_vdso(mm, addr + PAGE_SIZE, sysinfo_ehdr);
 
  up_fail:
        mmap_write_unlock(mm);
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 3408269d19c7..710e5ca99a53 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -233,7 +233,8 @@ static int install_vvar(struct mm_struct *mm, unsigned long 
addr)
 }
 
 /* assumes mmap_lock is write-locked */
-void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr,
+                     unsigned long *sysinfo_ehdr)
 {
        struct vm_area_struct *vma;
        unsigned long len;
@@ -254,7 +255,10 @@ void arm_install_vdso(struct mm_struct *mm, unsigned long 
addr)
                VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
                &vdso_text_mapping);
 
-       if (!IS_ERR(vma))
-               mm->context.vdso = addr;
+       if (IS_ERR(vma))
+               return;
+
+       mm->context.vdso = addr;
+       *sysinfo_ehdr = addr;
 }
 
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 1b710deb84d6..666338724a07 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -213,8 +213,7 @@ static vm_fault_t vvar_fault(const struct 
vm_special_mapping *sm,
 
 static int __setup_additional_pages(enum vdso_abi abi,
                                    struct mm_struct *mm,
-                                   struct linux_binprm *bprm,
-                                   int uses_interp)
+                                   unsigned long *sysinfo_ehdr)
 {
        unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
        unsigned long gp_flags = 0;
@@ -250,6 +249,8 @@ static int __setup_additional_pages(enum vdso_abi abi,
        if (IS_ERR(ret))
                goto up_fail;
 
+       *sysinfo_ehdr = vdso_base;
+
        return 0;
 
 up_fail:
@@ -401,8 +402,7 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm)
        return PTR_ERR_OR_ZERO(ret);
 }
 
-static int aarch32_setup_additional_pages(struct linux_binprm *bprm,
-                                         int uses_interp)
+static int aarch32_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        int ret;
@@ -412,8 +412,7 @@ static int aarch32_setup_additional_pages(struct 
linux_binprm *bprm,
                return ret;
 
        if (IS_ENABLED(CONFIG_COMPAT_VDSO)) {
-               ret = __setup_additional_pages(VDSO_ABI_AA32, mm, bprm,
-                                              uses_interp);
+               ret = __setup_additional_pages(VDSO_ABI_AA32, mm, sysinfo_ehdr);
                if (ret)
                        return ret;
        }
@@ -447,7 +446,7 @@ static int __init vdso_init(void)
 }
 arch_initcall(vdso_init);
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        int ret;
@@ -456,9 +455,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
                return -EINTR;
 
        if (is_compat_task())
-               ret = aarch32_setup_additional_pages(bprm, uses_interp);
+               ret = aarch32_setup_additional_pages(sysinfo_ehdr);
        else
-               ret = __setup_additional_pages(VDSO_ABI_AA64, mm, bprm, 
uses_interp);
+               ret = __setup_additional_pages(VDSO_ABI_AA64, mm, sysinfo_ehdr);
 
        mmap_write_unlock(mm);
 
diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c
index abc3dbc658d4..f72f76915c59 100644
--- a/arch/csky/kernel/vdso.c
+++ b/arch/csky/kernel/vdso.c
@@ -44,7 +44,7 @@ static int __init init_vdso(void)
 }
 subsys_initcall(init_vdso);
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        int ret;
        unsigned long addr;
@@ -68,6 +68,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
                goto up_fail;
 
        mm->context.vdso = (void *)addr;
+       *sysinfo_ehdr = addr;
 
 up_fail:
        mmap_write_unlock(mm);
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index b70970ac809f..39e78fe82b99 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -46,7 +46,7 @@ arch_initcall(vdso_init);
 /*
  * Called from binfmt_elf.  Create a VMA for the vDSO page.
  */
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        int ret;
        unsigned long vdso_base;
@@ -74,6 +74,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
                goto up_fail;
 
        mm->context.vdso = (void *)vdso_base;
+       *sysinfo_ehdr = vdso_base;
 
 up_fail:
        mmap_write_unlock(mm);
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 242dc5e83847..a4a321252df6 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -86,7 +86,7 @@ static unsigned long vdso_base(void)
        return base;
 }
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mips_vdso_image *image = current->thread.abi->vdso;
        struct mm_struct *mm = current->mm;
@@ -184,6 +184,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
        }
 
        mm->context.vdso = (void *)vdso_addr;
+       *sysinfo_ehdr = vdso_addr;
        ret = 0;
 
 out:
diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c
index e16009a07971..530164221166 100644
--- a/arch/nds32/kernel/vdso.c
+++ b/arch/nds32/kernel/vdso.c
@@ -111,7 +111,7 @@ unsigned long inline vdso_random_addr(unsigned long 
vdso_mapping_len)
        return addr;
 }
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
@@ -176,6 +176,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
        /*Map vdso to user space */
        vdso_base += PAGE_SIZE;
        mm->context.vdso = (void *)vdso_base;
+       *sysinfo_ehdr = vdso_base;
        vma = _install_special_mapping(mm, vdso_base, vdso_text_len,
                                       VM_READ | VM_EXEC |
                                       VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index 61862dbb0e32..e09e54198ac6 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -104,7 +104,7 @@ static int alloc_kuser_page(void)
 }
 arch_initcall(alloc_kuser_page);
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        int ret;
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 8dad44262e75..0ec3bbe7fb36 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -122,7 +122,7 @@ struct lib64_elfinfo
  * This is called from binfmt_elf, we create the special vma for the
  * vDSO and insert it into the mm struct tree
  */
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        struct page **vdso_pagelist;
@@ -211,6 +211,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
        }
 
        mmap_write_unlock(mm);
+       *sysinfo_ehdr = vdso_base;
        return 0;
 
  fail_mmapsem:
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 678204231700..d5c741e3cde6 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -56,11 +56,10 @@ static int __init vdso_init(void)
 }
 arch_initcall(vdso_init);
 
-int arch_setup_additional_pages(struct linux_binprm *bprm,
-       int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long vdso_base, vdso_len;
+       unsigned long vdso_base, vvar_base, vdso_len;
        int ret;
 
        vdso_len = (vdso_pages + 1) << PAGE_SHIFT;
@@ -89,12 +88,14 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
                goto end;
        }
 
-       vdso_base += (vdso_pages << PAGE_SHIFT);
+       vvar_base = vdso_base + (vdso_pages << PAGE_SHIFT);
        ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
                (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
 
        if (unlikely(ret))
                mm->context.vdso = NULL;
+       else
+               *sysinfo_ehdr = vdso_base;
 end:
        mmap_write_unlock(mm);
        return ret;
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 6c9ec9521203..810b72f8985c 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -150,7 +150,7 @@ void vdso_free_per_cpu(struct lowcore *lowcore)
  * This is called from binfmt_elf, we create the special vma for the
  * vDSO and insert it into the mm struct tree
  */
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
@@ -205,6 +205,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
        }
 
        current->mm->context.vdso_base = vdso_base;
+       *sysinfo_ehdr = vdso_base;
        rc = 0;
 
 out_up:
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c 
b/arch/sh/kernel/vsyscall/vsyscall.c
index 1bd85a6949c4..de8df3261b4f 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -55,7 +55,7 @@ int __init vsyscall_init(void)
 }
 
 /* Setup a VMA at program startup for the vsyscall page */
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        unsigned long addr;
@@ -78,6 +78,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, 
int uses_interp)
                goto up_fail;
 
        current->mm->context.vdso = (void *)addr;
+       *sysinfo_ehdr = addr;
 
 up_fail:
        mmap_write_unlock(mm);
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index cc19e09b0fa1..bf9195fe9bcc 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -346,8 +346,6 @@ static int __init init_vdso(void)
 }
 subsys_initcall(init_vdso);
 
-struct linux_binprm;
-
 /* Shuffle the vdso up a bit, randomly. */
 static unsigned long vdso_addr(unsigned long start, unsigned int len)
 {
@@ -359,7 +357,8 @@ static unsigned long vdso_addr(unsigned long start, 
unsigned int len)
 }
 
 static int map_vdso(const struct vdso_image *image,
-               struct vm_special_mapping *vdso_mapping)
+                   struct vm_special_mapping *vdso_mapping,
+                   unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
@@ -421,12 +420,14 @@ static int map_vdso(const struct vdso_image *image,
 up_fail:
        if (ret)
                current->mm->context.vdso = NULL;
+       else
+               *sysinfo_ehdr = text_start;
 
        mmap_write_unlock(mm);
        return ret;
 }
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
 
        if (!vdso_enabled)
@@ -434,11 +435,11 @@ int arch_setup_additional_pages(struct linux_binprm 
*bprm, int uses_interp)
 
 #if defined CONFIG_COMPAT
        if (!(is_32bit_task()))
-               return map_vdso(&vdso_image_64_builtin, &vdso_mapping64);
+               return map_vdso(&vdso_image_64_builtin, &vdso_mapping64, 
sysinfo_ehdr);
        else
-               return map_vdso(&vdso_image_32_builtin, &vdso_mapping32);
+               return map_vdso(&vdso_image_32_builtin, &vdso_mapping32, 
sysinfo_ehdr);
 #else
-       return map_vdso(&vdso_image_64_builtin, &vdso_mapping64);
+       return map_vdso(&vdso_image_64_builtin, &vdso_mapping64, sysinfo_ehdr);
 #endif
 
 }
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index aace862ed9a1..5b9020742e66 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -243,7 +243,8 @@ static const struct vm_special_mapping vvar_mapping = {
  * @image          - blob to map
  * @addr           - request a specific address (zero to map at free addr)
  */
-static int map_vdso(const struct vdso_image *image, unsigned long addr)
+static int map_vdso(const struct vdso_image *image, unsigned long addr,
+                   unsigned long *sysinfo_ehdr)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
@@ -290,6 +291,7 @@ static int map_vdso(const struct vdso_image *image, 
unsigned long addr)
        } else {
                current->mm->context.vdso = (void __user *)text_start;
                current->mm->context.vdso_image = image;
+               *sysinfo_ehdr = text_start;
        }
 
 up_fail:
@@ -342,11 +344,12 @@ static unsigned long vdso_addr(unsigned long start, 
unsigned len)
        return addr;
 }
 
-static int map_vdso_randomized(const struct vdso_image *image)
+static int map_vdso_randomized(const struct vdso_image *image,
+                              unsigned long *sysinfo_ehdr)
 {
        unsigned long addr = vdso_addr(current->mm->start_stack, 
image->size-image->sym_vvar_start);
 
-       return map_vdso(image, addr);
+       return map_vdso(image, addr, sysinfo_ehdr);
 }
 #endif
 
@@ -354,6 +357,7 @@ int map_vdso_once(const struct vdso_image *image, unsigned 
long addr)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
+       unsigned long unused;
 
        mmap_write_lock(mm);
        /*
@@ -372,19 +376,19 @@ int map_vdso_once(const struct vdso_image *image, 
unsigned long addr)
        }
        mmap_write_unlock(mm);
 
-       return map_vdso(image, addr);
+       return map_vdso(image, addr, &unused);
 }
 
 #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
-static int load_vdso_ia32(void)
+static int load_vdso_ia32(unsigned long *sysinfo_ehdr)
 {
        if (vdso32_enabled != 1)  /* Other values all mean "disabled" */
                return 0;
 
-       return map_vdso(&vdso_image_32, 0);
+       return map_vdso(&vdso_image_32, 0, sysinfo_ehdr);
 }
 #else
-static int load_vdso_ia32(void)
+static int load_vdso_ia32(unsigned long *sysinfo_ehdr)
 {
        WARN_ON_ONCE(1);
        return -ENODATA;
@@ -392,32 +396,32 @@ static int load_vdso_ia32(void)
 #endif
 
 #ifdef CONFIG_X86_64
-static int load_vdso_64(void)
+static int load_vdso_64(unsigned long *sysinfo_ehdr)
 {
        if (!vdso64_enabled)
                return 0;
 
 #ifdef CONFIG_X86_X32_ABI
        if (in_x32_syscall())
-               return map_vdso_randomized(&vdso_image_x32);
+               return map_vdso_randomized(&vdso_image_x32, sysinfo_ehdr);
 #endif
 
-       return map_vdso_randomized(&vdso_image_64);
+       return map_vdso_randomized(&vdso_image_64, sysinfo_ehdr);
 }
 #else
-static int load_vdso_64(void)
+static int load_vdso_64(unsigned long *sysinfo_ehdr)
 {
        WARN_ON_ONCE(1);
        return -ENODATA;
 }
 #endif
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        if (in_ia32_syscall())
-               return load_vdso_ia32();
+               return load_vdso_ia32(sysinfo_ehdr);
 
-       return load_vdso_64();
+       return load_vdso_64(sysinfo_ehdr);
 }
 
 #ifdef CONFIG_X86_64
diff --git a/arch/x86/um/vdso/vma.c b/arch/x86/um/vdso/vma.c
index 76d9f6ce7a3d..77488065f7cc 100644
--- a/arch/x86/um/vdso/vma.c
+++ b/arch/x86/um/vdso/vma.c
@@ -50,7 +50,7 @@ static int __init init_vdso(void)
 }
 subsys_initcall(init_vdso);
 
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+int arch_setup_additional_pages(unsigned long *sysinfo_ehdr)
 {
        int err;
        struct mm_struct *mm = current->mm;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b9adbeb59101..049ff514aa19 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -833,6 +833,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
        unsigned long interp_load_addr = 0;
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long reloc_func_desc __maybe_unused = 0;
+       unsigned long sysinfo_ehdr = 0;
        int executable_stack = EXSTACK_DEFAULT;
        struct elfhdr *elf_ex = (struct elfhdr *)bprm->buf;
        struct elfhdr *interp_elf_ex = NULL;
@@ -1249,7 +1250,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
 
        set_binfmt(&elf_format);
 
-       retval = arch_setup_additional_pages(bprm, !!interpreter);
+       retval = arch_setup_additional_pages(&sysinfo_ehdr);
        if (retval < 0)
                goto out;
 
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index b9a6d1b2b5bb..c9ee3c240855 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -183,6 +183,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
 {
        struct elf_fdpic_params exec_params, interp_params;
        struct pt_regs *regs = current_pt_regs();
+       unsigned long sysinfo_ehdr = 0;
        struct elf_phdr *phdr;
        unsigned long stack_size, entryaddr;
 #ifdef ELF_FDPIC_PLAT_INIT
@@ -375,7 +376,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
        if (retval < 0)
                goto error;
 
-       retval = arch_setup_additional_pages(bprm, !!interpreter_name);
+       retval = arch_setup_additional_pages(&sysinfo_ehdr);
        if (retval < 0)
                goto error;
 #endif
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 95bf7a1abaef..f9b561bb395d 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -104,13 +104,20 @@ static inline int arch_elf_adjust_prot(int prot,
 }
 #endif
 
-struct linux_binprm;
 #ifdef CONFIG_ARCH_HAS_SETUP_ADDITIONAL_PAGES
-extern int arch_setup_additional_pages(struct linux_binprm *bprm,
-                                      int uses_interp);
+/**
+ * arch_setup_additional_pages - Premap VMAs in a new-execed process
+ * @sysinfo_ehdr:      Returns vDSO position to be set in the initial
+ *                     auxiliary vector (tag AT_SYSINFO_EHDR) by binfmt
+ *                     loader. On failure isn't initialized.
+ *                     As address == 0 is never used, it allows to check
+ *                     if the tag should be set.
+ *
+ * Return: Zero if successful, or a negative error code on failure.
+ */
+extern int arch_setup_additional_pages(unsigned long *sysinfo_ehdr);
 #else
-static inline int arch_setup_additional_pages(struct linux_binprm *bprm,
-                                      int uses_interp)
+static inline int arch_setup_additional_pages(unsigned long *sysinfo_ehdr);
 {
        return 0;
 }
-- 
2.28.0

Reply via email to