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.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 04ad4001a289..2fb9e63b8fc4 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -49,15 +49,19 @@
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#define VM_FAULT_SIGNAL 0x080000
53 53
54static unsigned long store_indication; 54static unsigned long store_indication __read_mostly;
55 55
56void fault_init(void) 56#ifdef CONFIG_64BIT
57static int __init fault_init(void)
57{ 58{
58 if (test_facility(2) && test_facility(75)) 59 if (test_facility(75))
59 store_indication = 0xc00; 60 store_indication = 0xc00;
61 return 0;
60} 62}
63early_initcall(fault_init);
64#endif
61 65
62static inline int notify_page_fault(struct pt_regs *regs) 66static inline int notify_page_fault(struct pt_regs *regs)
63{ 67{
@@ -273,10 +277,16 @@ static inline int do_exception(struct pt_regs *regs, int access)
273 unsigned int flags; 277 unsigned int flags;
274 int fault; 278 int fault;
275 279
280 tsk = current;
281 /*
282 * The instruction that caused the program check has
283 * been nullified. Don't signal single step via SIGTRAP.
284 */
285 clear_tsk_thread_flag(tsk, TIF_PER_TRAP);
286
276 if (notify_page_fault(regs)) 287 if (notify_page_fault(regs))
277 return 0; 288 return 0;
278 289
279 tsk = current;
280 mm = tsk->mm; 290 mm = tsk->mm;
281 trans_exc_code = regs->int_parm_long; 291 trans_exc_code = regs->int_parm_long;
282 292
@@ -372,11 +382,6 @@ retry:
372 goto retry; 382 goto retry;
373 } 383 }
374 } 384 }
375 /*
376 * The instruction that caused the program check will
377 * be repeated. Don't signal single step via SIGTRAP.
378 */
379 clear_tsk_thread_flag(tsk, TIF_PER_TRAP);
380 fault = 0; 385 fault = 0;
381out_up: 386out_up:
382 up_read(&mm->mmap_sem); 387 up_read(&mm->mmap_sem);
@@ -423,6 +428,12 @@ void __kprobes do_asce_exception(struct pt_regs *regs)
423 struct vm_area_struct *vma; 428 struct vm_area_struct *vma;
424 unsigned long trans_exc_code; 429 unsigned long trans_exc_code;
425 430
431 /*
432 * The instruction that caused the program check has
433 * been nullified. Don't signal single step via SIGTRAP.
434 */
435 clear_tsk_thread_flag(current, TIF_PER_TRAP);
436
426 trans_exc_code = regs->int_parm_long; 437 trans_exc_code = regs->int_parm_long;
427 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) 438 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
428 goto no_context; 439 goto no_context;
@@ -558,7 +569,7 @@ static void pfault_interrupt(struct ext_code ext_code,
558 subcode = ext_code.subcode; 569 subcode = ext_code.subcode;
559 if ((subcode & 0xff00) != __SUBCODE_MASK) 570 if ((subcode & 0xff00) != __SUBCODE_MASK)
560 return; 571 return;
561 kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; 572 inc_irq_stat(IRQEXT_PFL);
562 /* Get the token (= pid of the affected task). */ 573 /* Get the token (= pid of the affected task). */
563 pid = sizeof(void *) == 4 ? param32 : param64; 574 pid = sizeof(void *) == 4 ? param32 : param64;
564 rcu_read_lock(); 575 rcu_read_lock();