diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/entry.S | 1 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 1 | ||||
-rw-r--r-- | arch/s390/kernel/kprobes.c | 9 |
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 | # |
559 | kernel_per: | 559 | kernel_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 | # |
570 | kernel_per: | 570 | kernel_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 | ||
318 | ss_probe: | 318 | ss_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(); | ||
466 | out: | 470 | out: |
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: |