x86_64: Tidy up vsyscall emulation and make it optional
Subsystems (2)
v2 cover x86_64: Tidy up vsyscall emulation and make it optional
Now that arch/x86/kernel/vsyscall_64.c contains only vsyscall emulation code, clean it up and make it optional.
Patch 1 makes vsyscall=none work be a bit more self-consistent: it actually removes the fake vsyscall page instead of just segfaulting anyone who tries to use it.
Patch 2 is pure cosmetic cleanup.
Patch 3 is the meat: it lets vsyscall emulation be configured out. The config option to disable it is hidden under CONFIG_EXPERT, since it will break legacy code.
Note that, last I checked, current userspace is unlikely to work if the vDSO *and* vsyscalls are off. Take it up with the glibc maintainers.
This applies on top of tip/x86/vdso.
Changes from v1:
- Added Josh's Reviewed-by
- Fixup up Xen bits in patch 3
Andy Lutomirski (3):
x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code x86_64,vsyscall: Make vsyscall emulation configurable
arch/x86/Kconfig | 18 ++++++++++++ arch/x86/include/asm/fixmap.h | 2 ++ arch/x86/include/asm/page_64.h | 4 ++- arch/x86/include/asm/vsyscall.h | 8 +++++ arch/x86/kernel/Makefile | 3 +- arch/x86/kernel/setup.c | 2 -- arch/x86/kernel/vsyscall_64.c | 65 +++++++++++++++++------------------------ arch/x86/xen/mmu.c | 6 ++-- 8 files changed, 63 insertions(+), 45 deletions(-)
Signature · 1 line
1.9.3
PATCH v2 1/3 x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none
I see no point in having an unusable read-only page sitting at 0xffffffffff600000 when vsyscall=none. Instead, skip mapping it and remove it from /proc/PID/maps.
I kept the ratelimited warning when programs try to use a vsyscall in this mode, since it may help admins avoid confusion.
--- arch/x86/kernel/vsyscall_64.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
arch/x86/kernel/vsyscall_64.c +9 -5
@@ -307,6 +307,8 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)if (!mm || mm->context.ia32_compat)return NULL ;#endif +if (vsyscall_mode ==NONE ) +return NULL ;return &gate_vma; }
@@ -327,7 +329,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)*/ int in_gate_area_no_mm (unsigned long addr) { -return (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; +return vsyscall_mode !=NONE && (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; }void __init map_vsyscall (void )
@@ -335,10 +337,12 @@ void __init map_vsyscall(void)extern char __vsyscall_page;unsigned long physaddr_vsyscall =__pa_symbol (&__vsyscall_page); -__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, - vsyscall_mode ==NATIVE - ?PAGE_KERNEL_VSYSCALL - :PAGE_KERNEL_VVAR ); +if (vsyscall_mode !=NONE ) +__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, + vsyscall_mode ==NATIVE + ?PAGE_KERNEL_VSYSCALL + :PAGE_KERNEL_VVAR ); +BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_PAGE ) != (unsigned long )VSYSCALL_ADDR ); }
Signature · 1 line
1.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86_64, vsyscall: Turn vsyscalls all the way off when vsyscall==none
x86_64, vsyscall: Turn vsyscalls all the way off when vsyscall==none
Commit-ID: 87983c66bc02c9cd8e4a42e7924435145d52bb13 Gitweb: http://git.kernel.org/tip/87983c66bc02c9cd8e4a42e7924435145d52bb13 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 29 Oct 2014 14:33:45 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Mon, 3 Nov 2014 21:44:57 +0100
x86_64, vsyscall: Turn vsyscalls all the way off when vsyscall==none
I see no point in having an unusable read-only page sitting at 0xffffffffff600000 when vsyscall=none. Instead, skip mapping it and remove it from /proc/PID/maps.
I kept the ratelimited warning when programs try to use a vsyscall in this mode, since it may help admins avoid confusion.
--- arch/x86/kernel/vsyscall_64.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
arch/x86/kernel/vsyscall_64.c +9 -5
@@ -307,6 +307,8 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)if (!mm || mm->context.ia32_compat)return NULL ;#endif +if (vsyscall_mode ==NONE ) +return NULL ;return &gate_vma; }
@@ -327,7 +329,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)*/ int in_gate_area_no_mm (unsigned long addr) { -return (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; +return vsyscall_mode !=NONE && (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; }void __init map_vsyscall (void )
@@ -335,10 +337,12 @@ void __init map_vsyscall(void)extern char __vsyscall_page;unsigned long physaddr_vsyscall =__pa_symbol (&__vsyscall_page); -__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, - vsyscall_mode ==NATIVE - ?PAGE_KERNEL_VSYSCALL - :PAGE_KERNEL_VVAR ); +if (vsyscall_mode !=NONE ) +__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, + vsyscall_mode ==NATIVE + ?PAGE_KERNEL_VSYSCALL + :PAGE_KERNEL_VVAR ); +BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_PAGE ) != (unsigned long )VSYSCALL_ADDR ); }
PATCH v2 2/3 x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
In reply to Andy Lutomirskivsyscall_64.c is just vsyscall emulation. Tidy it up accordingly.
If my comment editing offends anyone, let me know and I can fix it.
--- arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 33 deletions(-)
arch/x86/kernel/vsyscall_64.c +18 -33
@@ -1,52 +1,37 @@/* -* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE -* Copyright 2003 Andi Kleen, SuSE Labs. +* Mostly copyright (c) 2012-2014 Andy Lutomirski <[email protected]> * -* [ NOTE: this mechanism is now deprecated in favor of the vDSO. ] +* This file implements vsyscall emulation. vsyscalls are a legacy ABI: +* userspace can request certain kernel services by calling fixed +* addresses. This concept is problematic: * -* Thanks to [email protected] for some useful hint. -* Special thanks to Ingo Molnar for his early experience with -* a different vsyscall implementation for Linux/IA32 and for the name. +* - It interferes with ASLR. +* - It's awkward to write code that lives in kernel addresses but is +* callable by userspace at fixed addresses. +* - The whole concept is impossible for 32-bit compat userspace. +* - UML cannot easily virtualize a vsyscall. * -* vsyscall 1 is located at -10Mbyte, vsyscall 2 is located -* at virtual address -10Mbyte+1024bytes etc... There are at max 4 -* vsyscalls. One vsyscall can reserve more than 1 slot to avoid -* jumping out of line if necessary. We cannot add more with this -* mechanism because older kernels won't return -ENOSYS. +* As of mid-2014, I believe that there is no new userspace code that +* will use a vsyscall if the vDSO is present. I hope that there will +* soon be no new userspace code that will ever use a vsyscall. * -* Note: the concept clashes with user mode linux. UML users should -* use the vDSO. +* The code in this file emulates vsyscalls when notified of a page +* fault to a vsyscall address. +* +* The original version of this code is: +* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE +* Copyright 2003 Andi Kleen, SuSE Labs. */ -#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt -#include <linux/time.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/timer.h> -#include <linux/seqlock.h> -#include <linux/jiffies.h> -#include <linux/sysctl.h> -#include <linux/topology.h> -#include <linux/timekeeper_internal.h> -#include <linux/getcpu.h> -#include <linux/cpu.h> -#include <linux/smp.h> -#include <linux/notifier.h> #include <linux/syscalls.h> #include <linux/ratelimit.h> #include <asm/vsyscall.h> -#include <asm/pgtable.h> -#include <asm/compat.h> -#include <asm/page.h> #include <asm/unistd.h> #include <asm/fixmap.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/segment.h> -#include <asm/desc.h> -#include <asm/topology.h> #include <asm/traps.h> #define CREATE_TRACE_POINTS
Signature · 1 line
1.9.3
Re: [PATCH v2 2/3] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
Quoted 15 lines · Andy Lutomirski
vsyscall_64.cis just vsyscall emulation. Tidy it up accordingly.If my comment editing offends anyone, let me know and I can fix it.
Reviewed-by Josh Triplett <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 33 deletions(-)arch/x86/kernel/vsyscall_64.c +0
-0
arch/x86/kernel/vsyscall_64.c line 2
Quoted 4 lines
arch/x86/kernel/vsyscall_64.c +1
-2@@ -1,52 +1,37 @@/* -* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE -* Copyright 2003 Andi Kleen, SuSE Labs. +* Mostly copyright (c) 2012-2014 Andy Lutomirski <[email protected]>
We usualy leave the old copyright notices around even if the code which is related to them has been removed more or less completely.
So I change this to:
/*
* Copyright (c) 2012-2014 Andy Lutomirski <[email protected]> *
* Based on the original implementation:
* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE
* Copyright 2003 Andi Kleen, SuSE Labs.
and apply the whole lot.
Thanks,
tglx
Re: [PATCH v2 2/3] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
Quoted 27 lines · Thomas Gleixner
Quoted 15 lines · Andy Lutomirski
vsyscall_64.cis just vsyscall emulation. Tidy it up accordingly.If my comment editing offends anyone, let me know and I can fix it.
Reviewed-by Josh Triplett <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 33 deletions(-)arch/x86/kernel/vsyscall_64.c +0
-0arch/x86/kernel/vsyscall_64.c line 2
Quoted 4 lines
arch/x86/kernel/vsyscall_64.c +1
-2@@ -1,52 +1,37 @@/* -* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE -* Copyright 2003 Andi Kleen, SuSE Labs. +* Mostly copyright (c) 2012-2014 Andy Lutomirski <[email protected]> We usualy leave the old copyright notices around even if the code which is related to them has been removed more or less completely.
So I change this to:
Quoted 8 lines
/*
* Copyright (c) 2012-2014 Andy Lutomirski <[email protected]> *
* Based on the original implementation:
* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE
* Copyright 2003 Andi Kleen, SuSE Labs.and apply the whole lot.
Would it make more sense to move those copyright notices to arch/x86/vdso/vma.c? That's where most of the code ended up.
--Andy
Re: [PATCH v2 2/3] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
Quoted 35 lines · Andy Lutomirski
Quoted 34 lines · Thomas Gleixner
Quoted 15 lines · Andy Lutomirski
vsyscall_64.cis just vsyscall emulation. Tidy it up accordingly.If my comment editing offends anyone, let me know and I can fix it.
Reviewed-by Josh Triplett <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 33 deletions(-)arch/x86/kernel/vsyscall_64.c +0
-0arch/x86/kernel/vsyscall_64.c line 2
Quoted 4 lines
arch/x86/kernel/vsyscall_64.c +1
-2@@ -1,52 +1,37 @@/* -* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE -* Copyright 2003 Andi Kleen, SuSE Labs. +* Mostly copyright (c) 2012-2014 Andy Lutomirski <[email protected]> We usualy leave the old copyright notices around even if the code which is related to them has been removed more or less completely.
So I change this to:
/*
* Copyright (c) 2012-2014 Andy Lutomirski <[email protected]> *
* Based on the original implementation:
* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE
* Copyright 2003 Andi Kleen, SuSE Labs.
Quoted 4 lines
Quoted 1 line
and apply the whole lot.
Would it make more sense to move those copyright notices to
arch/x86/vdso/vma.c? That's where most of the code ended up.
That has already a notice from Andi and I cant figure out what parts of that have been written by Andrea. We'll worry about that when we remove vsyscall_64.c. Until then the git history will be our friend.
Thanks,
tglx
Re: [PATCH v2 2/3] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
Quoted 36 lines · Thomas Gleixner
Quoted 35 lines · Andy Lutomirski
Quoted 34 lines · Thomas Gleixner
Quoted 15 lines · Andy Lutomirski
vsyscall_64.cis just vsyscall emulation. Tidy it up accordingly.If my comment editing offends anyone, let me know and I can fix it.
Reviewed-by Josh Triplett <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 33 deletions(-)arch/x86/kernel/vsyscall_64.c +0
-0arch/x86/kernel/vsyscall_64.c line 2
Quoted 4 lines
arch/x86/kernel/vsyscall_64.c +1
-2@@ -1,52 +1,37 @@/* -* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE -* Copyright 2003 Andi Kleen, SuSE Labs. +* Mostly copyright (c) 2012-2014 Andy Lutomirski <[email protected]> We usualy leave the old copyright notices around even if the code which is related to them has been removed more or less completely.
So I change this to:
/*
* Copyright (c) 2012-2014 Andy Lutomirski <[email protected]> *
* Based on the original implementation:
* Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE
* Copyright 2003 Andi Kleen, SuSE Labs.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
and apply the whole lot.
Would it make more sense to move those copyright notices to
arch/x86/vdso/vma.c? That's where most of the code ended up.That has already a notice from Andi and I cant figure out what parts of that have been written by Andrea. We'll worry about that when we remove
vsyscall_64.c. Until then the git history will be our friend.
Works for me.
--Andy
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86_64, vsyscall: Rewrite comment and clean up headers in vsyscall code
In reply to Andy Lutomirskix86_64, vsyscall: Rewrite comment and clean up headers in vsyscall code
Commit-ID: 95c46b56922409ed8838b3b420b11cfebb8c6c88 Gitweb: http://git.kernel.org/tip/95c46b56922409ed8838b3b420b11cfebb8c6c88 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 29 Oct 2014 14:33:46 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Mon, 3 Nov 2014 21:44:57 +0100
x86_64, vsyscall: Rewrite comment and clean up headers in vsyscall code
vsyscall_64.c is just vsyscall emulation. Tidy it up accordingly.
[ tglx: Preserved the original copyright notices ]
--- arch/x86/kernel/vsyscall_64.c | 50 ++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 32 deletions(-)
arch/x86/kernel/vsyscall_64.c +18 -32
@@ -1,52 +1,38 @@/* +* Copyright (c) 2012-2014 Andy Lutomirski <[email protected]> +* +* Based on the original implementation which is: * Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE * Copyright 2003 Andi Kleen, SuSE Labs. * -* [ NOTE: this mechanism is now deprecated in favor of the vDSO. ] +* Parts of the original code have been moved to arch/x86/vdso/vma.c +* +* This file implements vsyscall emulation. vsyscalls are a legacy ABI: +* Userspace can request certain kernel services by calling fixed +* addresses. This concept is problematic: * -* Thanks to [email protected] for some useful hint. -* Special thanks to Ingo Molnar for his early experience with -* a different vsyscall implementation for Linux/IA32 and for the name. +* - It interferes with ASLR. +* - It's awkward to write code that lives in kernel addresses but is +* callable by userspace at fixed addresses. +* - The whole concept is impossible for 32-bit compat userspace. +* - UML cannot easily virtualize a vsyscall. * -* vsyscall 1 is located at -10Mbyte, vsyscall 2 is located -* at virtual address -10Mbyte+1024bytes etc... There are at max 4 -* vsyscalls. One vsyscall can reserve more than 1 slot to avoid -* jumping out of line if necessary. We cannot add more with this -* mechanism because older kernels won't return -ENOSYS. +* As of mid-2014, I believe that there is no new userspace code that +* will use a vsyscall if the vDSO is present. I hope that there will +* soon be no new userspace code that will ever use a vsyscall. * -* Note: the concept clashes with user mode linux. UML users should -* use the vDSO. +* The code in this file emulates vsyscalls when notified of a page +* fault to a vsyscall address. */ -#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt - -#include <linux/time.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/timer.h> -#include <linux/seqlock.h> -#include <linux/jiffies.h> -#include <linux/sysctl.h> -#include <linux/topology.h> -#include <linux/timekeeper_internal.h> -#include <linux/getcpu.h> -#include <linux/cpu.h> -#include <linux/smp.h> -#include <linux/notifier.h> #include <linux/syscalls.h> #include <linux/ratelimit.h> #include <asm/vsyscall.h> -#include <asm/pgtable.h> -#include <asm/compat.h> -#include <asm/page.h> #include <asm/unistd.h> #include <asm/fixmap.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/segment.h> -#include <asm/desc.h> -#include <asm/topology.h> #include <asm/traps.h> #define CREATE_TRACE_POINTS
PATCH v2 3/3 x86_64,vsyscall: Make vsyscall emulation configurable
In reply to Andy LutomirskiThis 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.
--- arch/x86/Kconfig | 18 ++++++++++++++++++ arch/x86/include/asm/fixmap.h | 2 ++ arch/x86/include/asm/page_64.h | 4 +++- arch/x86/include/asm/vsyscall.h | 8 ++++++++ arch/x86/kernel/Makefile | 3 +-- arch/x86/kernel/setup.c | 2 -- arch/x86/xen/mmu.c | 6 ++++-- 7 files changed, 36 insertions(+), 7 deletions(-)
arch/x86/Kconfig +18 -0
@@ -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
arch/x86/include/asm/fixmap.h +2 -0
@@ -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,
arch/x86/include/asm/page_64.h +3 -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 */
arch/x86/include/asm/vsyscall.h +8 -0
@@ -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 */
arch/x86/kernel/Makefile +1 -2
@@ -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
arch/x86/kernel/setup.c +0 -2
@@ -1190,9 +1190,7 @@ void __init setup_arch(char **cmdline_p)tboot_probe (); -#ifdef CONFIG_X86_64 map_vsyscall (); -#endif generic_apic_probe ();
arch/x86/xen/mmu.c +4 -2
@@ -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 ) {
Signature · 1 line
1.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86_64,vsyscall: Make vsyscall emulation configurable
x86_64,vsyscall: Make vsyscall emulation configurable
Commit-ID: 1ad83c858c7d4ea210429142c99a1548e6715a35 Gitweb: http://git.kernel.org/tip/1ad83c858c7d4ea210429142c99a1548e6715a35 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 29 Oct 2014 14:33:47 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Mon, 3 Nov 2014 21:44:57 +0100
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.
--- arch/x86/Kconfig | 18 ++++++++++++++++++ arch/x86/include/asm/fixmap.h | 2 ++ arch/x86/include/asm/page_64.h | 4 +++- arch/x86/include/asm/vsyscall.h | 8 ++++++++ arch/x86/kernel/Makefile | 3 +-- arch/x86/kernel/setup.c | 2 -- arch/x86/xen/mmu.c | 6 ++++-- 7 files changed, 36 insertions(+), 7 deletions(-)
arch/x86/Kconfig +18 -0
@@ -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
arch/x86/include/asm/fixmap.h +2 -0
@@ -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,
arch/x86/include/asm/page_64.h +3 -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 */
arch/x86/include/asm/vsyscall.h +8 -0
@@ -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 */
arch/x86/kernel/Makefile +1 -2
@@ -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
arch/x86/kernel/setup.c +0 -2
@@ -1190,9 +1190,7 @@ void __init setup_arch(char **cmdline_p)tboot_probe (); -#ifdef CONFIG_X86_64 map_vsyscall (); -#endif generic_apic_probe ();
arch/x86/xen/mmu.c +4 -2
@@ -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 ) {