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.c46
1 files changed, 2 insertions, 44 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fc6679210d83..d95265b2719f 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -115,13 +115,8 @@ static inline int user_space_fault(unsigned long trans_exc_code)
115 if (trans_exc_code == 2) 115 if (trans_exc_code == 2)
116 /* Access via secondary space, set_fs setting decides */ 116 /* Access via secondary space, set_fs setting decides */
117 return current->thread.mm_segment.ar4; 117 return current->thread.mm_segment.ar4;
118 if (s390_user_mode == HOME_SPACE_MODE)
119 /* User space if the access has been done via home space. */
120 return trans_exc_code == 3;
121 /* 118 /*
122 * If the user space is not the home space the kernel runs in home 119 * Access via primary space or access register is from user space
123 * space. Access via secondary space has already been covered,
124 * access via primary space or access register is from user space
125 * and access via home space is from the kernel. 120 * and access via home space is from the kernel.
126 */ 121 */
127 return trans_exc_code != 3; 122 return trans_exc_code != 3;
@@ -428,50 +423,13 @@ void __kprobes do_dat_exception(struct pt_regs *regs)
428 do_fault_error(regs, fault); 423 do_fault_error(regs, fault);
429} 424}
430 425
431#ifdef CONFIG_64BIT
432void __kprobes do_asce_exception(struct pt_regs *regs)
433{
434 struct mm_struct *mm = current->mm;
435 struct vm_area_struct *vma;
436 unsigned long trans_exc_code;
437
438 /*
439 * The instruction that caused the program check has
440 * been nullified. Don't signal single step via SIGTRAP.
441 */
442 clear_tsk_thread_flag(current, TIF_PER_TRAP);
443
444 trans_exc_code = regs->int_parm_long;
445 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
446 goto no_context;
447
448 down_read(&mm->mmap_sem);
449 vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK);
450 up_read(&mm->mmap_sem);
451
452 if (vma) {
453 update_mm(mm, current);
454 return;
455 }
456
457 /* User mode accesses just cause a SIGSEGV */
458 if (user_mode(regs)) {
459 do_sigsegv(regs, SEGV_MAPERR);
460 return;
461 }
462
463no_context:
464 do_no_context(regs);
465}
466#endif
467
468int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) 426int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
469{ 427{
470 struct pt_regs regs; 428 struct pt_regs regs;
471 int access, fault; 429 int access, fault;
472 430
473 /* Emulate a uaccess fault from kernel mode. */ 431 /* Emulate a uaccess fault from kernel mode. */
474 regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; 432 regs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK;
475 if (!irqs_disabled()) 433 if (!irqs_disabled())
476 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; 434 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
477 regs.psw.addr = (unsigned long) __builtin_return_address(0); 435 regs.psw.addr = (unsigned long) __builtin_return_address(0);