OSDN Git Service

x86/entry/64: Don't use IST entry for #BP stack
authorAndy Lutomirski <luto@kernel.org>
Thu, 23 Jul 2015 22:37:48 +0000 (15:37 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Mar 2018 16:39:24 +0000 (18:39 +0200)
commit d8ba61ba58c88d5207c1ba2f7d9a2280e7d03be9 upstream.

There's nothing IST-worthy about #BP/int3.  We don't allow kprobes
in the small handful of places in the kernel that run at CPL0 with
an invalid stack, and 32-bit kernels have used normal interrupt
gates for #BP forever.

Furthermore, we don't allow kprobes in places that have usergs while
in kernel mode, so "paranoid" is also unnecessary.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/entry/entry_64.S
arch/x86/kernel/traps.c

index 58610fe..d58d8dc 100644 (file)
@@ -943,7 +943,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 #endif /* CONFIG_HYPERV */
 
 idtentry debug                 do_debug                has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
-idtentry int3                  do_int3                 has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
+idtentry int3                  do_int3                 has_error_code=0
 idtentry stack_segment         do_stack_segment        has_error_code=1
 
 #ifdef CONFIG_XEN
index 322f433..f214293 100644 (file)
@@ -526,7 +526,6 @@ do_general_protection(struct pt_regs *regs, long error_code)
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
-/* May run on IST stack. */
 dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 {
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -541,7 +540,15 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
        if (poke_int3_handler(regs))
                return;
 
+       /*
+        * Use ist_enter despite the fact that we don't use an IST stack.
+        * We can be called from a kprobe in non-CONTEXT_KERNEL kernel
+        * mode or even during context tracking state changes.
+        *
+        * This means that we can't schedule.  That's okay.
+        */
        ist_enter(regs);
+
        RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
        if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
@@ -558,17 +565,11 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
                        SIGTRAP) == NOTIFY_STOP)
                goto exit;
 
-       /*
-        * Let others (NMI) know that the debug stack is in use
-        * as we may switch to the interrupt stack.
-        */
-       debug_stack_usage_inc();
        preempt_disable();
        cond_local_irq_enable(regs);
        do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
        cond_local_irq_disable(regs);
        preempt_enable_no_resched();
-       debug_stack_usage_dec();
 exit:
        ist_exit(regs);
 }
@@ -989,19 +990,16 @@ void __init trap_init(void)
        cpu_init();
 
        /*
-        * X86_TRAP_DB and X86_TRAP_BP have been set
-        * in early_trap_init(). However, ITS works only after
-        * cpu_init() loads TSS. See comments in early_trap_init().
+        * X86_TRAP_DB was installed in early_trap_init(). However,
+        * IST works only after cpu_init() loads TSS. See comments
+        * in early_trap_init().
         */
        set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK);
-       /* int3 can be called from all */
-       set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
 
        x86_init.irqs.trap_init();
 
 #ifdef CONFIG_X86_64
        memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16);
        set_nmi_gate(X86_TRAP_DB, &debug);
-       set_nmi_gate(X86_TRAP_BP, &int3);
 #endif
 }