Skip to content

Commit 6f442be

Browse files
amlutotorvalds
authored andcommitted
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>
1 parent af726f2 commit 6f442be

File tree

6 files changed

+8
-26
lines changed

6 files changed

+8
-26
lines changed

Diff for: arch/x86/include/asm/page_32_types.h

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
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

Diff for: arch/x86/include/asm/page_64_types.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
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))

Diff for: arch/x86/include/asm/traps.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ asmlinkage void simd_coprocessor_error(void);
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

Diff for: arch/x86/kernel/dumpstack_64.c

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = {
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 ...

Diff for: arch/x86/kernel/entry_64.S

+1-1
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
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

Diff for: arch/x86/kernel/traps.c

+1-17
Original file line numberDiff line numberDiff line change
@@ -233,27 +233,11 @@ DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op)
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)
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);

0 commit comments

Comments
 (0)