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
|
def_bool y
|
||||||
depends on X86_16BIT && X86_64
|
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
|
config TOSHIBA
|
||||||
tristate "Toshiba Laptop support"
|
tristate "Toshiba Laptop support"
|
||||||
depends on X86_32
|
depends on X86_32
|
||||||
|
|
|
@ -69,7 +69,9 @@ enum fixed_addresses {
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
FIX_HOLE,
|
FIX_HOLE,
|
||||||
#else
|
#else
|
||||||
|
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||||
VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
|
VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_PARAVIRT_CLOCK
|
#ifdef CONFIG_PARAVIRT_CLOCK
|
||||||
PVCLOCK_FIXMAP_BEGIN,
|
PVCLOCK_FIXMAP_BEGIN,
|
||||||
PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
|
PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
|
||||||
|
|
|
@ -39,6 +39,8 @@ void copy_page(void *to, void *from);
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#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 */
|
#endif /* _ASM_X86_PAGE_64_H */
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <linux/seqlock.h>
|
#include <linux/seqlock.h>
|
||||||
#include <uapi/asm/vsyscall.h>
|
#include <uapi/asm/vsyscall.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||||
extern void map_vsyscall(void);
|
extern void map_vsyscall(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -11,5 +12,12 @@ extern void map_vsyscall(void);
|
||||||
* Returns true if handled.
|
* Returns true if handled.
|
||||||
*/
|
*/
|
||||||
extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
|
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 */
|
#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) += sys_x86_64.o x8664_ksyms_64.o
|
||||||
obj-$(CONFIG_X86_64) += mcount_64.o
|
obj-$(CONFIG_X86_64) += mcount_64.o
|
||||||
obj-y += syscall_$(BITS).o vsyscall_gtod.o
|
obj-y += syscall_$(BITS).o vsyscall_gtod.o
|
||||||
obj-$(CONFIG_X86_64) += vsyscall_64.o
|
obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o
|
||||||
obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
|
|
||||||
obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
|
obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
|
||||||
obj-$(CONFIG_SYSFS) += ksysfs.o
|
obj-$(CONFIG_SYSFS) += ksysfs.o
|
||||||
obj-y += bootflag.o e820.o
|
obj-y += bootflag.o e820.o
|
||||||
|
|
|
@ -1190,9 +1190,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
tboot_probe();
|
tboot_probe();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
map_vsyscall();
|
map_vsyscall();
|
||||||
#endif
|
|
||||||
|
|
||||||
generic_apic_probe();
|
generic_apic_probe();
|
||||||
|
|
||||||
|
|
|
@ -1457,8 +1457,10 @@ static int xen_pgd_alloc(struct mm_struct *mm)
|
||||||
page->private = (unsigned long)user_pgd;
|
page->private = (unsigned long)user_pgd;
|
||||||
|
|
||||||
if (user_pgd != NULL) {
|
if (user_pgd != NULL) {
|
||||||
|
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||||
user_pgd[pgd_index(VSYSCALL_ADDR)] =
|
user_pgd[pgd_index(VSYSCALL_ADDR)] =
|
||||||
__pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
|
__pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
|
||||||
|
#endif
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2021,7 +2023,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
||||||
# ifdef CONFIG_HIGHMEM
|
# ifdef CONFIG_HIGHMEM
|
||||||
case FIX_KMAP_BEGIN ... FIX_KMAP_END:
|
case FIX_KMAP_BEGIN ... FIX_KMAP_END:
|
||||||
# endif
|
# endif
|
||||||
#else
|
#elif defined(CONFIG_X86_VSYSCALL_EMULATION)
|
||||||
case VSYSCALL_PAGE:
|
case VSYSCALL_PAGE:
|
||||||
#endif
|
#endif
|
||||||
case FIX_TEXT_POKE0:
|
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);
|
__native_set_fixmap(idx, pte);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||||
/* Replicate changes to map the vsyscall page into the user
|
/* Replicate changes to map the vsyscall page into the user
|
||||||
pagetable vsyscall mapping. */
|
pagetable vsyscall mapping. */
|
||||||
if (idx == VSYSCALL_PAGE) {
|
if (idx == VSYSCALL_PAGE) {
|
||||||
|
|
Loading…
Reference in New Issue