aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-10-29 17:33:47 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-11-03 15:44:57 -0500
commit1ad83c858c7d4ea210429142c99a1548e6715a35 (patch)
tree9c40dd5e49b646ae68e252c9a3e8afbd01a6a588
parent95c46b56922409ed8838b3b420b11cfebb8c6c88 (diff)
x86_64,vsyscall: Make vsyscall emulation configurable
This adds CONFIG_X86_VSYSCALL_EMULATION, guarded by CONFIG_EXPERT. Turning it off completely disables vsyscall emulation, saving ~3.5k for vsyscall_64.c, 4k for vsyscall_emu_64.S (the fake vsyscall page), some tiny amount of core mm code that supports a gate area, and possibly 4k for a wasted pagetable. The latter is because the vsyscall addresses are misaligned and fit poorly in the fixmap. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Link: http://lkml.kernel.org/r/406db88b8dd5f0cbbf38216d11be34bbb43c7eae.1414618407.git.luto@amacapital.net Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/Kconfig18
-rw-r--r--arch/x86/include/asm/fixmap.h2
-rw-r--r--arch/x86/include/asm/page_64.h4
-rw-r--r--arch/x86/include/asm/vsyscall.h8
-rw-r--r--arch/x86/kernel/Makefile3
-rw-r--r--arch/x86/kernel/setup.c2
-rw-r--r--arch/x86/xen/mmu.c6
7 files changed, 36 insertions, 7 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f2327e88e07c..cd10436d7d1c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -984,6 +984,24 @@ config X86_ESPFIX64
984 def_bool y 984 def_bool y
985 depends on X86_16BIT && X86_64 985 depends on X86_16BIT && X86_64
986 986
987config X86_VSYSCALL_EMULATION
988 bool "Enable vsyscall emulation" if EXPERT
989 default y
990 depends on X86_64
991 ---help---
992 This enables emulation of the legacy vsyscall page. Disabling
993 it is roughly equivalent to booting with vsyscall=none, except
994 that it will also disable the helpful warning if a program
995 tries to use a vsyscall. With this option set to N, offending
996 programs will just segfault, citing addresses of the form
997 0xffffffffff600?00.
998
999 This option is required by many programs built before 2013, and
1000 care should be used even with newer programs if set to N.
1001
1002 Disabling this option saves about 7K of kernel size and
1003 possibly 4K of additional runtime pagetable memory.
1004
987config TOSHIBA 1005config TOSHIBA
988 tristate "Toshiba Laptop support" 1006 tristate "Toshiba Laptop support"
989 depends on X86_32 1007 depends on X86_32
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index ffb1733ac91f..d8d5bcb2a0b5 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -69,7 +69,9 @@ enum fixed_addresses {
69#ifdef CONFIG_X86_32 69#ifdef CONFIG_X86_32
70 FIX_HOLE, 70 FIX_HOLE,
71#else 71#else
72#ifdef CONFIG_X86_VSYSCALL_EMULATION
72 VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT, 73 VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
74#endif
73#ifdef CONFIG_PARAVIRT_CLOCK 75#ifdef CONFIG_PARAVIRT_CLOCK
74 PVCLOCK_FIXMAP_BEGIN, 76 PVCLOCK_FIXMAP_BEGIN,
75 PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1, 77 PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index f408caf73430..b3bebf9e5746 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -39,6 +39,8 @@ void copy_page(void *to, void *from);
39 39
40#endif /* !__ASSEMBLY__ */ 40#endif /* !__ASSEMBLY__ */
41 41
42#define __HAVE_ARCH_GATE_AREA 1 42#ifdef CONFIG_X86_VSYSCALL_EMULATION
43# define __HAVE_ARCH_GATE_AREA 1
44#endif
43 45
44#endif /* _ASM_X86_PAGE_64_H */ 46#endif /* _ASM_X86_PAGE_64_H */
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index 34f7d8857542..6ba66ee79710 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -4,6 +4,7 @@
4#include <linux/seqlock.h> 4#include <linux/seqlock.h>
5#include <uapi/asm/vsyscall.h> 5#include <uapi/asm/vsyscall.h>
6 6
7#ifdef CONFIG_X86_VSYSCALL_EMULATION
7extern void map_vsyscall(void); 8extern void map_vsyscall(void);
8 9
9/* 10/*
@@ -11,5 +12,12 @@ extern void map_vsyscall(void);
11 * Returns true if handled. 12 * Returns true if handled.
12 */ 13 */
13extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); 14extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
15#else
16static inline void map_vsyscall(void) {}
17static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
18{
19 return false;
20}
21#endif
14 22
15#endif /* _ASM_X86_VSYSCALL_H */ 23#endif /* _ASM_X86_VSYSCALL_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8f1e77440b2b..5d4502c8b983 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -28,8 +28,7 @@ obj-$(CONFIG_X86_32) += i386_ksyms_32.o
28obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 28obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
29obj-$(CONFIG_X86_64) += mcount_64.o 29obj-$(CONFIG_X86_64) += mcount_64.o
30obj-y += syscall_$(BITS).o vsyscall_gtod.o 30obj-y += syscall_$(BITS).o vsyscall_gtod.o
31obj-$(CONFIG_X86_64) += vsyscall_64.o 31obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o
32obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
33obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o 32obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
34obj-$(CONFIG_SYSFS) += ksysfs.o 33obj-$(CONFIG_SYSFS) += ksysfs.o
35obj-y += bootflag.o e820.o 34obj-y += bootflag.o e820.o
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 235cfd39e0d7..59a6f884fdad 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1190,9 +1190,7 @@ void __init setup_arch(char **cmdline_p)
1190 1190
1191 tboot_probe(); 1191 tboot_probe();
1192 1192
1193#ifdef CONFIG_X86_64
1194 map_vsyscall(); 1193 map_vsyscall();
1195#endif
1196 1194
1197 generic_apic_probe(); 1195 generic_apic_probe();
1198 1196
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index a8a1a3d08d4d..8906cf0e536f 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1457,8 +1457,10 @@ static int xen_pgd_alloc(struct mm_struct *mm)
1457 page->private = (unsigned long)user_pgd; 1457 page->private = (unsigned long)user_pgd;
1458 1458
1459 if (user_pgd != NULL) { 1459 if (user_pgd != NULL) {
1460#ifdef CONFIG_X86_VSYSCALL_EMULATION
1460 user_pgd[pgd_index(VSYSCALL_ADDR)] = 1461 user_pgd[pgd_index(VSYSCALL_ADDR)] =
1461 __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE); 1462 __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
1463#endif
1462 ret = 0; 1464 ret = 0;
1463 } 1465 }
1464 1466
@@ -2021,7 +2023,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2021# ifdef CONFIG_HIGHMEM 2023# ifdef CONFIG_HIGHMEM
2022 case FIX_KMAP_BEGIN ... FIX_KMAP_END: 2024 case FIX_KMAP_BEGIN ... FIX_KMAP_END:
2023# endif 2025# endif
2024#else 2026#elif defined(CONFIG_X86_VSYSCALL_EMULATION)
2025 case VSYSCALL_PAGE: 2027 case VSYSCALL_PAGE:
2026#endif 2028#endif
2027 case FIX_TEXT_POKE0: 2029 case FIX_TEXT_POKE0:
@@ -2060,7 +2062,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2060 2062
2061 __native_set_fixmap(idx, pte); 2063 __native_set_fixmap(idx, pte);
2062 2064
2063#ifdef CONFIG_X86_64 2065#ifdef CONFIG_X86_VSYSCALL_EMULATION
2064 /* Replicate changes to map the vsyscall page into the user 2066 /* Replicate changes to map the vsyscall page into the user
2065 pagetable vsyscall mapping. */ 2067 pagetable vsyscall mapping. */
2066 if (idx == VSYSCALL_PAGE) { 2068 if (idx == VSYSCALL_PAGE) {