aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/fault.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-07 18:24:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-07 18:24:38 -0500
commit280c84d1c1726be7ada045735858acdc8cfdd65a (patch)
treeb9afa3fb97b08272b6952d5c8d1fe31f6a8092fa /arch/s390/mm/fault.c
parent8efdf2b759409f85953b84d52a14ea4d39c80474 (diff)
parentde9587a2f54d2d0063f0dbc775328129b9daaaa2 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "The bulk of the patches for the 3.13 merge window. Heiko spent quite a bit of work to improve the code generation for the kernel. That includes the exploitation of the interlocked-access facility for the atomics and bitops implementation and the improvement for the -march and -mtune compiler settings. Another important change is the removal of the user_mode=home option, user processes now always run in primary space. The storage keys are not initialized at system startup any more, with that the storage key removal work is complete. For the PCI support the hibernation hooks have been implemented. And as usual cleanup and fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (62 commits) s390/scm_blk: fix endless loop for requests != REQ_TYPE_FS s390/mm,tlb: correct tlb flush on page table upgrade s390/mm: page_table_realloc returns failure s390: allow to set gcc -mtune flag s390/percpu: remove this_cpu_xor() implementation s390/vtime: correct idle time calculation s390/time: fix get_tod_clock_ext inline assembly tty/hvc_iucv: remove redundant NULL check s390/dasd: Write to profile data area only if it is available s390: convert use of typedef ctl_table to struct ctl_table s390/pci: cleanup function information block s390/pci: remove CONFIG_PCI_DEBUG dependancy s390/pci: message cleanup Update default configuration s390: add a couple of useful defconfigs s390/percpu: make use of interlocked-access facility 1 instructions s390/percpu: use generic percpu ops for CONFIG_32BIT s390/compat: make psw32_user_bits a constant value again s390: fix handling of runtime instrumentation psw bit s390: fix save and restore of the floating-point-control register ...
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);