History

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.

Andy Lutomirski committed 11 years ago

Commit 6f442be1 parent af726f26 files · +8 −26Browse files

Unified · Split

6 files
  1. arch/x86/include/asm/page_32_types.h +0 −1
  2. arch/x86/include/asm/page_64_types.h +5 −6
  3. arch/x86/include/asm/traps.h +1 −0
  4. arch/x86/kernel/dumpstack_64.c +0 −1
  5. arch/x86/kernel/entry_64.S +1 −1
  6. arch/x86/kernel/traps.c +1 −17
arch/x86/include/asm/page_32_types.h+0−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#define THREAD_SIZE_ORDER 120#define THREAD_SIZE_ORDER 1
21#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)21#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
22 22
23#define STACKFAULT_STACK 0
24#define DOUBLEFAULT_STACK 123#define DOUBLEFAULT_STACK 1
25#define NMI_STACK 024#define NMI_STACK 0
26#define DEBUG_STACK 025#define DEBUG_STACK 0
arch/x86/include/asm/page_64_types.h+5−6
@@ -14,12 +14,11 @@ · 13 unmodified lines
14#define IRQ_STACK_ORDER 214#define IRQ_STACK_ORDER 2
15#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)15#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
16 16
17#define STACKFAULT_STACK 117#define DOUBLEFAULT_STACK 1
18#define DOUBLEFAULT_STACK 218#define NMI_STACK 2
19#define NMI_STACK 319#define DEBUG_STACK 3
20#define DEBUG_STACK 420#define MCE_STACK 4
21#define MCE_STACK 521#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */
22#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
23 22
24#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)23#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
25#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))24#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
arch/x86/include/asm/traps.h+1−0
@@ -39,6 +39,7 @@ asmlinkage void simd_coprocessor_error(void); · 38 unmodified lines
39 39
40#ifdef CONFIG_TRACING40#ifdef CONFIG_TRACING
41asmlinkage void trace_page_fault(void);41asmlinkage void trace_page_fault(void);
42#define trace_stack_segment stack_segment
42#define trace_divide_error divide_error43#define trace_divide_error divide_error
43#define trace_bounds bounds44#define trace_bounds bounds
44#define trace_invalid_op invalid_op45#define trace_invalid_op invalid_op
arch/x86/kernel/dumpstack_64.c+0−1
@@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = { · 23 unmodified lines
24 [ DEBUG_STACK-1 ] = "#DB",24 [ DEBUG_STACK-1 ] = "#DB",
25 [ NMI_STACK-1 ] = "NMI",25 [ NMI_STACK-1 ] = "NMI",
26 [ DOUBLEFAULT_STACK-1 ] = "#DF",26 [ DOUBLEFAULT_STACK-1 ] = "#DF",
27 [ STACKFAULT_STACK-1 ] = "#SS",
28 [ MCE_STACK-1 ] = "#MC",27 [ MCE_STACK-1 ] = "#MC",
29#if DEBUG_STKSZ > EXCEPTION_STKSZ28#if DEBUG_STKSZ > EXCEPTION_STKSZ
30 [ N_EXCEPTION_STACKS ...29 [ N_EXCEPTION_STACKS ...
arch/x86/kernel/entry_64.S+1−1
@@ -1259,7 +1259,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ · 1258 unmodified lines
1259 1259
1260idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK1260idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
1261idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK1261idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
1262idtentry stack_segment do_stack_segment has_error_code=1 paranoid=11262idtentry stack_segment do_stack_segment has_error_code=1
1263#ifdef CONFIG_XEN1263#ifdef CONFIG_XEN
1264idtentry xen_debug do_debug has_error_code=01264idtentry xen_debug do_debug has_error_code=0
1265idtentry xen_int3 do_int3 has_error_code=01265idtentry xen_int3 do_int3 has_error_code=0
arch/x86/kernel/traps.c+1−17
@@ -233,27 +233,11 @@ DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op) · 232 unmodified lines
233DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun)233DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun)
234DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)234DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
235DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)235DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
236#ifdef CONFIG_X86_32
237DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)236DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
238#endif
239DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)237DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)
240 238
241#ifdef CONFIG_X86_64239#ifdef CONFIG_X86_64
242/* Runs on IST stack */240/* Runs on IST stack */
243dotraplinkage 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
257dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)241dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
258{242{
259 static const char str[] = "double fault";243 static const char str[] = "double fault";
@@ -802,7 +786,7 @@ void __init trap_init(void) · 542 unmodified lines
802 set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);786 set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
803 set_intr_gate(X86_TRAP_TS, invalid_TSS);787 set_intr_gate(X86_TRAP_TS, invalid_TSS);
804 set_intr_gate(X86_TRAP_NP, segment_not_present);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 set_intr_gate(X86_TRAP_GP, general_protection);790 set_intr_gate(X86_TRAP_GP, general_protection);
807 set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);791 set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
808 set_intr_gate(X86_TRAP_MF, coprocessor_error);792 set_intr_gate(X86_TRAP_MF, coprocessor_error);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t