linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / i386 / kernel / traps.c
index 05ab8b0..610d2f9 100644 (file)
@@ -11,6 +11,7 @@
  * 'Traps.c' handles hardware traps and faults after we have saved some
  * state in 'asm.s'.
  */
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -27,7 +28,6 @@
 #include <linux/utsname.h>
 #include <linux/kprobes.h>
 #include <linux/kexec.h>
-#include <linux/unwind.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
 #include <asm/nmi.h>
-#include <asm/unwind.h>
+
 #include <asm/smp.h>
 #include <asm/arch_hooks.h>
 #include <asm/kdebug.h>
-#include <asm/stacktrace.h>
 
 #include <linux/module.h>
 #include <linux/vserver/debug.h>
@@ -94,27 +93,19 @@ asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
 
 static int kstack_depth_to_print = 24;
-#ifdef CONFIG_STACK_UNWIND
-static int call_trace = 1;
-#else
-#define call_trace (-1)
-#endif
-ATOMIC_NOTIFIER_HEAD(i386die_chain);
-
-extern char last_sysfs_file[];
+struct notifier_block *i386die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
 
 int register_die_notifier(struct notifier_block *nb)
 {
-       vmalloc_sync_all();
-       return atomic_notifier_chain_register(&i386die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&i386die_chain, nb);
+       int err = 0;
+       unsigned long flags;
+       spin_lock_irqsave(&die_notifier_lock, flags);
+       err = notifier_chain_register(&i386die_chain, nb);
+       spin_unlock_irqrestore(&die_notifier_lock, flags);
+       return err;
 }
-EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
+EXPORT_SYMBOL(register_die_notifier);
 
 static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 {
@@ -122,182 +113,72 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
                p < (void *)tinfo + THREAD_SIZE - 3;
 }
 
+static void print_addr_and_symbol(unsigned long addr, char *log_lvl)
+{
+       printk(log_lvl);
+       printk(" [<%08lx>] ", addr);
+       print_symbol("%s", addr);
+       printk("\n");
+}
+
 static inline unsigned long print_context_stack(struct thread_info *tinfo,
                                unsigned long *stack, unsigned long ebp,
-                               struct stacktrace_ops *ops, void *data)
+                               char *log_lvl)
 {
        unsigned long addr;
 
 #ifdef CONFIG_FRAME_POINTER
        while (valid_stack_ptr(tinfo, (void *)ebp)) {
                addr = *(unsigned long *)(ebp + 4);
-               ops->address(data, addr);
-               /*
-                * break out of recursive entries (such as
-                * end_of_stack_stop_unwind_function):
-                */
-               if (ebp == *(unsigned long *)ebp)
-                       break;
+               print_addr_and_symbol(addr, log_lvl);
                ebp = *(unsigned long *)ebp;
        }
 #else
        while (valid_stack_ptr(tinfo, stack)) {
                addr = *stack++;
                if (__kernel_text_address(addr))
-                       ops->address(data, addr);
+                       print_addr_and_symbol(addr, log_lvl);
        }
 #endif
        return ebp;
 }
 
