s390/mm: make page faults killable
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Fri, 27 Jul 2012 06:54:20 +0000 (08:54 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 30 Jul 2012 09:03:08 +0000 (11:03 +0200)
This is the s390 variant of 37b23e05 "x86,mm: make pagefault killable".

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/mm/fault.c

index 6a12d1bb6e09d065e5a4b2625ce79ba7209b5c2b..2a34a1c35a7ca8bac7938ad6980b3ac4067773cd 100644 (file)
@@ -49,6 +49,7 @@
 #define VM_FAULT_BADCONTEXT    0x010000
 #define VM_FAULT_BADMAP                0x020000
 #define VM_FAULT_BADACCESS     0x040000
+#define VM_FAULT_SIGNAL        0x080000
 
 static unsigned long store_indication;
 
@@ -229,6 +230,10 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
        case VM_FAULT_BADCONTEXT:
                do_no_context(regs);
                break;
+       case VM_FAULT_SIGNAL:
+               if (!user_mode(regs))
+                       do_no_context(regs);
+               break;
        default: /* fault & VM_FAULT_ERROR */
                if (fault & VM_FAULT_OOM) {
                        if (!(regs->psw.mask & PSW_MASK_PSTATE))
@@ -286,7 +291,7 @@ static inline int do_exception(struct pt_regs *regs, int access)
 
        address = trans_exc_code & __FAIL_ADDR_MASK;
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
-       flags = FAULT_FLAG_ALLOW_RETRY;
+       flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
        if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
                flags |= FAULT_FLAG_WRITE;
        down_read(&mm->mmap_sem);
@@ -335,6 +340,11 @@ retry:
         * the fault.
         */
        fault = handle_mm_fault(mm, vma, address, flags);
+       /* No reason to continue if interrupted by SIGKILL. */
+       if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+               fault = VM_FAULT_SIGNAL;
+               goto out;
+       }
        if (unlikely(fault & VM_FAULT_ERROR))
                goto out_up;