Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af65d648 authored by Roland McGrath's avatar Roland McGrath Committed by Ingo Molnar
Browse files

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: default avatarRoland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 00f8b1bc
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1988,6 +1988,11 @@ and is between 256 and 4096 characters. It is defined in the file
			vdso=1: enable VDSO (default)
			vdso=0: disable VDSO mapping

	vdso32=		[X86-32,X86-64]
			vdso32=2: enable compat VDSO (default with COMPAT_VDSO)
			vdso32=1: enable 32-bit VDSO (default)
			vdso32=0: disable 32-bit VDSO mapping

	vector=		[IA-64,SMP]
			vector=percpu: enable percpu vector domain

+2 −2
Original line number Diff line number Diff line
@@ -1191,9 +1191,9 @@ config HOTPLUG_CPU
config COMPAT_VDSO
	bool "Compat VDSO support"
	default y
	depends on X86_32
	depends on X86_32 || IA32_EMULATION
	help
	  Map the VDSO to the predictable old-style address too.
	  Map the 32-bit VDSO to the predictable old-style address too.
	---help---
	  Say N here if you are running a sufficiently recent glibc
	  version (2.3.3 or later), to remove the high-mapped
+1 −1
Original line number Diff line number Diff line
@@ -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)
+4 −5
Original line number Diff line number Diff line
@@ -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)

+14 −8
Original line number Diff line number Diff line
@@ -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 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
			goto give_sigsegv;
	}

	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 = VSYSCALL32_SIGRETURN;
			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
						 sigreturn);
		else
			restorer = (void *)&frame->retcode;
	if (ka->sa.sa_flags & SA_RESTORER)
		restorer = ka->sa.sa_restorer;
	}
	err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);

	/*
@@ -519,7 +522,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
{
	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 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,

	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);

	/*
Loading