Merge commit 'v2.6.27-rc7' into x86/debug
[sfrench/cifs-2.6.git] / arch / x86 / kernel / traps_64.c
index 2696a683778204e2f1b417ab4929f27f657836bf..7ffc8cff6cccf479eb20abbc25a8c554028896cf 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
 #include <asm/pda.h>
+#include <asm/traps.h>
 
 #include <mach_traps.h>
 
-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
-asmlinkage void nmi(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-asmlinkage void device_not_available(void);
-asmlinkage void double_fault(void);
-asmlinkage void coprocessor_segment_overrun(void);
-asmlinkage void invalid_TSS(void);
-asmlinkage void segment_not_present(void);
-asmlinkage void stack_segment(void);
-asmlinkage void general_protection(void);
-asmlinkage void page_fault(void);
-asmlinkage void coprocessor_error(void);
-asmlinkage void simd_coprocessor_error(void);
-asmlinkage void alignment_check(void);
-asmlinkage void spurious_interrupt_bug(void);
-asmlinkage void machine_check(void);
-
 int panic_on_unrecovered_nmi;
 int kstack_depth_to_print = 12;
 static unsigned int code_bytes = 64;
@@ -355,17 +335,23 @@ static const struct stacktrace_ops print_trace_ops = {
        .address = print_trace_address,
 };
 
+static void
+show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *stack, unsigned long bp, char *log_lvl)
+{
+       printk("Call Trace:\n");
+       dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
+}
+
 void show_trace(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp)
 {
-       printk("\nCall Trace:\n");
-       dump_trace(task, regs, stack, bp, &print_trace_ops, NULL);
-       printk("\n");
+       show_trace_log_lvl(task, regs, stack, bp, "");
 }
 
 static void
-_show_stack(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *sp, unsigned long bp)
+show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *sp, unsigned long bp, char *log_lvl)
 {
        unsigned long *stack;
        int i;
@@ -399,12 +385,13 @@ _show_stack(struct task_struct *task, struct pt_regs *regs,
                printk(" %016lx", *stack++);
                touch_nmi_watchdog();
        }
-       show_trace(task, regs, sp, bp);
+       printk("\n");
+       show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 }
 
 void show_stack(struct task_struct *task, unsigned long *sp)
 {
-       _show_stack(task, NULL, sp, 0);
+       show_stack_log_lvl(task, NULL, sp, 0, "");
 }
 
 /*
@@ -454,8 +441,8 @@ void show_registers(struct pt_regs *regs)
                u8 *ip;
 
                printk("Stack: ");
-               _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
-               printk("\n");
+               show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
+                               regs->bp, "");
 
                printk(KERN_EMERG "Code: ");
 
@@ -518,7 +505,7 @@ unsigned __kprobes long oops_begin(void)
 }
 
 void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
-{ 
+{
        die_owner = -1;
        bust_spinlocks(0);
        die_nest_count--;
@@ -1143,7 +1130,14 @@ asmlinkage void math_state_restore(void)
        }
 
        clts();                         /* Allow maths ops (or we recurse) */
-       restore_fpu_checking(&me->thread.xstate->fxsave);
+       /*
+        * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+        */
+       if (unlikely(restore_fpu_checking(&me->thread.xstate->fxsave))) {
+               stts();
+               force_sig(SIGSEGV, me);
+               return;
+       }
        task_thread_info(me)->status |= TS_USEDFPU;
        me->fpu_counter++;
 }