The core mm code will provide a default gate area based on FIXADDR_USER_START and FIXADDR_USER_END if !defined(__HAVE_ARCH_GATE_AREA) && defined(AT_SYSINFO_EHDR). This default is only useful for ia64. arm64, ppc, s390, sh, tile, 64-bit UML, and x86_32 have their own code just to disable it. arm, 32-bit UML, and x86_64 have gate areas, but they have their own implementations. This gets rid of the default and moves the code into ia64. This should save some code on architectures without a gate area: it's now possible to inline the gate_area functions in the default case. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Acked-by: Nathan Lynch <nathan_lynch@mentor.com> Acked-by: H. Peter Anvin <hpa@linux.intel.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [in principle] Acked-by: Richard Weinberger <richard@nod.at> [for um] Acked-by: Will Deacon <will.deacon@arm.com> [for arm64] Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Chris Metcalf <cmetcalf@tilera.com> Cc: Jeff Dike <jdike@addtoit.com> Cc: Richard Weinberger <richard@nod.at> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Nathan Lynch <Nathan_Lynch@mentor.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			120 lines
		
	
	
	
		
			2.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
	
		
			2.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * (C) Copyright 2002 Linus Torvalds
 | 
						|
 * Portions based on the vdso-randomization code from exec-shield:
 | 
						|
 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
 | 
						|
 *
 | 
						|
 * This file contains the needed initializations to support sysenter.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/init.h>
 | 
						|
#include <linux/smp.h>
 | 
						|
#include <linux/kernel.h>
 | 
						|
#include <linux/mm_types.h>
 | 
						|
 | 
						|
#include <asm/cpufeature.h>
 | 
						|
#include <asm/processor.h>
 | 
						|
#include <asm/vdso.h>
 | 
						|
 | 
						|
#ifdef CONFIG_COMPAT_VDSO
 | 
						|
#define VDSO_DEFAULT	0
 | 
						|
#else
 | 
						|
#define VDSO_DEFAULT	1
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * Should the kernel map a VDSO page into processes and pass its
 | 
						|
 * address down to glibc upon exec()?
 | 
						|
 */
 | 
						|
unsigned int __read_mostly vdso32_enabled = VDSO_DEFAULT;
 | 
						|
 | 
						|
static int __init vdso32_setup(char *s)
 | 
						|
{
 | 
						|
	vdso32_enabled = simple_strtoul(s, NULL, 0);
 | 
						|
 | 
						|
	if (vdso32_enabled > 1)
 | 
						|
		pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n");
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * For consistency, the argument vdso32=[012] affects the 32-bit vDSO
 | 
						|
 * behavior on both 64-bit and 32-bit kernels.
 | 
						|
 * On 32-bit kernels, vdso=[012] means the same thing.
 | 
						|
 */
 | 
						|
__setup("vdso32=", vdso32_setup);
 | 
						|
 | 
						|
#ifdef CONFIG_X86_32
 | 
						|
__setup_param("vdso=", vdso_setup, vdso32_setup, 0);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef CONFIG_X86_64
 | 
						|
 | 
						|
#define	vdso32_sysenter()	(boot_cpu_has(X86_FEATURE_SYSENTER32))
 | 
						|
#define	vdso32_syscall()	(boot_cpu_has(X86_FEATURE_SYSCALL32))
 | 
						|
 | 
						|
#else  /* CONFIG_X86_32 */
 | 
						|
 | 
						|
#define vdso32_sysenter()	(boot_cpu_has(X86_FEATURE_SEP))
 | 
						|
#define vdso32_syscall()	(0)
 | 
						|
 | 
						|
#endif	/* CONFIG_X86_64 */
 | 
						|
 | 
						|
#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
 | 
						|
const struct vdso_image *selected_vdso32;
 | 
						|
#endif
 | 
						|
 | 
						|
int __init sysenter_setup(void)
 | 
						|
{
 | 
						|
#ifdef CONFIG_COMPAT
 | 
						|
	if (vdso32_syscall())
 | 
						|
		selected_vdso32 = &vdso_image_32_syscall;
 | 
						|
	else
 | 
						|
#endif
 | 
						|
	if (vdso32_sysenter())
 | 
						|
		selected_vdso32 = &vdso_image_32_sysenter;
 | 
						|
	else
 | 
						|
		selected_vdso32 = &vdso_image_32_int80;
 | 
						|
 | 
						|
	init_vdso_image(selected_vdso32);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CONFIG_X86_64
 | 
						|
 | 
						|
subsys_initcall(sysenter_setup);
 | 
						|
 | 
						|
#ifdef CONFIG_SYSCTL
 | 
						|
/* Register vsyscall32 into the ABI table */
 | 
						|
#include <linux/sysctl.h>
 | 
						|
 | 
						|
static struct ctl_table abi_table2[] = {
 | 
						|
	{
 | 
						|
		.procname	= "vsyscall32",
 | 
						|
		.data		= &vdso32_enabled,
 | 
						|
		.maxlen		= sizeof(int),
 | 
						|
		.mode		= 0644,
 | 
						|
		.proc_handler	= proc_dointvec
 | 
						|
	},
 | 
						|
	{}
 | 
						|
};
 | 
						|
 | 
						|
static struct ctl_table abi_root_table2[] = {
 | 
						|
	{
 | 
						|
		.procname = "abi",
 | 
						|
		.mode = 0555,
 | 
						|
		.child = abi_table2
 | 
						|
	},
 | 
						|
	{}
 | 
						|
};
 | 
						|
 | 
						|
static __init int ia32_binfmt_init(void)
 | 
						|
{
 | 
						|
	register_sysctl_table(abi_root_table2);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
__initcall(ia32_binfmt_init);
 | 
						|
#endif /* CONFIG_SYSCTL */
 | 
						|
 | 
						|
#endif	/* CONFIG_X86_64 */
 |