aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/lib/sstep.c
diff options
context:
space:
mode:
authorTiejun Chen <tiejun.chen@windriver.com>2012-09-16 19:54:31 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-18 01:32:45 -0400
commit8e9f69371536981a2a8c9ee4a49dbe3aa4946df4 (patch)
tree8785a164fdaa422a146fdda4b21100189858f90d /arch/powerpc/lib/sstep.c
parenta9c4e541ea9b22944da356f2a9258b4eddcc953b (diff)
powerpc/kprobe: Don't emulate store when kprobe stwu r1
We don't do the real store operation for kprobing 'stwu Rx,(y)R1' since this may corrupt the exception frame, now we will do this operation safely in exception return code after migrate current exception frame below the kprobed function stack. So we only update gpr[1] here and trigger a thread flag to mask this. Note we should make sure if we trigger kernel stack over flow. Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/lib/sstep.c')
-rw-r--r--arch/powerpc/lib/sstep.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 9a52349874ee..e15c521846ca 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -566,7 +566,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
566 unsigned long int ea; 566 unsigned long int ea;
567 unsigned int cr, mb, me, sh; 567 unsigned int cr, mb, me, sh;
568 int err; 568 int err;
569 unsigned long old_ra; 569 unsigned long old_ra, val3;
570 long ival; 570 long ival;
571 571
572 opcode = instr >> 26; 572 opcode = instr >> 26;
@@ -1486,11 +1486,43 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1486 goto ldst_done; 1486 goto ldst_done;
1487 1487
1488 case 36: /* stw */ 1488 case 36: /* stw */
1489 case 37: /* stwu */
1490 val = regs->gpr[rd]; 1489 val = regs->gpr[rd];
1491 err = write_mem(val, dform_ea(instr, regs), 4, regs); 1490 err = write_mem(val, dform_ea(instr, regs), 4, regs);
1492 goto ldst_done; 1491 goto ldst_done;
1493 1492
1493 case 37: /* stwu */
1494 val = regs->gpr[rd];
1495 val3 = dform_ea(instr, regs);
1496 /*
1497 * For PPC32 we always use stwu to change stack point with r1. So
1498 * this emulated store may corrupt the exception frame, now we
1499 * have to provide the exception frame trampoline, which is pushed
1500 * below the kprobed function stack. So we only update gpr[1] but
1501 * don't emulate the real store operation. We will do real store
1502 * operation safely in exception return code by checking this flag.
1503 */
1504 if ((ra == 1) && !(regs->msr & MSR_PR) \
1505 && (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) {
1506 /*
1507 * Check if we will touch kernel sack overflow
1508 */
1509 if (val3 - STACK_INT_FRAME_SIZE <= current->thread.ksp_limit) {
1510 printk(KERN_CRIT "Can't kprobe this since Kernel stack overflow.\n");
1511 err = -EINVAL;
1512 break;
1513 }
1514
1515 /*
1516 * Check if we already set since that means we'll
1517 * lose the previous value.
1518 */
1519 WARN_ON(test_thread_flag(TIF_EMULATE_STACK_STORE));
1520 set_thread_flag(TIF_EMULATE_STACK_STORE);
1521 err = 0;
1522 } else
1523 err = write_mem(val, val3, 4, regs);
1524 goto ldst_done;
1525
1494 case 38: /* stb */ 1526 case 38: /* stb */
1495 case 39: /* stbu */ 1527 case 39: /* stbu */
1496 val = regs->gpr[rd]; 1528 val = regs->gpr[rd];