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
2020 #define THREAD_SIZE_ORDER 1
2121 #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
2222
23−#define STACKFAULT_STACK 0
2423 #define DOUBLEFAULT_STACK 1
2524 #define NMI_STACK 0
2625 #define DEBUG_STACK 0
arch/x86/include/asm/page_64_types.h+5−6
@@ -14,12 +14,11 @@ · 13 unmodified lines
1414 #define IRQ_STACK_ORDER 2
1515 #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
1616
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 */
2322
2423 #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
2524 #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
3939
4040 #ifdef CONFIG_TRACING
4141 asmlinkage void trace_page_fault(void);
42+#define trace_stack_segment stack_segment
4243 #define trace_divide_error divide_error
4344 #define trace_bounds bounds
4445 #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
2424 [ DEBUG_STACK-1 ] = "#DB",
2525 [ NMI_STACK-1 ] = "NMI",
2626 [ DOUBLEFAULT_STACK-1 ] = "#DF",
27− [ STACKFAULT_STACK-1 ] = "#SS",
2827 [ MCE_STACK-1 ] = "#MC",
2928 #if DEBUG_STKSZ > EXCEPTION_STKSZ
3029 [ N_EXCEPTION_STACKS ...
arch/x86/kernel/entry_64.S+1−1
@@ -1259,7 +1259,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ · 1258 unmodified lines
12591259
12601260 idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
12611261 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
12631263 #ifdef CONFIG_XEN
12641264 idtentry xen_debug do_debug has_error_code=0
12651265 idtentry 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
233233 DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun)
234234 DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
235235 DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
236−#ifdef CONFIG_X86_32
237236 DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
238−#endif
239237 DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)
240238
241239 #ifdef CONFIG_X86_64
242240 /* 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−
257241 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
258242 {
259243 static const char str[] = "double fault";
@@ -802,7 +786,7 @@ void __init trap_init(void) · 542 unmodified lines
802786 set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
803787 set_intr_gate(X86_TRAP_TS, invalid_TSS);
804788 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);
806790 set_intr_gate(X86_TRAP_GP, general_protection);
807791 set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
808792 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