aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-05 10:46:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-05 10:46:15 -0400
commit2071b3e34fd33e496ebd7b90331ac5b3b0ac3b81 (patch)
treeaeee17f8994ffaa234354cfe70d664f85b331247
parent9df0fe64ebbdd85dd871cb8d52c16efe5ec45319 (diff)
parente6ab9a20e73e790d47e6aa231fcf66f27b6ce3d4 (diff)
Merge branch 'x86/espfix' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next
Pull x86-64 espfix changes from Peter Anvin: "This is the espfix64 code, which fixes the IRET information leak as well as the associated functionality problem. With this code applied, 16-bit stack segments finally work as intended even on a 64-bit kernel. Consequently, this patchset also removes the runtime option that we added as an interim measure. To help the people working on Linux kernels for very small systems, this patchset also makes these compile-time configurable features" * 'x86/espfix' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime option" x86, espfix: Make it possible to disable 16-bit support x86, espfix: Make espfix64 a Kconfig option, fix UML x86, espfix: Fix broken header guard x86, espfix: Move espfix definitions into a separate header file x86-32, espfix: Remove filter for espfix32 due to race x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit stack
-rw-r--r--Documentation/x86/x86_64/mm.txt2
-rw-r--r--arch/x86/Kconfig25
-rw-r--r--arch/x86/include/asm/espfix.h16
-rw-r--r--arch/x86/include/asm/pgtable_64_types.h2
-rw-r--r--arch/x86/include/asm/setup.h2
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/entry_32.S17
-rw-r--r--arch/x86/kernel/entry_64.S81
-rw-r--r--arch/x86/kernel/espfix_64.c209
-rw-r--r--arch/x86/kernel/ldt.c10
-rw-r--r--arch/x86/kernel/smpboot.c7
-rw-r--r--arch/x86/mm/dump_pagetables.c44
-rw-r--r--arch/x86/vdso/vdso32-setup.c8
-rw-r--r--init/main.c4
14 files changed, 387 insertions, 41 deletions
diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index c584a51add15..afe68ddbe6a4 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -12,6 +12,8 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
12ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole 12ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
13ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB) 13ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
14... unused hole ... 14... unused hole ...
15ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
16... unused hole ...
15ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 17ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
16ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space 18ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
17ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls 19ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 272b493ea1bf..b660088c220d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -912,10 +912,27 @@ config VM86
912 default y 912 default y
913 depends on X86_32 913 depends on X86_32
914 ---help--- 914 ---help---
915 This option is required by programs like DOSEMU to run 16-bit legacy 915 This option is required by programs like DOSEMU to run
916 code on X86 processors. It also may be needed by software like 916 16-bit real mode legacy code on x86 processors. It also may
917 XFree86 to initialize some video cards via BIOS. Disabling this 917 be needed by software like XFree86 to initialize some video
918 option saves about 6k. 918 cards via BIOS. Disabling this option saves about 6K.
919
920config X86_16BIT
921 bool "Enable support for 16-bit segments" if EXPERT
922 default y
923 ---help---
924 This option is required by programs like Wine to run 16-bit
925 protected mode legacy code on x86 processors. Disabling
926 this option saves about 300 bytes on i386, or around 6K text
927 plus 16K runtime memory on x86-64,
928
929config X86_ESPFIX32
930 def_bool y
931 depends on X86_16BIT && X86_32
932
933config X86_ESPFIX64
934 def_bool y
935 depends on X86_16BIT && X86_64
919 936
920config TOSHIBA 937config TOSHIBA
921 tristate "Toshiba Laptop support" 938 tristate "Toshiba Laptop support"
diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h
new file mode 100644
index 000000000000..99efebb2f69d
--- /dev/null
+++ b/arch/x86/include/asm/espfix.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_X86_ESPFIX_H
2#define _ASM_X86_ESPFIX_H
3
4#ifdef CONFIG_X86_64
5
6#include <asm/percpu.h>
7
8DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
9DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
10
11extern void init_espfix_bsp(void);
12extern void init_espfix_ap(void);
13
14#endif /* CONFIG_X86_64 */
15
16#endif /* _ASM_X86_ESPFIX_H */
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index c883bf726398..7166e25ecb57 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -61,6 +61,8 @@ typedef struct { pteval_t pte; } pte_t;
61#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) 61#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
62#define MODULES_END _AC(0xffffffffff000000, UL) 62#define MODULES_END _AC(0xffffffffff000000, UL)
63#define MODULES_LEN (MODULES_END - MODULES_VADDR) 63#define MODULES_LEN (MODULES_END - MODULES_VADDR)
64#define ESPFIX_PGD_ENTRY _AC(-2, UL)
65#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
64 66
65#define EARLY_DYNAMIC_PAGE_TABLES 64 67#define EARLY_DYNAMIC_PAGE_TABLES 64
66 68
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 9264f04a4c55..ff4e7b236e21 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -59,6 +59,8 @@ static inline void x86_ce4100_early_setup(void) { }
59 59
60#ifndef _SETUP 60#ifndef _SETUP
61 61
62#include <asm/espfix.h>
63
62/* 64/*
63 * This is set up by the setup-routine at boot-time 65 * This is set up by the setup-routine at boot-time
64 */ 66 */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index f4d96000d33a..491ef3e59850 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
29obj-y += syscall_$(BITS).o vsyscall_gtod.o 29obj-y += syscall_$(BITS).o vsyscall_gtod.o
30obj-$(CONFIG_X86_64) += vsyscall_64.o 30obj-$(CONFIG_X86_64) += vsyscall_64.o
31obj-$(CONFIG_X86_64) += vsyscall_emu_64.o 31obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
32obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
32obj-$(CONFIG_SYSFS) += ksysfs.o 33obj-$(CONFIG_SYSFS) += ksysfs.o
33obj-y += bootflag.o e820.o 34obj-y += bootflag.o e820.o
34obj-y += pci-dma.o quirks.o topology.o kdebugfs.o 35obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index a2a4f4697889..98313ffaae6a 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -527,6 +527,7 @@ syscall_exit:
527restore_all: 527restore_all:
528 TRACE_IRQS_IRET 528 TRACE_IRQS_IRET
529restore_all_notrace: 529restore_all_notrace:
530#ifdef CONFIG_X86_ESPFIX32
530 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS 531 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
531 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we 532 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
532 # are returning to the kernel. 533 # are returning to the kernel.
@@ -537,6 +538,7 @@ restore_all_notrace:
537 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax 538 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
538 CFI_REMEMBER_STATE 539 CFI_REMEMBER_STATE
539 je ldt_ss # returning to user-space with LDT SS 540 je ldt_ss # returning to user-space with LDT SS
541#endif
540restore_nocheck: 542restore_nocheck:
541 RESTORE_REGS 4 # skip orig_eax/error_code 543 RESTORE_REGS 4 # skip orig_eax/error_code
542irq_return: 544irq_return:
@@ -549,13 +551,9 @@ ENTRY(iret_exc)
549.previous 551.previous
550 _ASM_EXTABLE(irq_return,iret_exc) 552 _ASM_EXTABLE(irq_return,iret_exc)
551 553
554#ifdef CONFIG_X86_ESPFIX32
552 CFI_RESTORE_STATE 555 CFI_RESTORE_STATE
553ldt_ss: 556ldt_ss:
554 larl PT_OLDSS(%esp), %eax
555 jnz restore_nocheck
556 testl $0x00400000, %eax # returning to 32bit stack?
557 jnz restore_nocheck # allright, normal return
558
559#ifdef CONFIG_PARAVIRT 557#ifdef CONFIG_PARAVIRT
560 /* 558 /*
561 * The kernel can't run on a non-flat stack if paravirt mode 559 * The kernel can't run on a non-flat stack if paravirt mode
@@ -597,6 +595,7 @@ ldt_ss:
597 lss (%esp), %esp /* switch to espfix segment */ 595 lss (%esp), %esp /* switch to espfix segment */
598 CFI_ADJUST_CFA_OFFSET -8 596 CFI_ADJUST_CFA_OFFSET -8
599 jmp restore_nocheck 597 jmp restore_nocheck
598#endif
600 CFI_ENDPROC 599 CFI_ENDPROC
601ENDPROC(system_call) 600ENDPROC(system_call)
602 601
@@ -704,6 +703,7 @@ END(syscall_badsys)
704 * the high word of the segment base from the GDT and swiches to the 703 * the high word of the segment base from the GDT and swiches to the
705 * normal stack and adjusts ESP with the matching offset. 704 * normal stack and adjusts ESP with the matching offset.
706 */ 705 */
706#ifdef CONFIG_X86_ESPFIX32
707 /* fixup the stack */ 707 /* fixup the stack */
708 mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */ 708 mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
709 mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */ 709 mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
@@ -713,8 +713,10 @@ END(syscall_badsys)