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>
This commit is contained in:
parent
95c46b5692
commit
1ad83c858c
|
@ -984,6 +984,24 @@ config X86_ESPFIX64
|
|||
def_bool y
|
||||
depends on X86_16BIT && X86_64
|
||||
|
||||
config X86_VSYSCALL_EMULATION
|
||||
bool "Enable vsyscall emulation" if EXPERT
|
||||
default y
|
||||
depends on X86_64
|
||||
---help---
|
||||
This enables emulation of the legacy vsyscall page. Disabling
|
||||
it is roughly equivalent to booting with vsyscall=none, except
|
||||
that it will also disable the helpful warning if a program
|
||||
tries to use a vsyscall. With this option set to N, offending
|
||||
programs will just segfault, citing addresses of the form
|
||||
0xffffffffff600?00.
|
||||
|
||||
This option is required by many programs built before 2013, and
|
||||
care should be used even with newer programs if set to N.
|
||||
|
||||
Disabling this option saves about 7K of kernel size and
|
||||
possibly 4K of additional runtime pagetable memory.
|
||||
|
||||
config TOSHIBA
|
||||
tristate "Toshiba Laptop support"
|
||||
depends on X86_32
|
||||
|
|
|
@ -69,7 +69,9 @@ enum fixed_addresses {
|
|||
#ifdef CONFIG_X86_32
|
||||
FIX_HOLE,
|
||||
#else
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
|
||||
#endif
|
||||
#ifdef CONFIG_PARAVIRT_CLOCK
|
||||
PVCLOCK_FIXMAP_BEGIN,
|
||||
PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
|
||||
|
|
|
@ -39,6 +39,8 @@ void copy_page(void *to, void *from);
|
|||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define __HAVE_ARCH_GATE_AREA 1
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
# define __HAVE_ARCH_GATE_AREA 1
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_PAGE_64_H */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <linux/seqlock.h>
|
||||
#include <uapi/asm/vsyscall.h>
|
||||
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
extern void map_vsyscall(void);
|
||||
|
||||
/*
|
||||
|
@ -11,5 +12,12 @@ extern void map_vsyscall(void);
|
|||
* Returns true if handled.
|
||||
*/
|
||||
extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
|
||||
#else
|
||||
static inline void map_vsyscall(void) {}
|
||||
static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_VSYSCALL_H */
|
||||
|
|
|
@ -28,8 +28,7 @@ obj-$(CONFIG_X86_32) += i386_ksyms_32.o
|
|||
obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
|
||||
obj-$(CONFIG_X86_64) += mcount_64.o
|
||||
obj-y += syscall_$(BITS).o vsyscall_gtod.o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_64.o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
|
||||
obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o
|
||||
obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
|
||||
obj-$(CONFIG_SYSFS) += ksysfs.o
|
||||
obj-y += bootflag.o e820.o
|
||||
|
|
|
@ -1190,9 +1190,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
tboot_probe();
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
map_vsyscall();
|
||||
#endif
|
||||
|
||||
generic_apic_probe();
|
||||
|
||||
|
|
|
@ -1457,8 +1457,10 @@ static int xen_pgd_alloc(struct mm_struct *mm)
|
|||
page->private = (unsigned long)user_pgd;
|
||||
|
||||
if (user_pgd != NULL) {
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
user_pgd[pgd_index(VSYSCALL_ADDR)] =
|
||||
__pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
|
||||
#endif
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
@ -2021,7 +2023,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
|||
# ifdef CONFIG_HIGHMEM
|
||||
case FIX_KMAP_BEGIN ... FIX_KMAP_END:
|
||||
# endif
|
||||
#else
|
||||
#elif defined(CONFIG_X86_VSYSCALL_EMULATION)
|
||||
case VSYSCALL_PAGE:
|
||||
#endif
|
||||
case FIX_TEXT_POKE0:
|
||||
|
@ -2060,7 +2062,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
|||
|
||||
__native_set_fixmap(idx, pte);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
/* Replicate changes to map the vsyscall page into the user
|
||||
pagetable vsyscall mapping. */
|
||||
if (idx == VSYSCALL_PAGE) {
|
||||
|
|
Loading…
Reference in New Issue