Commit 6f442be2fb22be02cafa606f1769fa1e6f894441
Committed by
Linus Torvalds
1 parent
af726f21ed
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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
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
arch/x86/kernel/dumpstack_64.c
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); |