diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 17:24:20 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 17:24:20 -0500 |
| commit | 3100e448e7d74489a96cb7b45d88fe6962774eaa (patch) | |
| tree | 53e46a702bd191ca43639b560d2bb1d3b0ad18c8 | |
| parent | c9f861c77269bc9950c16c6404a9476062241671 (diff) | |
| parent | 26893107aa717cd11010f0c278d02535defa1ac9 (diff) | |
Merge branch 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 vdso updates from Ingo Molnar:
"Various vDSO updates from Andy Lutomirski, mostly cleanups and
reorganization to improve maintainability, but also some
micro-optimizations and robustization changes"
* 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86_64/vsyscall: Restore orig_ax after vsyscall seccomp
x86_64: Add a comment explaining the TASK_SIZE_MAX guard page
x86_64,vsyscall: Make vsyscall emulation configurable
x86_64, vsyscall: Rewrite comment and clean up headers in vsyscall code
x86_64, vsyscall: Turn vsyscalls all the way off when vsyscall==none
x86,vdso: Use LSL unconditionally for vgetcpu
x86: vdso: Fix build with older gcc
x86_64/vdso: Clean up vgetcpu init and merge the vdso initcalls
x86_64/vdso: Remove jiffies from the vvar page
x86/vdso: Make the PER_CPU segment 32 bits
x86/vdso: Make the PER_CPU segment start out accessed
x86/vdso: Change the PER_CPU segment to use struct desc_struct
x86_64/vdso: Move getcpu code from vsyscall_64.c to vdso/vma.c
x86_64/vsyscall: Move all of the gate_area code to vsyscall_64.c
| -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/processor.h | 8 | ||||
| -rw-r--r-- | arch/x86/include/asm/vgtod.h | 19 | ||||
| -rw-r--r-- | arch/x86/include/asm/vsyscall.h | 33 | ||||
| -rw-r--r-- | arch/x86/include/asm/vvar.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/time.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 147 | ||||
| -rw-r--r-- | arch/x86/mm/init_64.c | 49 | ||||
| -rw-r--r-- | arch/x86/vdso/vgetcpu.c | 2 | ||||
| -rw-r--r-- | arch/x86/vdso/vma.c | 83 | ||||
| -rw-r--r-- | arch/x86/xen/mmu.c | 6 |
16 files changed, 190 insertions, 200 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 666ac6651c17..bea3a0159496 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -992,6 +992,24 @@ config X86_ESPFIX64 | |||
| 992 | def_bool y | 992 | def_bool y |
| 993 | depends on X86_16BIT && X86_64 | 993 | depends on X86_16BIT && X86_64 |
| 994 | 994 | ||
| 995 | config X86_VSYSCALL_EMULATION | ||
| 996 | bool "Enable vsyscall emulation" if EXPERT | ||
| 997 | default y | ||
| 998 | depends on X86_64 | ||
| 999 | ---help--- | ||
| 1000 | This enables emulation of the legacy vsyscall page. Disabling | ||
| 1001 | it is roughly equivalent to booting with vsyscall=none, except | ||
| 1002 | that it will also disable the helpful warning if a program | ||
| 1003 | tries to use a vsyscall. With this option set to N, offending | ||
| 1004 | programs will just segfault, citing addresses of the form | ||
| 1005 | 0xffffffffff600?00. | ||
| 1006 | |||
| 1007 | This option is required by many programs built before 2013, and | ||
| 1008 | care should be used even with newer programs if set to N. | ||
| 1009 | |||
| 1010 | Disabling this option saves about 7K of kernel size and | ||
| 1011 | possibly 4K of additional runtime pagetable memory. | ||
| 1012 | |||
| 995 | config TOSHIBA | 1013 | config TOSHIBA |
| 996 | tristate "Toshiba Laptop support" | 1014 | tristate "Toshiba Laptop support" |
| 997 | depends on X86_32 | 1015 | depends on X86_32 |
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index bf728e49c53c..f80d70009ff8 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/processor.h b/arch/x86/include/asm/processor.h index 25b8de0f21c0..a092a0cce0b7 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
| @@ -894,7 +894,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); | |||
| 894 | 894 | ||
| 895 | #else | 895 | #else |
| 896 | /* | 896 | /* |
| 897 | * User space process size. 47bits minus one guard page. | 897 | * User space process size. 47bits minus one guard page. The guard |
| 898 | * page is necessary on Intel CPUs: if a SYSCALL instruction is at | ||
| 899 | * the highest possible canonical userspace address, then that | ||
| 900 | * syscall will enter the kernel with a non-canonical return | ||
| 901 | * address, and SYSRET will explode dangerously. We avoid this | ||
| 902 | * particular problem by preventing anything from being mapped | ||
| 903 | * at the maximum canonical address. | ||
| 898 | */ | 904 | */ |
| 899 | #define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE) | 905 | #define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE) |
| 900 | 906 | ||
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index 3c3366c2e37f..e7e9682a33e9 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h | |||
| @@ -70,4 +70,23 @@ static inline void gtod_write_end(struct vsyscall_gtod_data *s) | |||
| 70 | ++s->seq; | 70 | ++s->seq; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #ifdef CONFIG_X86_64 | ||
| 74 | |||
| 75 | #define VGETCPU_CPU_MASK 0xfff | ||
| 76 | |||
| 77 | static inline unsigned int __getcpu(void) | ||
| 78 | { | ||
| 79 | unsigned int p; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Load per CPU data from GDT. LSL is faster than RDTSCP and | ||
| 83 | * works on all CPUs. | ||
| 84 | */ | ||
| 85 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | ||
| 86 | |||
| 87 | return p; | ||
| 88 | } | ||
| 89 | |||
| 90 | #endif /* CONFIG_X86_64 */ | ||
| 91 | |||
| 73 | #endif /* _ASM_X86_VGTOD_H */ | 92 | #endif /* _ASM_X86_VGTOD_H */ |
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h index 2a46ca720afc..6ba66ee79710 100644 --- a/arch/x86/include/asm/vsyscall.h +++ b/arch/x86/include/asm/vsyscall.h | |||
| @@ -4,15 +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 | #define VGETCPU_RDTSCP 1 | 7 | #ifdef CONFIG_X86_VSYSCALL_EMULATION |
| 8 | #define VGETCPU_LSL 2 | ||
| 9 | |||
| 10 | /* kernel space (writeable) */ | ||
| 11 | extern int vgetcpu_mode; | ||
| 12 | extern struct timezone sys_tz; | ||
| 13 | |||
| 14 | #include <asm/vvar.h> | ||
| 15 | |||
| 16 | extern void map_vsyscall(void); | 8 | extern void map_vsyscall(void); |
| 17 | 9 | ||
| 18 | /* | 10 | /* |
| @@ -20,25 +12,12 @@ extern void map_vsyscall(void); | |||
| 20 | * Returns true if handled. | 12 | * Returns true if handled. |
| 21 | */ | 13 | */ |
| 22 | extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); | 14 | extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); |
| 23 | 15 | #else | |
| 24 | #ifdef CONFIG_X86_64 | 16 | static inline void map_vsyscall(void) {} |
| 25 | 17 | static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) | |
| 26 | #define VGETCPU_CPU_MASK 0xfff | ||
| 27 | |||
| 28 | static inline unsigned int __getcpu(void) | ||
| 29 | { | 18 | { |
| 30 | unsigned int p; | 19 | return false; |
| 31 | |||
| 32 | if (VVAR(vgetcpu_mode) == VGETCPU_RDTSCP) { | ||
| 33 | /* Load per CPU data from RDTSCP */ | ||
| 34 | native_read_tscp(&p); | ||
| 35 | } else { | ||
| 36 | /* Load per CPU data from GDT */ | ||
| 37 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | ||
| 38 | } | ||
| 39 | |||
| 40 | return p; | ||
| 41 | } | 20 | } |
| 42 | #endif /* CONFIG_X86_64 */ | 21 | #endif |
| 43 | 22 | ||
| 44 | #endif /* _ASM_X86_VSYSCALL_H */ | 23 | #endif /* _ASM_X86_VSYSCALL_H */ |
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index 5d2b9ad2c6d2..3f32dfc2ab73 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h | |||
| @@ -44,8 +44,6 @@ extern char __vvar_page; | |||
| 44 | 44 | ||
| 45 | /* DECLARE_VVAR(offset, type, name) */ | 45 | /* DECLARE_VVAR(offset, type, name) */ |
| 46 | 46 | ||
| 47 | DECLARE_VVAR(0, volatile unsigned long, jiffies) | ||
| 48 | DECLARE_VVAR(16, int, vgetcpu_mode) | ||
| 49 | DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data) | 47 | DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data) |
| 50 | 48 | ||
| 51 | #undef DECLARE_VVAR | 49 | #undef DECLARE_VVAR |
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. |
