mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
x86_64, traps: Stop using IST for #SS
commit 6f442be2fb upstream.
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>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
ea21cb1f6b
commit
fd5683d05e
@@ -18,7 +18,6 @@
|
||||
#define THREAD_SIZE_ORDER 1
|
||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
|
||||
|
||||
#define STACKFAULT_STACK 0
|
||||
#define DOUBLEFAULT_STACK 1
|
||||
#define NMI_STACK 0
|
||||
#define DEBUG_STACK 0
|
||||
|
||||
@@ -14,12 +14,11 @@
|
||||
#define IRQ_STACK_ORDER 2
|
||||
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
|
||||
|
||||
#define STACKFAULT_STACK 1
|
||||
#define DOUBLEFAULT_STACK 2
|
||||
#define NMI_STACK 3
|
||||
#define DEBUG_STACK 4
|
||||
#define MCE_STACK 5
|
||||
#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
|
||||
#define DOUBLEFAULT_STACK 1
|
||||
#define NMI_STACK 2
|
||||
#define DEBUG_STACK 3
|
||||
#define MCE_STACK 4
|
||||
#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */
|
||||
|
||||
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
||||
|
||||
@@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = {
|
||||
[ DEBUG_STACK-1 ] = "#DB",
|
||||
[ NMI_STACK-1 ] = "NMI",
|
||||
[ DOUBLEFAULT_STACK-1 ] = "#DF",
|
||||
[ STACKFAULT_STACK-1 ] = "#SS",
|
||||
[ MCE_STACK-1 ] = "#MC",
|
||||
#if DEBUG_STKSZ > EXCEPTION_STKSZ
|
||||
[ N_EXCEPTION_STACKS ...
|
||||
|
||||
@@ -1503,7 +1503,7 @@ apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
|
||||
|
||||
paranoidzeroentry_ist debug do_debug DEBUG_STACK
|
||||
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
|
||||
paranoiderrorentry stack_segment do_stack_segment
|
||||
errorentry stack_segment do_stack_segment
|
||||
#ifdef CONFIG_XEN
|
||||
zeroentry xen_debug do_debug
|
||||
zeroentry xen_int3 do_int3
|
||||
|
||||
@@ -220,28 +220,12 @@ DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",
|
||||
coprocessor_segment_overrun)
|
||||
DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
|
||||
DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
|
||||
#ifdef CONFIG_X86_32
|
||||
DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
|
||||
#endif
|
||||
DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check,
|
||||
BUS_ADRALN, 0)
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* Runs on IST stack */
|
||||
dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
enum ctx_state prev_state;
|
||||
|
||||
prev_state = exception_enter();
|
||||
if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
|
||||
X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
|
||||
preempt_conditional_sti(regs);
|
||||
do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
|
||||
preempt_conditional_cli(regs);
|
||||
}
|
||||
exception_exit(prev_state);
|
||||
}
|
||||
|
||||
dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
static const char str[] = "double fault";
|
||||
@@ -769,7 +753,7 @@ void __init trap_init(void)
|
||||
set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
|
||||
set_intr_gate(X86_TRAP_TS, &invalid_TSS);
|
||||
set_intr_gate(X86_TRAP_NP, &segment_not_present);
|
||||
set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
|
||||
set_intr_gate(X86_TRAP_SS, stack_segment);
|
||||
set_intr_gate(X86_TRAP_GP, &general_protection);
|
||||
set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
|
||||
set_intr_gate(X86_TRAP_MF, &coprocessor_error);
|
||||
|
||||
Reference in New Issue
Block a user