aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2012-07-27 02:54:20 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-07-30 05:03:08 -0400
commitf2c76e3b6f72c3fda290998109594dc490b8b087 (patch)
treec82f073d8c61ff212e34c90e8f3090abbb7ac967 /arch/s390/mm
parent216550e4fd5ade3f255bd5460db6b59e57f5f8c2 (diff)
s390/mm: make page faults killable
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>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/fault.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 6a12d1bb6e09..2a34a1c35a7c 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -49,6 +49,7 @@
49#define VM_FAULT_BADCONTEXT 0x010000 49#define VM_FAULT_BADCONTEXT 0x010000
50#define VM_FAULT_BADMAP 0x020000 50#define VM_FAULT_BADMAP 0x020000
51#define VM_FAULT_BADACCESS 0x040000 51#define VM_FAULT_BADACCESS 0x040000
52#define VM_FAULT_SIGNAL 0x080000
52 53
53static unsigned long store_indication; 54static unsigned long store_indication;
54 55
@@ -229,6 +230,10 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
229 case VM_FAULT_BADCONTEXT: 230 case VM_FAULT_BADCONTEXT:
230 do_no_context(regs); 231 do_no_context(regs);
231 break; 232 break;
233 case VM_FAULT_SIGNAL:
234 if (!user_mode(regs))
235 do_no_context(regs);
236 break;
232 default: /* fault & VM_FAULT_ERROR */ 237 default: /* fault & VM_FAULT_ERROR */
233 if (fault & VM_FAULT_OOM) { 238 if (fault & VM_FAULT_OOM) {
234 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 239 if (!(regs->psw.mask & PSW_MASK_PSTATE))
@@ -286,7 +291,7 @@ static inline int do_exception(struct pt_regs *regs, int access)
286 291
287 address = trans_exc_code & __FAIL_ADDR_MASK; 292 address = trans_exc_code & __FAIL_ADDR_MASK;
288 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); 293 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
289 flags = FAULT_FLAG_ALLOW_RETRY; 294 flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
290 if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) 295 if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
291 flags |= FAULT_FLAG_WRITE; 296 flags |= FAULT_FLAG_WRITE;
292 down_read(&mm->mmap_sem); 297 down_read(&mm->mmap_sem);
@@ -335,6 +340,11 @@ retry:
335 * the fault. 340 * the fault.
336 */ 341 */
337 fault = handle_mm_fault(mm, vma, address, flags); 342 fault = handle_mm_fault(mm, vma, address, flags);
343 /* No reason to continue if interrupted by SIGKILL. */
344 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
345 fault = VM_FAULT_SIGNAL;
346 goto out;
347 }
338 if (unlikely(fault & VM_FAULT_ERROR)) 348 if (unlikely(fault & VM_FAULT_ERROR))
339 goto out_up; 349 goto out_up;
340 350