Commit 6f442be2fb22be02cafa606f1769fa1e6f894441

Authored by Andy Lutomirski
Committed by Linus Torvalds
1 parent af726f21ed

x86_64, traps: Stop using IST for #SS

On a 32-bit kernel, this has no effect, since there are no IST stacks.

On a 64-bit kernel, #SS can only happen in user code, on a failed iret
to user space, a canonical violation on access via RSP or RBP, or a
genuine stack segment violation in 32-bit kernel code.  The first two
cases don't need IST, and the latter two cases are unlikely fatal bugs,
and promoting them to double faults would be fine.

This fixes a bug in which the espfix64 code mishandles a stack segment
violation.

This saves 4k of memory per CPU and a tiny bit of code.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 6 changed files with 8 additions and 26 deletions Side-by-side Diff

arch/x86/include/asm/page_32_types.h
... ... @@ -20,7 +20,6 @@
20 20 #define THREAD_SIZE_ORDER 1
21 21 #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
22 22  
23   -#define STACKFAULT_STACK 0
24 23 #define DOUBLEFAULT_STACK 1
25 24 #define NMI_STACK 0
26 25 #define DEBUG_STACK 0
arch/x86/include/asm/page_64_types.h
... ... @@ -14,12 +14,11 @@
14 14 #define IRQ_STACK_ORDER 2
15 15 #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
16 16  
17   -#define STACKFAULT_STACK 1
18   -#define DOUBLEFAULT_STACK 2
19   -#define NMI_STACK 3
20   -#define DEBUG_STACK 4
21   -#define MCE_STACK 5
22   -#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
  17 +#define DOUBLEFAULT_STACK 1
  18 +#define NMI_STACK 2
  19 +#define DEBUG_STACK 3
  20 +#define MCE_STACK 4
  21 +#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */
23 22  
24 23 #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
25 24 #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
arch/x86/include/asm/traps.h
... ... @@ -39,6 +39,7 @@
39 39  
40 40 #ifdef CONFIG_TRACING
41 41 asmlinkage void trace_page_fault(void);
  42 +#define trace_stack_segment stack_segment
42 43 #define trace_divide_error divide_error
43 44 #define trace_bounds bounds
44 45 #define trace_invalid_op invalid_op
arch/x86/kernel/dumpstack_64.c
... ... @@ -24,7 +24,6 @@
24 24 [ DEBUG_STACK-1 ] = "#DB",
25 25 [ NMI_STACK-1 ] = "NMI",
26 26 [ DOUBLEFAULT_STACK-1 ] = "#DF",
27   - [ STACKFAULT_STACK-1 ] = "#SS",
28 27 [ MCE_STACK-1 ] = "#MC",
29 28 #if DEBUG_STKSZ > EXCEPTION_STKSZ
30 29 [ N_EXCEPTION_STACKS ...
arch/x86/kernel/entry_64.S
... ... @@ -1259,7 +1259,7 @@
1259 1259  
1260 1260 idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
1261 1261 idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
1262   -idtentry stack_segment do_stack_segment has_error_code=1 paranoid=1
  1262 +idtentry stack_segment do_stack_segment has_error_code=1
1263 1263 #ifdef CONFIG_XEN
1264 1264 idtentry xen_debug do_debug has_error_code=0
1265 1265 idtentry xen_int3 do_int3 has_error_code=0
arch/x86/kernel/traps.c
... ... @@ -233,27 +233,11 @@
233 233 DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun)
234 234 DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
235 235 DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
236   -#ifdef CONFIG_X86_32
237 236 DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
238   -#endif
239 237 DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)
240 238  
241 239 #ifdef CONFIG_X86_64
242 240 /* Runs on IST stack */
243   -dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
244   -{
245   - enum ctx_state prev_state;
246   -
247   - prev_state = exception_enter();
248   - if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
249   - X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
250   - preempt_conditional_sti(regs);
251   - do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
252   - preempt_conditional_cli(regs);
253   - }
254   - exception_exit(prev_state);
255   -}
256   -
257 241 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
258 242 {
259 243 static const char str[] = "double fault";
... ... @@ -802,7 +786,7 @@
802 786 set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
803 787 set_intr_gate(X86_TRAP_TS, invalid_TSS);
804 788 set_intr_gate(X86_TRAP_NP, segment_not_present);
805   - set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
  789 + set_intr_gate(X86_TRAP_SS, stack_segment);
806 790 set_intr_gate(X86_TRAP_GP, general_protection);
807 791 set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
808 792 set_intr_gate(X86_TRAP_MF, coprocessor_error);