-struct ops_and_data {
-       struct stacktrace_ops *ops;
-       void *data;
-};
-
-static asmlinkage int
-dump_trace_unwind(struct unwind_frame_info *info, void *data)
-{
-       struct ops_and_data *oad = (struct ops_and_data *)data;
-       int n = 0;
-
-       while (unwind(info) == 0 && UNW_PC(info)) {
-               n++;
-               oad->ops->address(oad->data, UNW_PC(info));
-               if (arch_unw_user_mode(info))
-                       break;
-       }
-       return n;
-}
-
-void dump_trace(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *stack,
-               struct stacktrace_ops *ops, void *data)
+static void show_trace_log_lvl(struct task_struct *task,
+                              unsigned long *stack, char *log_lvl)
 {
-       unsigned long ebp = 0;
+       unsigned long ebp;
 
        if (!task)
                task = current;
 
-       if (call_trace >= 0) {
-               int unw_ret = 0;
-               struct unwind_frame_info info;
-               struct ops_and_data oad = { .ops = ops, .data = data };
-
-               if (regs) {
-                       if (unwind_init_frame_info(&info, task, regs) == 0)
-                               unw_ret = dump_trace_unwind(&info, &oad);
-               } else if (task == current)
-                       unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad);
-               else {
-                       if (unwind_init_blocked(&info, task) == 0)
-                               unw_ret = dump_trace_unwind(&info, &oad);
-               }
-               if (unw_ret > 0) {
-                       if (call_trace == 1 && !arch_unw_user_mode(&info)) {
-                               ops->warning_symbol(data, "DWARF2 unwinder stuck at %s",
-                                            UNW_PC(&info));
-                               if (UNW_SP(&info) >= PAGE_OFFSET) {
-                                       ops->warning(data, "Leftover inexact backtrace:");
-                                       stack = (void *)UNW_SP(&info);
-                                       if (!stack)
-                                               return;
-                                       ebp = UNW_FP(&info);
-                               } else
-                                       ops->warning(data, "Full inexact backtrace again:");
-                       } else if (call_trace >= 1)
-                               return;
-                       else
-                               ops->warning(data, "Full inexact backtrace again:");
-               } else
-                       ops->warning(data, "Inexact backtrace:");
-       }
-       if (!stack) {
-               unsigned long dummy;
-               stack = &dummy;
-               if (task && task != current)
-                       stack = (unsigned long *)task->thread.esp;
-       }
-
-#ifdef CONFIG_FRAME_POINTER
-       if (!ebp) {
-               if (task == current) {
-                       /* Grab ebp right from our regs */
-                       asm ("movl %%ebp, %0" : "=r" (ebp) : );
-               } else {
-                       /* ebp is the last reg pushed by switch_to */
-                       ebp = *(unsigned long *) task->thread.esp;
-               }
+       if (task == current) {
+               /* Grab ebp right from our regs */
+               asm ("movl %%ebp, %0" : "=r" (ebp) : );
+       } else {
+               /* ebp is the last reg pushed by switch_to */
+               ebp = *(unsigned long *) task->thread.esp;
        }
-#endif
 
        while (1) {
                struct thread_info *context;
                context = (struct thread_info *)
                        ((unsigned long)stack & (~(THREAD_SIZE - 1)));
-               ebp = print_context_stack(context, stack, ebp, ops, data);
-               /* Should be after the line below, but somewhere
-                  in early boot context comes out corrupted and we
-                  can't reference it -AK */
-               if (ops->stack(data, "IRQ") < 0)
-                       break;
+               ebp = print_context_stack(context, stack, ebp, log_lvl);
                stack = (unsigned long*)context->previous_esp;
                if (!stack)
                        break;
+               printk(log_lvl);
+               printk(" =======================\n");
        }
 }
-EXPORT_SYMBOL(dump_trace);
-
-static void
-print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-       printk(data);
-       print_symbol(msg, symbol);
-       printk("\n");
-}
-
-static void print_trace_warning(void *data, char *msg)
-{
-       printk("%s%s\n", (char *)data, msg);
-}
-
-static int print_trace_stack(void *data, char *name)
-{
-       return 0;
-}
-
-/*
- * Print one address/symbol entries per line.
- */
-static void print_trace_address(void *data, unsigned long addr)
-{
-       printk("%s [<%08lx>] ", (char *)data, addr);
-       print_symbol("%s\n", addr);
-}
-
-static struct stacktrace_ops print_trace_ops = {
-       .warning = print_trace_warning,
-       .warning_symbol = print_trace_warning_symbol,
-       .stack = print_trace_stack,
-       .address = print_trace_address,
-};
-
-static void
-show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
-                  unsigned long * stack, char *log_lvl)
-{
-       dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
-       printk("%s =======================\n", log_lvl);
-}
 
-void show_trace(struct task_struct *task, struct pt_regs *regs,
-               unsigned long * stack)
+void show_trace(struct task_struct *task, unsigned long * stack)
 {
-       show_trace_log_lvl(task, regs, stack, "");
+       show_trace_log_lvl(task, stack, "");
 }
 
-static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
-                              unsigned long *esp, char *log_lvl)
+static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
+                              char *log_lvl)
 {
        unsigned long *stack;
        int i;
@@ -310,21 +191,26 @@ static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
        }
 
        stack = esp;
