vdso_base = VDSO64_MBASE;
        }
 
+       current->thread.vdso_base = 0;
+
        /* vDSO has a problem and was disabled, just don't "enable" it for the
         * process
         */
-       if (vdso_pages == 0) {
-               current->thread.vdso_base = 0;
+       if (vdso_pages == 0)
                return 0;
-       }
+
        vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
        if (vma == NULL)
                return -ENOMEM;
        memset(vma, 0, sizeof(*vma));
 
        /*
-        * pick a base address for the vDSO in process space. We have a default
-        * base of 1Mb on which we had a random offset up to 1Mb.
-        * XXX: Add possibility for a program header to specify that location
+        * pick a base address for the vDSO in process space. We try to put it
+        * at vdso_base which is the "natural" base for it, but we might fail
+        * and end up putting it elsewhere.
         */
+       vdso_base = get_unmapped_area(NULL, vdso_base,
+                                     vdso_pages << PAGE_SHIFT, 0, 0);
+       if (vdso_base & ~PAGE_MASK)
+               return (int)vdso_base;
+
        current->thread.vdso_base = vdso_base;
-       /*  + ((unsigned long)vma & 0x000ff000); */
 
        vma->vm_mm = mm;
        vma->vm_start = current->thread.vdso_base;
 
                goto out_free_dentry;
        }
        
-#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
-       retval = arch_setup_additional_pages(bprm, executable_stack);
-       if (retval < 0) {
-               send_sig(SIGKILL, current, 0);
-               goto out_free_dentry;
-       }
-#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
-
        current->mm->start_stack = bprm->p;
 
        /* Now we do a little grungy work by mmaping the ELF image into
 
        set_binfmt(&elf_format);
 
+#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
+       retval = arch_setup_additional_pages(bprm, executable_stack);
+       if (retval < 0) {
+               send_sig(SIGKILL, current, 0);
+               goto out_free_dentry;
+       }
+#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
+
        compute_creds(bprm);
        current->flags &= ~PF_FORKNOEXEC;
        create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
 
 #ifdef __KERNEL__
 
 /* Default link addresses for the vDSOs */
-#define VDSO32_LBASE   0
-#define VDSO64_LBASE   0
+#define VDSO32_LBASE   0x100000
+#define VDSO64_LBASE   0x100000
 
 /* Default map addresses */
-#define VDSO32_MBASE   0x100000
-#define VDSO64_MBASE   0x100000
+#define VDSO32_MBASE   VDSO32_LBASE
+#define VDSO64_MBASE   VDSO64_LBASE
 
 #define VDSO_VERSION_STRING    LINUX_2.6.12