Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / arch / x86 / kernel / traps_32.c
index 05c27ec..02d1e1e 100644 (file)
@@ -63,6 +63,9 @@
 
 int panic_on_unrecovered_nmi;
 
+DECLARE_BITMAP(used_vectors, NR_VECTORS);
+EXPORT_SYMBOL_GPL(used_vectors);
+
 asmlinkage int system_call(void);
 
 /* Do we ignore FPU interrupts ? */
@@ -112,7 +115,7 @@ struct stack_frame {
 
 static inline unsigned long print_context_stack(struct thread_info *tinfo,
                                unsigned long *stack, unsigned long ebp,
-                               struct stacktrace_ops *ops, void *data)
+                               const struct stacktrace_ops *ops, void *data)
 {
 #ifdef CONFIG_FRAME_POINTER
        struct stack_frame *frame = (struct stack_frame *)ebp;
@@ -149,7 +152,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
 
 void dump_trace(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack,
-               struct stacktrace_ops *ops, void *data)
+               const struct stacktrace_ops *ops, void *data)
 {
        unsigned long ebp = 0;
 
@@ -221,7 +224,7 @@ static void print_trace_address(void *data, unsigned long addr)
        touch_nmi_watchdog();
 }
 
-static struct stacktrace_ops print_trace_ops = {
+static const struct stacktrace_ops print_trace_ops = {
        .warning = print_trace_warning,
        .warning_symbol = print_trace_warning_symbol,
        .stack = print_trace_stack,
@@ -280,6 +283,11 @@ void dump_stack(void)
 {
        unsigned long stack;
 
+       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+               current->pid, current->comm, print_tainted(),
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
        show_trace(current, NULL, &stack);
 }
 
@@ -288,48 +296,24 @@ EXPORT_SYMBOL(dump_stack);
 void show_registers(struct pt_regs *regs)
 {
        int i;
-       int in_kernel = 1;
-       unsigned long esp;
-       unsigned short ss, gs;
-
-       esp = (unsigned long) (&regs->esp);
-       savesegment(ss, ss);
-       savesegment(gs, gs);
-       if (user_mode_vm(regs)) {
-               in_kernel = 0;
-               esp = regs->esp;
-               ss = regs->xss & 0xffff;
-       }
+
        print_modules();
-       printk(KERN_EMERG "CPU:    %d\n"
-               KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
-               KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
-               smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-               print_tainted(), regs->eflags, init_utsname()->release,
-               (int)strcspn(init_utsname()->version, " "),
-               init_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);
-       printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-               regs->esi, regs->edi, regs->ebp, esp);
-       printk(KERN_EMERG "ds: %04x   es: %04x   fs: %04x  gs: %04x  ss: %04x\n",
-              regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
+       __show_registers(regs, 0);
        printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
-               TASK_COMM_LEN, current->comm, current->pid,
+               TASK_COMM_LEN, current->comm, task_pid_nr(current),
                current_thread_info(), current, task_thread_info(current));
        /*
         * When in-kernel, we also print out the stack and code at the
         * time of the fault..
         */
-       if (in_kernel) {
+       if (!user_mode_vm(regs)) {
                u8 *eip;
                unsigned int code_prologue = code_bytes * 43 / 64;
                unsigned int code_len = code_bytes;
                unsigned char c;
 
                printk("\n" KERN_EMERG "Stack: ");
-               show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
+               show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
 
                printk(KERN_EMERG "Code: ");
 
@@ -374,11 +358,11 @@ int is_valid_bugaddr(unsigned long eip)
 void die(const char * str, struct pt_regs * regs, long err)
 {
        static struct {
-               spinlock_t lock;
+               raw_spinlock_t lock;
                u32 lock_owner;
                int lock_owner_depth;
        } die = {
-               .lock =                 __SPIN_LOCK_UNLOCKED(die.lock),
+               .lock =                 __RAW_SPIN_LOCK_UNLOCKED,
                .lock_owner =           -1,
                .lock_owner_depth =     0
        };
@@ -389,40 +373,33 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        if (die.lock_owner != raw_smp_processor_id()) {
                console_verbose();
-               spin_lock_irqsave(&die.lock, flags);
+               raw_local_irq_save(flags);
+               __raw_spin_lock(&die.lock);
                die.lock_owner = smp_processor_id();
                die.lock_owner_depth = 0;
                bust_spinlocks(1);
-       }
-       else
-               local_save_flags(flags);
+       } else
+               raw_local_irq_save(flags);
 
        if (++die.lock_owner_depth < 3) {
-               int nl = 0;
                unsigned long esp;
                unsigned short ss;
 
                report_bug(regs->eip, regs);
 
-               printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+               printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
+                      ++die_counter);
 #ifdef CONFIG_PREEMPT
-               printk(KERN_EMERG "PREEMPT ");
-               nl = 1;
+               printk("PREEMPT ");
 #endif
 #ifdef CONFIG_SMP
-               if (!nl)
-                       printk(KERN_EMERG);
                printk("SMP ");
-               nl = 1;
 #endif
 #ifdef CONFIG_DEBUG_PAGEALLOC
-               if (!nl)
-                       printk(KERN_EMERG);
                printk("DEBUG_PAGEALLOC");
-               nl = 1;
 #endif
-               if (nl)
-                       printk("\n");
+               printk("\n");
+
                if (notify_die(DIE_OOPS, str, regs, err,
                                        current->thread.trap_no, SIGSEGV) !=
                                NOTIFY_STOP) {
@@ -446,7 +423,8 @@ void die(const char * str, struct pt_regs * regs, long err)
        bust_spinlocks(0);
        die.lock_owner = -1;
        add_taint(TAINT_DIE);
-       spin_unlock_irqrestore(&die.lock, flags);
+       __raw_spin_unlock(&die.lock);
+       raw_local_irq_restore(flags);
 
        if (!regs)
                return;
@@ -563,6 +541,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
        info.si_errno = 0; \
        info.si_code = sicode; \
        info.si_addr = (void __user *)siaddr; \
+       trace_hardirqs_fixup(); \
        if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
                                                == NOTIFY_STOP) \
                return; \
@@ -629,7 +608,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
            printk_ratelimit())
                printk(KERN_INFO
                    "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
-                   current->comm, current->pid,
+                   current->comm, task_pid_nr(current),
                    regs->eip, regs->esp, error_code);
 
        force_sig(SIGSEGV, current);
@@ -815,6 +794,8 @@ void restart_nmi(void)
 #ifdef CONFIG_KPROBES
 fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
+       trace_hardirqs_fixup();
+
        if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
                        == NOTIFY_STOP)
                return;
@@ -852,6 +833,8 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
        unsigned int condition;
        struct task_struct *tsk = current;
 
+       trace_hardirqs_fixup();
+
        get_debugreg(condition, 6);
 
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
@@ -1112,20 +1095,6 @@ asmlinkage void math_emulate(long arg)
 
 #endif /* CONFIG_MATH_EMULATION */
 
-#ifdef CONFIG_X86_F00F_BUG
-void __init trap_init_f00f_bug(void)
-{
-       __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
-
-       /*
-        * Update the IDT descriptor and reload the IDT so that
-        * it uses the read-only mapped virtual address.
-        */
-       idt_descr.address = fix_to_virt(FIX_F00F_IDT);
-       load_idt(&idt_descr);
-}
-#endif
-
 /*
  * This needs to use 'idt_table' rather than 'idt', and
  * thus use the _nonmapped_ version of the IDT, as the
@@ -1163,6 +1132,8 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
 
 void __init trap_init(void)
 {
+       int i;
+
 #ifdef CONFIG_EISA
        void __iomem *p = ioremap(0x0FFFD9, 4);
        if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1222,6 +1193,11 @@ void __init trap_init(void)
 
        set_system_gate(SYSCALL_VECTOR,&system_call);
 
+       /* Reserve all the builtin and the syscall vector. */
+       for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
+               set_bit(i, used_vectors);
+       set_bit(SYSCALL_VECTOR, used_vectors);
+
        /*
         * Should be a barrier for any external CPU state.
         */