+       printk(log_lvl);
        for(i = 0; i < kstack_depth_to_print; i++) {
                if (kstack_end(stack))
                        break;
-               if (i && ((i % 8) == 0))
-                       printk("\n%s       ", log_lvl);
+               if (i && ((i % 8) == 0)) {
+                       printk("\n");
+                       printk(log_lvl);
+                       printk("       ");
+               }
                printk("%08lx ", *stack++);
        }
-       printk("\n%sCall Trace:\n", log_lvl);
-       show_trace_log_lvl(task, regs, esp, log_lvl);
+       printk("\n");
+       printk(log_lvl);
+       printk("Call Trace:\n");
+       show_trace_log_lvl(task, esp, log_lvl);
 }
 
 void show_stack(struct task_struct *task, unsigned long *esp)
 {
-       printk("       ");
-       show_stack_log_lvl(task, NULL, esp, "");
+       show_stack_log_lvl(task, esp, "");
 }
 
 /*
@@ -334,7 +220,7 @@ void dump_stack(void)
 {
        unsigned long stack;
 
-       show_trace(current, NULL, &stack);
+       show_trace(current, &stack);
 }
 
 EXPORT_SYMBOL(dump_stack);
@@ -348,7 +234,7 @@ void show_registers(struct pt_regs *regs)
 
        esp = (unsigned long) (&regs->esp);
        savesegment(ss, ss);
-       if (user_mode_vm(regs)) {
+       if (user_mode(regs)) {
                in_kernel = 0;
                esp = regs->esp;
                ss = regs->xss & 0xffff;
@@ -367,9 +253,9 @@ void show_registers(struct pt_regs *regs)
                regs->esi, regs->edi, regs->ebp, esp);
        printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
                regs->xds & 0xffff, regs->xes & 0xffff, ss);
-       printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
-               TASK_COMM_LEN, current->comm, current->pid, current->xid,
-               current_thread_info(), current, current->thread_info);
+       printk(KERN_EMERG "Process %s (pid: %d[#%u], threadinfo=%p task=%p)",
+               current->comm, current->pid, current->xid,
+               current_thread_info(), current);
        /*
         * When in-kernel, we also print out the stack and code at the
         * time of the fault..
@@ -378,7 +264,7 @@ void show_registers(struct pt_regs *regs)
                u8 __user *eip;
 
                printk("\n" KERN_EMERG "Stack: ");
-               show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
+               show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
 
                printk(KERN_EMERG "Code: ");
 
@@ -401,35 +287,35 @@ void show_registers(struct pt_regs *regs)
 
 static void handle_BUG(struct pt_regs *regs)
 {
-       unsigned long eip = regs->eip;
        unsigned short ud2;
+       unsigned short line;
+       char *file;
+       char c;
+       unsigned long eip;
+
+       eip = regs->eip;
 
        if (eip < PAGE_OFFSET)
-               return;
+               goto no_bug;
        if (__get_user(ud2, (unsigned short __user *)eip))
-               return;
+               goto no_bug;
        if (ud2 != 0x0b0f)
-               return;
+               goto no_bug;
+       if (__get_user(line, (unsigned short __user *)(eip + 2)))
+               goto bug;
+       if (__get_user(file, (char * __user *)(eip + 4)) ||
+               (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
+               file = "<bad filename>";
 
        printk(KERN_EMERG "------------[ cut here ]------------\n");
+       printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-       do {
-               unsigned short line;
-               char *file;
-               char c;
-
-               if (__get_user(line, (unsigned short __user *)(eip + 2)))
-                       break;
-               if (__get_user(file, (char * __user *)(eip + 4)) ||
-                   (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
-                       file = "<bad filename>";
+no_bug:
+       return;
 
-               printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
-               return;
-       } while (0);
-#endif
-       printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
+       /* Here we know it was a BUG but file-n-line is unavailable */
+bug:
+       printk(KERN_EMERG "Kernel BUG\n");
 }
 
 /* This is gone through when something in the kernel
@@ -449,8 +335,6 @@ void die(const char * str, struct pt_regs * regs, long err)
        static int die_counter;
        unsigned long flags;
 
-       oops_enter();
-
        vxh_throw_oops();
 
        if (die.lock_owner != raw_smp_processor_id()) {
@@ -465,9 +349,6 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        if (++die.lock_owner_depth < 3) {
                int nl = 0;
-               unsigned long esp;
-               unsigned short ss;
-
                handle_BUG(regs);
                printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
@@ -488,26 +369,9 @@ void die(const char * str, struct pt_regs * regs, long err)
 #endif
                if (nl)
                        printk("\n");
-#ifdef CONFIG_SYSFS
-               printk(KERN_ALERT "last sysfs file: %s\n", last_sysfs_file);
-#endif
-               if (notify_die(DIE_OOPS, str, regs, err,
-                       current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
-                       show_registers(regs);
-                       vxh_dump_history();
-                       /* Executive summary in case the oops scrolled away */
-                       esp = (unsigned long) (&regs->esp);
-                       savesegment(ss, ss);
-                       if (user_mode(regs)) {
-                               esp = regs->esp;
-                               ss = regs->xss & 0xffff;
-                       }
-                       printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
-                       print_symbol("%s", regs->eip);
-                       printk(" SS:ESP %04x:%08lx\n", ss, esp);
-               }
-               else
-                       regs = NULL;
+               notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
+               show_registers(regs);
+               vxh_dump_history();
        } else
                printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
 
