aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r--arch/s390/mm/fault.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 9564fc779b27..a9a301866b3c 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -307,7 +307,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
307 307
308#ifdef CONFIG_PGSTE 308#ifdef CONFIG_PGSTE
309 if (test_tsk_thread_flag(current, TIF_SIE) && S390_lowcore.gmap) { 309 if (test_tsk_thread_flag(current, TIF_SIE) && S390_lowcore.gmap) {
310 address = gmap_fault(address, 310 address = __gmap_fault(address,
311 (struct gmap *) S390_lowcore.gmap); 311 (struct gmap *) S390_lowcore.gmap);
312 if (address == -EFAULT) { 312 if (address == -EFAULT) {
313 fault = VM_FAULT_BADMAP; 313 fault = VM_FAULT_BADMAP;
@@ -393,7 +393,7 @@ void __kprobes do_protection_exception(struct pt_regs *regs, long pgm_int_code,
393 int fault; 393 int fault;
394 394
395 /* Protection exception is suppressing, decrement psw address. */ 395 /* Protection exception is suppressing, decrement psw address. */
396 regs->psw.addr -= (pgm_int_code >> 16); 396 regs->psw.addr = __rewind_psw(regs->psw, pgm_int_code >> 16);
397 /* 397 /*
398 * Check for low-address protection. This needs to be treated 398 * Check for low-address protection. This needs to be treated
399 * as a special case because the translation exception code 399 * as a special case because the translation exception code
@@ -454,7 +454,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
454 struct pt_regs regs; 454 struct pt_regs regs;
455 int access, fault; 455 int access, fault;
456 456
457 regs.psw.mask = psw_kernel_bits; 457 regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
458 if (!irqs_disabled()) 458 if (!irqs_disabled())
459 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; 459 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
460 regs.psw.addr = (unsigned long) __builtin_return_address(0); 460 regs.psw.addr = (unsigned long) __builtin_return_address(0);
@@ -587,8 +587,13 @@ static void pfault_interrupt(unsigned int ext_int_code,
587 } else { 587 } else {
588 /* Completion interrupt was faster than initial 588 /* Completion interrupt was faster than initial
589 * interrupt. Set pfault_wait to -1 so the initial 589 * interrupt. Set pfault_wait to -1 so the initial
590 * interrupt doesn't put the task to sleep. */ 590 * interrupt doesn't put the task to sleep.
591 tsk->thread.pfault_wait = -1; 591 * If the task is not running, ignore the completion
592 * interrupt since it must be a leftover of a PFAULT
593 * CANCEL operation which didn't remove all pending
594 * completion interrupts. */
595 if (tsk->state == TASK_RUNNING)
596 tsk->thread.pfault_wait = -1;
592 } 597 }
593 put_task_struct(tsk); 598 put_task_struct(tsk);
594 } else { 599 } else {