Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[powerpc.git] / arch / arm / kernel / traps.c
index 66e5a05..d566d5f 100644 (file)
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/kallsyms.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -165,7 +165,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
        } else if (verify_stack(fp)) {
                printk("invalid frame pointer 0x%08x", fp);
                ok = 0;
-       } else if (fp < (unsigned long)(tsk->thread_info + 1))
+       } else if (fp < (unsigned long)end_of_stack(tsk))
                printk("frame pointer underflow");
        printk("\n");
 
@@ -198,35 +198,47 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
        barrier();
 }
 
-DEFINE_SPINLOCK(die_lock);
-
-/*
- * This function is protected against re-entrancy.
- */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 {
-       struct task_struct *tsk = current;
+       struct task_struct *tsk = thread->task;
        static int die_counter;
 
-       console_verbose();
-       spin_lock_irq(&die_lock);
-       bust_spinlocks(1);
-
        printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
        print_modules();
        __show_regs(regs);
        printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-               tsk->comm, tsk->pid, tsk->thread_info + 1);
+               tsk->comm, tsk->pid, thread + 1);
 
        if (!user_mode(regs) || in_interrupt()) {
                dump_mem("Stack: ", regs->ARM_sp,
-                        THREAD_SIZE + (unsigned long)tsk->thread_info);
+                        THREAD_SIZE + (unsigned long)task_stack_page(tsk));
                dump_backtrace(regs, tsk);
                dump_instr(regs);
        }
+}
+
+DEFINE_SPINLOCK(die_lock);
 
+/*
+ * This function is protected against re-entrancy.
+ */
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+{
+       struct thread_info *thread = current_thread_info();
+
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
+       __die(str, err, thread, regs);
        bust_spinlocks(0);
        spin_unlock_irq(&die_lock);
+
+       if (panic_on_oops) {
+               printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+               ssleep(5);
+               panic("Fatal exception");
+       }
+
        do_exit(SIGSEGV);
 }
 
@@ -400,7 +412,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
        struct thread_info *thread = current_thread_info();
        siginfo_t info;
 
-       if ((no >> 16) != 0x9f)
+       if ((no >> 16) != (__ARM_NR_BASE>> 16))
                return bad_syscall(no, regs);
 
        switch (no & 0xffff) {
@@ -494,7 +506,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
                if (!pmd_present(*pmd))
                        goto bad_access;
                pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
-               if (!pte_present(*pte) || !pte_write(*pte)) {
+               if (!pte_present(*pte) || !pte_dirty(*pte)) {
                        pte_unmap_unlock(pte, ptl);
                        goto bad_access;
                }