@@ -515,19 +379,17 @@ void die(const char * str, struct pt_regs * regs, long err)
        die.lock_owner = -1;
        spin_unlock_irqrestore(&die.lock, flags);
 
-       if (!regs)
-               return;
-
        if (kexec_should_crash(current))
                crash_kexec(regs);
 
        if (in_interrupt())
                panic("Fatal exception in interrupt");
 
-       if (panic_on_oops)
+       if (panic_on_oops) {
+               printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+               ssleep(5);
                panic("Fatal exception");
-
-       oops_exit();
+       }
        do_exit(SIGSEGV);
 }
 
@@ -633,82 +495,7 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-
-
-/*
- * lazy-check for CS validity on exec-shield binaries:
- *
- * the original non-exec stack patch was written by
- * Solar Designer <solar at openwall.com>. Thanks!
- */
-static int
-check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
-{
-       struct desc_struct *desc1, *desc2;
-       struct vm_area_struct *vma;
-       unsigned long limit;
-
-       if (current->mm == NULL)
-               return 0;
-
-       limit = -1UL;
-       if (current->mm->context.exec_limit != -1UL) {
-               limit = PAGE_SIZE;
-               spin_lock(&current->mm->page_table_lock);
-               for (vma = current->mm->mmap; vma; vma = vma->vm_next)
-                       if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
-                               limit = vma->vm_end;
-               spin_unlock(&current->mm->page_table_lock);
-               if (limit >= TASK_SIZE)
-                       limit = -1UL;
-               current->mm->context.exec_limit = limit;
-       }
-       set_user_cs(&current->mm->context.user_cs, limit);
-
-       desc1 = &current->mm->context.user_cs;
-       desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS;
-
-       if (desc1->a != desc2->a || desc1->b != desc2->b) {
-               /*
-                * The CS was not in sync - reload it and retry the
-                * instruction. If the instruction still faults then
-                * we won't hit this branch next time around.
-                */
-               if (print_fatal_signals >= 2) {
-                       printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
-                       printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
-               }
-               load_user_cs_desc(cpu, current->mm);
-               return 1;
-       }
-
-       return 0;
-}
-
-/*
- * The fixup code for errors in iret jumps to here (iret_exc).  It loses
- * the original trap number and error code.  The bogus trap 32 and error
- * code 0 are what the vanilla kernel delivers via:
- * DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
- *
- * In case of a general protection fault in the iret instruction, we
- * need to check for a lazy CS update for exec-shield.
- */
-fastcall void do_iret_error(struct pt_regs *regs, long error_code)
-{
-       int ok = check_lazy_exec_limit(get_cpu(), regs, error_code);
-       put_cpu();
-       if (!ok && notify_die(DIE_TRAP, "iret exception", regs,
-                             error_code, 32, SIGSEGV) != NOTIFY_STOP) {
-               siginfo_t info;
-               info.si_signo = SIGSEGV;
-               info.si_errno = 0;
-               info.si_code = ILL_BADSTK;
-               info.si_addr = 0;
-               do_trap(32, SIGSEGV, "iret exception", 0, regs, error_code,
-                       &info);
-       }
-}
+DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
 
 fastcall void __kprobes do_general_protection(struct pt_regs * regs,
                                              long error_code)
