aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-29 10:50:45 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-29 10:50:50 -0400
commit9ec2708053b647969bee862902872d44a5f9b439 (patch)
treea7ca43a31a656bac010fac46d11ff0fa23488ef1 /arch/s390
parentf2166bb117952404689f0dc42624ee0b54a66e5e (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.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: