Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied...
[sfrench/cifs-2.6.git] / arch / arm / mm / fault.c
index c5e0622c77650480f4dc148254d77f3545606d5d..5d9ce7deb4a7bc6433f54aac7074e6749ee6c739 100644 (file)
@@ -10,7 +10,6 @@
  */
 #include <linux/module.h>
 #include <linux/signal.h>
-#include <linux/ptrace.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 
@@ -131,10 +130,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
        force_sig_info(sig, &si, tsk);
 }
 
-void
-do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-           unsigned int fsr, struct pt_regs *regs)
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
+       struct task_struct *tsk = current;
+       struct mm_struct *mm = tsk->active_mm;
+
        /*
         * If we are in kernel mode at this point, we
         * have no context to handle this fault with.
@@ -170,7 +170,7 @@ good_area:
        if (fsr & (1 << 11)) /* write? */
                mask = VM_WRITE;
        else
-               mask = VM_READ|VM_EXEC;
+               mask = VM_READ|VM_EXEC|VM_WRITE;
 
        fault = VM_FAULT_BADACCESS;
        if (!(vma->vm_flags & mask))
@@ -197,7 +197,7 @@ survive:
                return fault;
        }
 
-       if (tsk->pid != 1)
+       if (!is_init(tsk))
                goto out;
 
        /*
@@ -229,7 +229,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
         * If we're in an interrupt or have no user
         * context, we must not take the fault..
         */
-       if (in_interrupt() || !mm)
+       if (in_atomic() || !mm)
                goto no_context;
 
        /*
@@ -319,7 +319,6 @@ static int
 do_translation_fault(unsigned long addr, unsigned int fsr,
                     struct pt_regs *regs)
 {
-       struct task_struct *tsk;
        unsigned int index;
        pgd_t *pgd, *pgd_k;
        pmd_t *pmd, *pmd_k;
@@ -351,9 +350,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
        return 0;
 
 bad_area:
-       tsk = current;
-
-       do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
+       do_bad_area(addr, fsr, regs);
        return 0;
 }
 
@@ -364,8 +361,7 @@ bad_area:
 static int
 do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
-       struct task_struct *tsk = current;
-       do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
+       do_bad_area(addr, fsr, regs);
        return 0;
 }
 
@@ -441,7 +437,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *)
 /*
  * Dispatch a data abort to the relevant handler.
  */
-asmlinkage void
+asmlinkage void __exception
 do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
        const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
@@ -460,7 +456,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        notify_die("", regs, &info, fsr, 0);
 }
 
-asmlinkage void
+asmlinkage void __exception
 do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
        do_translation_fault(addr, 0, regs);