aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/ia32
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-01-30 07:30:43 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:30:43 -0500
commitaf65d64845a90c8f2fc90b97e2148ff74672e979 (patch)
treee70a57a9635acaf8154c150f95e11dcb51937fd8 /arch/x86/ia32
parent00f8b1bc0e44ba94fb33e1fbd8ac82841d7cc570 (diff)
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>
Diffstat (limited to 'arch/x86/ia32')
-rw-r--r--arch/x86/ia32/Makefile2
-rw-r--r--arch/x86/ia32/ia32_binfmt.c9
-rw-r--r--arch/x86/ia32/ia32_signal.c22
3 files changed, 19 insertions, 14 deletions
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index a3c997e9f39a..1f58a21a41dc 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \ 5obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \
6 ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o 6 ia32_binfmt.o fpu32.o ptrace32.o
7 7
8sysv-$(CONFIG_SYSVIPC) := ipc32.o 8sysv-$(CONFIG_SYSVIPC) := ipc32.o
9obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) 9obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index 55822d2cf053..e32974c3dd3b 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -26,7 +26,7 @@
26#include <asm/i387.h> 26#include <asm/i387.h>
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <asm/ia32.h> 28#include <asm/ia32.h>
29#include <asm/vsyscall32.h> 29#include <asm/vdso.h>
30 30
31#undef ELF_ARCH 31#undef ELF_ARCH
32#undef ELF_CLASS 32#undef ELF_CLASS
@@ -47,14 +47,13 @@
47#define AT_SYSINFO 32 47#define AT_SYSINFO 32
48#define AT_SYSINFO_EHDR 33 48#define AT_SYSINFO_EHDR 33
49 49
50int sysctl_vsyscall32 = 1; 50extern int sysctl_vsyscall32;
51 51
52#undef ARCH_DLINFO 52#undef ARCH_DLINFO
53#define ARCH_DLINFO do { \ 53#define ARCH_DLINFO do { \
54 if (sysctl_vsyscall32) { \ 54 if (sysctl_vsyscall32) { \
55 current->mm->context.vdso = (void *)VSYSCALL32_BASE; \ 55 NEW_AUX_ENT(AT_SYSINFO, (u32)VDSO_ENTRY); \
56 NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \ 56 NEW_AUX_ENT(AT_SYSINFO_EHDR, (u32)VDSO_CURRENT_BASE); \
57 NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
58 } \ 57 } \
59} while(0) 58} while(0)
60 59
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 0fc5d8563e19..39356a756b28 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -31,7 +31,7 @@
31#include <asm/sigcontext32.h> 31#include <asm/sigcontext32.h>
32#include <asm/fpu32.h> 32#include <asm/fpu32.h>
33#include <asm/proto.h> 33#include <asm/proto.h>
34#include <asm/vsyscall32.h> 34#include <asm/vdso.h>
35 35
36#define DEBUG_SIG 0 36#define DEBUG_SIG 0
37 37
@@ -465,13 +465,16 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
465 goto give_sigsegv; 465 goto give_sigsegv;
466 } 466 }
467 467
468 /* Return stub is in 32bit vsyscall page */ 468 if (ka->sa.sa_flags & SA_RESTORER) {
469 if (current->binfmt->hasvdso)
470 restorer = VSYSCALL32_SIGRETURN;
471 else
472 restorer = (void *)&frame->retcode;
473 if (ka->sa.sa_flags & SA_RESTORER)
474 restorer = ka->sa.sa_restorer; 469 restorer = ka->sa.sa_restorer;
470 } else {
471 /* Return stub is in 32bit vsyscall page */
472 if (current->binfmt->hasvdso)
473 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
474 sigreturn);
475 else
476 restorer = (void *)&frame->retcode;
477 }
475 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode); 478 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
476 479
477 /* 480 /*
@@ -519,7 +522,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
519{ 522{
520 struct rt_sigframe __user *frame; 523 struct rt_sigframe __user *frame;
521 struct exec_domain *ed = current_thread_info()->exec_domain; 524 struct exec_domain *ed = current_thread_info()->exec_domain;
522 void __user *restorer = VSYSCALL32_RTSIGRETURN; 525 void __user *restorer;
523 int err = 0; 526 int err = 0;
524 527
525 /* __copy_to_user optimizes that into a single 8 byte store */ 528 /* __copy_to_user optimizes that into a single 8 byte store */
@@ -564,6 +567,9 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
564 567
565 if (ka->sa.sa_flags & SA_RESTORER) 568 if (ka->sa.sa_flags & SA_RESTORER)
566 restorer = ka->sa.sa_restorer; 569 restorer = ka->sa.sa_restorer;
570 else
571 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
572 rt_sigreturn);
567 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode); 573 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
568 574
569 /* 575 /*