Merge master.kernel.org:/home/rmk/linux-2.6-serial
[powerpc.git] / arch / i386 / kernel / traps.c
index 1144df0..c34d1bf 100644 (file)
@@ -52,7 +52,6 @@
 #include <asm/arch_hooks.h>
 #include <asm/kdebug.h>
 
-#include <linux/irq.h>
 #include <linux/module.h>
 
 #include "mach_traps.h"
@@ -210,7 +209,7 @@ void show_registers(struct pt_regs *regs)
        unsigned short ss;
 
        esp = (unsigned long) (&regs->esp);
-       ss = __KERNEL_DS;
+       savesegment(ss, ss);
        if (user_mode(regs)) {
                in_kernel = 0;
                esp = regs->esp;
@@ -267,9 +266,6 @@ static void handle_BUG(struct pt_regs *regs)
        char c;
        unsigned long eip;
 
-       if (user_mode(regs))
-               goto no_bug;            /* Not in kernel */
-
        eip = regs->eip;
 
        if (eip < PAGE_OFFSET)
@@ -366,8 +362,9 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
                die(str, regs, err);
 }
 
-static void do_trap(int trapnr, int signr, char *str, int vm86,
-                          struct pt_regs * regs, long error_code, siginfo_t *info)
+static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
+                             struct pt_regs * regs, long error_code,
+                             siginfo_t *info)
 {
        struct task_struct *tsk = current;
        tsk->thread.error_code = error_code;
@@ -463,7 +460,8 @@ DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
 
-fastcall void do_general_protection(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_general_protection(struct pt_regs * regs,
+                                             long error_code)
 {
        int cpu = get_cpu();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
@@ -490,6 +488,7 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
                                tss->io_bitmap_max - thread->io_bitmap_max);
                tss->io_bitmap_max = thread->io_bitmap_max;
                tss->io_bitmap_base = IO_BITMAP_OFFSET;
+               tss->io_bitmap_owner = thread;
                put_cpu();
                return;
        }
@@ -568,6 +567,10 @@ static DEFINE_SPINLOCK(nmi_print_lock);
 
 void die_nmi (struct pt_regs *regs, const char *msg)
 {
+       if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) ==
+           NOTIFY_STOP)
+               return;
+
        spin_lock(&nmi_print_lock);
        /*
        * We are in trouble anyway, lets at least try
@@ -656,7 +659,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
 
        ++nmi_count(cpu);
 
-       if (!nmi_callback(regs, cpu))
+       if (!rcu_dereference(nmi_callback)(regs, cpu))
                default_do_nmi(regs);
 
        nmi_exit();
@@ -664,7 +667,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
 
 void set_nmi_callback(nmi_callback_t callback)
 {
-       nmi_callback = callback;
+       rcu_assign_pointer(nmi_callback, callback);
 }
 EXPORT_SYMBOL_GPL(set_nmi_callback);
 
@@ -675,7 +678,7 @@ void unset_nmi_callback(void)
 EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
 #ifdef CONFIG_KPROBES
-fastcall void do_int3(struct pt_regs *regs, long error_code)
+fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
        if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
                        == NOTIFY_STOP)
@@ -709,7 +712,7 @@ fastcall void do_int3(struct pt_regs *regs, long error_code)
  * find every occurrence of the TF bit that could be saved away even
  * by user code)
  */
-fastcall void do_debug(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
 {
        unsigned int condition;
        struct task_struct *tsk = current;
@@ -804,8 +807,9 @@ void math_error(void __user *eip)
        cwd = get_fpu_cwd(task);
        swd = get_fpu_swd(task);
        switch (swd & ~cwd & 0x3f) {
-               case 0x000:
-               default:
+               case 0x000: /* No unmasked exception */
+                       return;
+               default:    /* Multiple exceptions */
                        break;
                case 0x001: /* Invalid Op */
                        /*