@@ -716,7 +503,6 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
        int cpu = get_cpu();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
        struct thread_struct *thread = &current->thread;
-       int ok;
 
        /*
         * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
@@ -743,6 +529,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
                put_cpu();
                return;
        }
+       put_cpu();
 
        current->thread.error_code = error_code;
        current->thread.trap_no = 13;
@@ -753,31 +540,17 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
        if (!user_mode(regs))
                goto gp_in_kernel;
 
-       ok = check_lazy_exec_limit(cpu, regs, error_code);
-
-       put_cpu();
-
-       if (ok)
-               return;
-
-       if (print_fatal_signals) {
-               printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
-               printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
-       }
-
        current->thread.error_code = error_code;
        current->thread.trap_no = 13;
        force_sig(SIGSEGV, current);
        return;
 
 gp_in_vm86:
-       put_cpu();
        local_irq_enable();
        handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
        return;
 
 gp_in_kernel:
-       put_cpu();
        if (!fixup_exception(regs)) {
                if (notify_die(DIE_GPF, "general protection fault", regs,
                                error_code, 13, SIGSEGV) == NOTIFY_STOP)
@@ -799,11 +572,18 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
 
 static void io_check_error(unsigned char reason, struct pt_regs * regs)
 {
+       unsigned long i;
+
        printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
        show_registers(regs);
 
        /* Re-enable the IOCK line, wait for a few seconds */
-       clear_io_check_error(reason);
+       reason = (reason & 0xf) | 8;
+       outb(reason, 0x61);
+       i = 2000;
+       while (--i) udelay(1000);
+       reason &= ~8;
+       outb(reason, 0x61);
 }
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
@@ -826,7 +606,7 @@ static DEFINE_SPINLOCK(nmi_print_lock);
 
 void die_nmi (struct pt_regs *regs, const char *msg)
 {
-       if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) ==
+       if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) ==
            NOTIFY_STOP)
                return;
 
@@ -840,6 +620,7 @@ void die_nmi (struct pt_regs *regs, const char *msg)
        printk(" on CPU%d, eip %08lx, registers:\n",
                smp_processor_id(), regs->eip);
        show_registers(regs);
+       printk(KERN_EMERG "console shuts up ...\n");
        console_silent();
        spin_unlock(&nmi_print_lock);
        bust_spinlocks(0);
@@ -847,7 +628,7 @@ void die_nmi (struct pt_regs *regs, const char *msg)
        /* If we are in kernel we are probably nested up pretty bad
         * and might aswell get out now while we still can.
        */
-       if (!user_mode_vm(regs)) {
+       if (!user_mode(regs)) {
                current->thread.trap_no = 2;
                crash_kexec(regs);
        }
@@ -864,7 +645,7 @@ static void default_do_nmi(struct pt_regs * regs)
                reason = get_nmi_reason();
  
        if (!(reason & 0xc0)) {
-               if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
+               if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
                                                        == NOTIFY_STOP)
                        return;
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -880,7 +661,7 @@ static void default_do_nmi(struct pt_regs * regs)
                unknown_nmi_error(reason, regs);
                return;
        }
-       if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
+       if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
                return;
        if (reason & 0x80)
                mem_parity_error(reason, regs);
@@ -918,7 +699,6 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
 
 void set_nmi_callback(nmi_callback_t callback)
 {
-       vmalloc_sync_all();
        rcu_assign_pointer(nmi_callback, callback);
 }
 EXPORT_SYMBOL_GPL(set_nmi_callback);
@@ -1389,22 +1169,6 @@ void __init trap_init(void)
 static int __init kstack_setup(char *s)
 {
        kstack_depth_to_print = simple_strtoul(s, NULL, 0);
-       return 1;
+       return 0;
 }
 __setup("kstack=", kstack_setup);
-
-#ifdef CONFIG_STACK_UNWIND
-static int __init call_trace_setup(char *s)
-{
-       if (strcmp(s, "old") == 0)
-               call_trace = -1;
-       else if (strcmp(s, "both") == 0)
-               call_trace = 0;
-       else if (strcmp(s, "newfallback") == 0)
-               call_trace = 1;
-       else if (strcmp(s, "new") == 2)
-               call_trace = 2;
-       return 1;
-}
-__setup("call_trace=", call_trace_setup);
-#endif