diff options
-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 5efce72..1ecc337 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -557,6 +557,7 @@ pgm_svcper: # per was called from kernel, must be kprobes # kernel_per: + REENABLE_IRQS mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check mvi SP_SVCNR+1(%r15),0xff 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 a2be239..8f3e802 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -568,6 +568,7 @@ pgm_svcper: # per was called from kernel, must be kprobes # kernel_per: + REENABLE_IRQS xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_single_step diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 2a3d2bf..d60fc43 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) return 1; ss_probe: + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_disable(); prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1; @@ -463,6 +465,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) goto out; } reset_current_kprobe(); + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_enable(); out: preempt_enable_no_resched(); @@ -502,8 +506,11 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) regs->psw.mask |= kcb->kprobe_saved_imask; if (kcb->kprobe_status == KPROBE_REENTER) restore_previous_kprobe(kcb); - else + else { reset_current_kprobe(); + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_enable(); + } preempt_enable_no_resched(); break; case KPROBE_HIT_ACTIVE: |