aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/entry.S1
-rw-r--r--arch/s390/kernel/entry64.S1
-rw-r--r--arch/s390/kernel/kprobes.c9
3 files changed, 10 insertions, 1 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5efce7202984..1ecc337fb679 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -557,6 +557,7 @@ pgm_svcper:
557# per was called from kernel, must be kprobes 557# per was called from kernel, must be kprobes
558# 558#
559kernel_per: 559kernel_per:
560 REENABLE_IRQS
560 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check 561 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
561 mvi SP_SVCNR+1(%r15),0xff 562 mvi SP_SVCNR+1(%r15),0xff
562 la %r2,SP_PTREGS(%r15) # address of register-save area 563 la %r2,SP_PTREGS(%r15) # address of register-save area
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index a2be23922f43..8f3e802174db 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -568,6 +568,7 @@ pgm_svcper:
568# per was called from kernel, must be kprobes 568# per was called from kernel, must be kprobes
569# 569#
570kernel_per: 570kernel_per:
571 REENABLE_IRQS
571 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number 572 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
572 la %r2,SP_PTREGS(%r15) # address of register-save area 573 la %r2,SP_PTREGS(%r15) # address of register-save area
573 brasl %r14,do_single_step 574 brasl %r14,do_single_step
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 2a3d2bf6f083..d60fc4398516 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -316,6 +316,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
316 return 1; 316 return 1;
317 317
318ss_probe: 318ss_probe:
319 if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
320 local_irq_disable();
319 prepare_singlestep(p, regs); 321 prepare_singlestep(p, regs);
320 kcb->kprobe_status = KPROBE_HIT_SS; 322 kcb->kprobe_status = KPROBE_HIT_SS;
321 return 1; 323 return 1;
@@ -463,6 +465,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
463 goto out; 465 goto out;
464 } 466 }
465 reset_current_kprobe(); 467 reset_current_kprobe();
468 if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
469 local_irq_enable();
466out: 470out:
467 preempt_enable_no_resched(); 471 preempt_enable_no_resched();
468 472
@@ -502,8 +506,11 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
502 regs->psw.mask |= kcb->kprobe_saved_imask; 506 regs->psw.mask |= kcb->kprobe_saved_imask;
503 if (kcb->kprobe_status == KPROBE_REENTER) 507 if (kcb->kprobe_status == KPROBE_REENTER)
504 restore_previous_kprobe(kcb); 508 restore_previous_kprobe(kcb);
505 else 509 else {
506 reset_current_kprobe(); 510 reset_current_kprobe();
511 if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
512 local_irq_enable();
513 }
507 preempt_enable_no_resched(); 514 preempt_enable_no_resched();
508 break; 515 break;
509 case KPROBE_HIT_ACTIVE: 516 case KPROBE_HIT_ACTIVE: