This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / s390 / mm / fault.c
index 8b2dda8..9cf3b39 100644 (file)
@@ -159,8 +159,7 @@ static void force_sigsegv(struct pt_regs *regs, unsigned long error_code,
  *   11       Page translation     ->  Not present       (nullification)
  *   3b       Region third trans.  ->  Not present       (nullification)
  */
-extern inline void
-do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
+extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
 {
         struct task_struct *tsk;
         struct mm_struct *mm;
@@ -178,7 +177,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
         * as a special case because the translation exception code 
         * field is not guaranteed to contain valid data in this case.
         */
-       if (is_protection && !(S390_lowcore.trans_exc_code & 4)) {
+       if (error_code == 4 && !(S390_lowcore.trans_exc_code & 4)) {
 
                /* Low-address protection hit in kernel mode means 
                   NULL pointer write access in kernel mode.  */
@@ -233,7 +232,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
  */
 good_area:
        si_code = SEGV_ACCERR;
-       if (!is_protection) {
+       if (error_code != 4) {
                /* page not present, check vm flags */
                if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                        goto bad_area;
@@ -248,7 +247,7 @@ survive:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-       switch (handle_mm_fault(mm, vma, address, is_protection)) {
+       switch (handle_mm_fault(mm, vma, address, error_code == 4)) {
        case VM_FAULT_MINOR:
                tsk->min_flt++;
                break;
@@ -264,11 +263,6 @@ survive:
        }
 
         up_read(&mm->mmap_sem);
-       /*
-        * The instruction that caused the program check will
-        * be repeated. Don't signal single step via SIGTRAP.
-        */
-       clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
         return;
 
 /*
@@ -343,15 +337,28 @@ do_sigbus:
 void do_protection_exception(struct pt_regs *regs, unsigned long error_code)
 {
        regs->psw.addr -= (error_code >> 16);
-       do_exception(regs, 4, 1);
+       do_exception(regs, 4);
 }
 
-void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
+void do_segment_exception(struct pt_regs *regs, unsigned long error_code)
 {
-       do_exception(regs, error_code & 0xff, 0);
+       do_exception(regs, 0x10);
 }
 
-#ifndef CONFIG_ARCH_S390X
+void do_page_exception(struct pt_regs *regs, unsigned long error_code)
+{
+       do_exception(regs, 0x11);
+}
+
+#ifdef CONFIG_ARCH_S390X
+
+void
+do_region_exception(struct pt_regs *regs, unsigned long error_code)
+{
+       do_exception(regs, 0x3b);
+}
+
+#else /* CONFIG_ARCH_S390X */
 
 typedef struct _pseudo_wait_t {
        struct _pseudo_wait_t *next;
@@ -449,11 +456,6 @@ do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
                 wait_struct.next = pseudo_lock_queue;
                 pseudo_lock_queue = &wait_struct;
                 spin_unlock(&pseudo_wait_spinlock);
-               /*
-                * The instruction that caused the program check will
-                * be repeated. Don't signal single step via SIGTRAP.
-                */
-               clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
                 /* go to sleep */
                 wait_event(wait_struct.queue, wait_struct.resolved);
         }