diff options
| author | Andy Lutomirski <luto@amacapital.net> | 2014-10-29 17:33:47 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2014-11-03 15:44:57 -0500 |
| commit | 1ad83c858c7d4ea210429142c99a1548e6715a35 (patch) | |
| tree | 9c40dd5e49b646ae68e252c9a3e8afbd01a6a588 | |
| parent | 95c46b56922409ed8838b3b420b11cfebb8c6c88 (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/Kconfig | 18 | ||||
| -rw-r--r-- | arch/x86/include/asm/fixmap.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/page_64.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/vsyscall.h | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 2 | ||||
| -rw-r--r-- | arch/x86/xen/mmu.c | 6 |
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 | ||
| 987 | config 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 | |||
| 987 | config TOSHIBA | 1005 | config 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 | ||
| 7 | extern void map_vsyscall(void); | 8 | extern 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 | */ |
| 13 | extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); | 14 | extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); |
| 15 | #else | ||
| 16 | static inline void map_vsyscall(void) {} | ||
| 17 | static 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 | |||
| 28 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o | 28 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o |
| 29 | obj-$(CONFIG_X86_64) += mcount_64.o | 29 | obj-$(CONFIG_X86_64) += mcount_64.o |
| 30 | obj-y += syscall_$(BITS).o vsyscall_gtod.o | 30 | obj-y += syscall_$(BITS).o vsyscall_gtod.o |
| 31 | obj-$(CONFIG_X86_64) += vsyscall_64.o | 31 | obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o |
| 32 | obj-$(CONFIG_X86_64) += vsyscall_emu_64.o | ||
| 33 | obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o | 32 | obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o |
| 34 | obj-$(CONFIG_SYSFS) += ksysfs.o | 33 | obj-$(CONFIG_SYSFS) += ksysfs.o |
| 35 | obj-y += bootflag.o e820.o | 34 | obj-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) { |
