diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-10-29 10:50:45 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-29 10:50:50 -0400 |
commit | 9ec2708053b647969bee862902872d44a5f9b439 (patch) | |
tree | a7ca43a31a656bac010fac46d11ff0fa23488ef1 /arch/s390 | |
parent | f2166bb117952404689f0dc42624ee0b54a66e5e (diff) |
[S390] fix kprobes single stepping
Fix kprobes after git commit 1e54622e0403891b10f2105663e0f9dd595a1f17
broke it. The kprobe_handler is now called with interrupts in the state
at the time of the breakpoint. The single step of the replaced instruction
is done with interrupts off which makes it necessary to enable and disable
the interupts in the kprobes code.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
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: |