#include <asm/vdso.h>
 
-extern unsigned int vdso_enabled;
+#ifdef CONFIG_X86_64
+extern unsigned int vdso64_enabled;
+#endif
+#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
+extern unsigned int vdso32_enabled;
+#endif
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
 
 struct task_struct;
 
-#define        ARCH_DLINFO_IA32(vdso_enabled)                                  \
+#define        ARCH_DLINFO_IA32                                                \
 do {                                                                   \
-       if (vdso_enabled) {                                             \
+       if (vdso32_enabled) {                                           \
                NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY);                    \
                NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);        \
        }                                                               \
 
 #define STACK_RND_MASK (0x7ff)
 
-#define ARCH_DLINFO            ARCH_DLINFO_IA32(vdso_enabled)
+#define ARCH_DLINFO            ARCH_DLINFO_IA32
 
 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 
 
 #define ARCH_DLINFO                                                    \
 do {                                                                   \
-       if (vdso_enabled)                                               \
+       if (vdso64_enabled)                                             \
                NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
                            (unsigned long)current->mm->context.vdso);  \
 } while (0)
 
+/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
 #define ARCH_DLINFO_X32                                                        \
 do {                                                                   \
-       if (vdso_enabled)                                               \
+       if (vdso64_enabled)                                             \
                NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
                            (unsigned long)current->mm->context.vdso);  \
 } while (0)
 if (test_thread_flag(TIF_X32))                                         \
        ARCH_DLINFO_X32;                                                \
 else                                                                   \
-       ARCH_DLINFO_IA32(sysctl_vsyscall32)
+       ARCH_DLINFO_IA32
 
 #define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
 
 
 #include <asm/page.h>
 #include <linux/init.h>
 
-unsigned int __read_mostly vdso_enabled = 1;
+static unsigned int __read_mostly vdso_enabled = 1;
 unsigned long um_vdso_addr;
 
 extern unsigned long task_size;
 
 #endif
 
 #ifdef CONFIG_X86_64
-#define vdso_enabled                   sysctl_vsyscall32
 #define arch_setup_additional_pages    syscall32_setup_pages
 #endif
 
  * Should the kernel map a VDSO page into processes and pass its
  * address down to glibc upon exec()?
  */
-unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT;
+unsigned int __read_mostly vdso32_enabled = VDSO_DEFAULT;
 
-static int __init vdso_setup(char *s)
+static int __init vdso32_setup(char *s)
 {
-       vdso_enabled = simple_strtoul(s, NULL, 0);
+       vdso32_enabled = simple_strtoul(s, NULL, 0);
 
-       if (vdso_enabled > 1)
+       if (vdso32_enabled > 1)
                pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n");
 
        return 1;
  * behavior on both 64-bit and 32-bit kernels.
  * On 32-bit kernels, vdso=[012] means the same thing.
  */
-__setup("vdso32=", vdso_setup);
+__setup("vdso32=", vdso32_setup);
 
 #ifdef CONFIG_X86_32
-__setup_param("vdso=", vdso32_setup, vdso_setup, 0);
-
-EXPORT_SYMBOL_GPL(vdso_enabled);
+__setup_param("vdso=", vdso_setup, vdso32_setup, 0);
 #endif
 
 static struct page **vdso32_pages;
                return x32_setup_additional_pages(bprm, uses_interp);
 #endif
 
-       if (vdso_enabled != 1)  /* Other values all mean "disabled" */
+       if (vdso32_enabled != 1)  /* Other values all mean "disabled" */
                return 0;
 
        down_write(&mm->mmap_sem);
 static struct ctl_table abi_table2[] = {
        {
                .procname       = "vsyscall32",
-               .data           = &sysctl_vsyscall32,
+               .data           = &vdso32_enabled,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec
 
 #include <asm/page.h>
 
 #if defined(CONFIG_X86_64)
-unsigned int __read_mostly vdso_enabled = 1;
+unsigned int __read_mostly vdso64_enabled = 1;
 
 DECLARE_VDSO_IMAGE(vdso);
 extern unsigned short vdso_sync_cpuid;
        unsigned long addr;
        int ret;
 
-       if (!vdso_enabled)
+       if (!vdso64_enabled)
                return 0;
 
        down_write(&mm->mmap_sem);
 
 static __init int vdso_setup(char *s)
 {
-       vdso_enabled = simple_strtoul(s, NULL, 0);
+       vdso64_enabled = simple_strtoul(s, NULL, 0);
        return 0;
 }
 __setup("vdso=", vdso_setup);
 
    (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
        {
                .procname       = "vdso_enabled",
+#ifdef CONFIG_X86_32
+               .data           = &vdso32_enabled,
+               .maxlen         = sizeof(vdso32_enabled),
+#else
                .data           = &vdso_enabled,
                .maxlen         = sizeof(vdso_enabled),
+#endif
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
                .extra1         = &zero,