[PATCH] i386: actively synchronize vmalloc area when registering certain callbacks
[powerpc.git] / arch / i386 / kernel / traps.c
index 0aaebf3..d510de7 100644 (file)
@@ -99,6 +99,8 @@ int register_die_notifier(struct notifier_block *nb)
 {
        int err = 0;
        unsigned long flags;
+
+       vmalloc_sync_all();
        spin_lock_irqsave(&die_notifier_lock, flags);
        err = notifier_chain_register(&i386die_chain, nb);
        spin_unlock_irqrestore(&die_notifier_lock, flags);
@@ -112,12 +114,30 @@ 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)
+/*
+ * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line.
+ */
+static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
+                                       int printed)
 {
-       printk(log_lvl);
+       if (!printed)
+               printk(log_lvl);
+
+#if CONFIG_STACK_BACKTRACE_COLS == 1
        printk(" [<%08lx>] ", addr);
+#else
+       printk(" <%08lx> ", addr);
+#endif
        print_symbol("%s", addr);
-       printk("\n");
+
+       printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
+
+       if (printed)
+               printk("  ");
+       else
+               printk("\n");
+
+       return printed;
 }
 
 static inline unsigned long print_context_stack(struct thread_info *tinfo,
@@ -125,20 +145,24 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
                                char *log_lvl)
 {
        unsigned long addr;
+       int printed = 0; /* nr of entries already printed on current line */
 
 #ifdef CONFIG_FRAME_POINTER
        while (valid_stack_ptr(tinfo, (void *)ebp)) {
                addr = *(unsigned long *)(ebp + 4);
-               print_addr_and_symbol(addr, log_lvl);
+               printed = print_addr_and_symbol(addr, log_lvl, printed);
                ebp = *(unsigned long *)ebp;
        }
 #else
        while (valid_stack_ptr(tinfo, stack)) {
                addr = *stack++;
                if (__kernel_text_address(addr))
-                       print_addr_and_symbol(addr, log_lvl);
+                       printed = print_addr_and_symbol(addr, log_lvl, printed);
        }
 #endif
+       if (printed)
+               printk("\n");
+
        return ebp;
 }
 
@@ -166,7 +190,7 @@ static void show_trace_log_lvl(struct task_struct *task,
                stack = (unsigned long*)context->previous_esp;
                if (!stack)
                        break;
-               printk(KERN_EMERG " =======================\n");
+               printk("%s =======================\n", log_lvl);
        }
 }
 
@@ -195,14 +219,12 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
                        break;
                if (i && ((i % 8) == 0)) {
                        printk("\n");
-                       printk(log_lvl);
-                       printk("       ");
+                       printk("%s       ", log_lvl);
                }
                printk("%08lx ", *stack++);
        }
        printk("\n");
-       printk(log_lvl);
-       printk("Call Trace:\n");
+       printk("%sCall Trace:\n", log_lvl);
        show_trace_log_lvl(task, esp, log_lvl);
 }
 
@@ -239,9 +261,11 @@ void show_registers(struct pt_regs *regs)
        }
        print_modules();
        printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
-                       "EFLAGS: %08lx   (%s) \n",
+                       "EFLAGS: %08lx   (%s %.*s) \n",
                smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-               print_tainted(), regs->eflags, system_utsname.release);
+               print_tainted(), regs->eflags, system_utsname.release,
+               (int)strcspn(system_utsname.version, " "),
+               system_utsname.version);
        print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
        printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
@@ -691,6 +715,7 @@ 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);