x86 vDSO: consolidate vdso32

This makes x86_64's ia32 emulation support share the sources used in the
32-bit kernel for the 32-bit vDSO and much of its setup code.

The 32-bit vDSO mapping now behaves the same on x86_64 as on native 32-bit.
The abi.syscall32 sysctl on x86_64 now takes the same values that
vm.vdso_enabled takes on the 32-bit kernel.  That is, 1 means a randomized
vDSO location, 2 means the fixed old address.  The CONFIG_COMPAT_VDSO
option is now available to make this the default setting, the same meaning
it has for the 32-bit kernel.  (This does not affect the 64-bit vDSO.)

The argument vdso32=[012] can be used on both 32-bit and 64-bit kernels to
set this paramter at boot time.  The vdso=[012] argument still does this
same thing on the 32-bit kernel.

Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index a3c997e..1f58a21 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \
-	ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o
+	ia32_binfmt.o fpu32.o ptrace32.o
 
 sysv-$(CONFIG_SYSVIPC) := ipc32.o
 obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index 55822d2..e32974c 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -26,7 +26,7 @@
 #include <asm/i387.h>
 #include <asm/uaccess.h>
 #include <asm/ia32.h>
-#include <asm/vsyscall32.h>
+#include <asm/vdso.h>
 
 #undef	ELF_ARCH
 #undef	ELF_CLASS
@@ -47,14 +47,13 @@
 #define AT_SYSINFO 32
 #define AT_SYSINFO_EHDR		33
 
-int sysctl_vsyscall32 = 1;
+extern int sysctl_vsyscall32;
 
 #undef ARCH_DLINFO
 #define ARCH_DLINFO do {  \
 	if (sysctl_vsyscall32) { \
-		current->mm->context.vdso = (void *)VSYSCALL32_BASE;	\
-		NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE);    \
+		NEW_AUX_ENT(AT_SYSINFO, (u32)VDSO_ENTRY);		\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, (u32)VDSO_CURRENT_BASE);	\
 	}	\
 } while(0)
 
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 0fc5d85..39356a7 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -31,7 +31,7 @@
 #include <asm/sigcontext32.h>
 #include <asm/fpu32.h>
 #include <asm/proto.h>
-#include <asm/vsyscall32.h>
+#include <asm/vdso.h>
 
 #define DEBUG_SIG 0
 
@@ -465,13 +465,16 @@
 			goto give_sigsegv;
 	}
 
-	/* Return stub is in 32bit vsyscall page */
-	if (current->binfmt->hasvdso)
-		restorer = VSYSCALL32_SIGRETURN;
-	else
-		restorer = (void *)&frame->retcode;
-	if (ka->sa.sa_flags & SA_RESTORER)
+	if (ka->sa.sa_flags & SA_RESTORER) {
 		restorer = ka->sa.sa_restorer;
+	} else {
+		/* Return stub is in 32bit vsyscall page */
+		if (current->binfmt->hasvdso)
+			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+						 sigreturn);
+		else
+			restorer = (void *)&frame->retcode;
+	}
 	err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
 
 	/*
@@ -519,7 +522,7 @@
 {
 	struct rt_sigframe __user *frame;
 	struct exec_domain *ed = current_thread_info()->exec_domain;
-	void __user *restorer = VSYSCALL32_RTSIGRETURN;
+	void __user *restorer;
 	int err = 0;
 
 	/* __copy_to_user optimizes that into a single 8 byte store */
@@ -564,6 +567,9 @@
 
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
+	else
+		restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+					 rt_sigreturn);
 	err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
 
 	/*