Thread (10 messages) 10 messages, 5 authors, 2011-10-14

Re: [PATCH] MIPS Kprobes: Support branch instructions probing

From: Maneesh Soni <hidden>
Date: 2011-10-14 17:28:35
Also in: lkml

On Thu, Oct 13, 2011 at 10:28:51AM -0700, David Daney wrote:
On 10/13/2011 02:07 AM, Maneesh Soni wrote:
quoted
From: Maneesh Soni<redacted>

This patch provides support for kprobes on branch instructions. The branch
instruction at the probed address is actually emulated and not executed
out-of-line like other normal instructions. Instead the delay-slot instruction
is copied and single stepped out of line.

At the time of probe hit, the original branch instruction is evaluated
and the target cp0_epc is computed similar to compute_retrun_epc(). It
is also checked if the delay slot instruction can be skipped, which is
true if there is a NOP in delay slot or branch is taken in case of
branch likely instructions. Once the delay slot instruction is single
stepped the normal execution resume with the cp0_epc updated the earlier
computed cp0_epc as per the branch instructions.
I haven't tested it but...

quoted
Signed-off-by: Maneesh Soni<redacted>
---
 arch/mips/include/asm/kprobes.h |    7 +
 arch/mips/kernel/kprobes.c      |  341 +++++++++++++++++++++++++++++++++++----
 2 files changed, 320 insertions(+), 28 deletions(-)
[...]
quoted
+static int evaluate_branch_instruction(struct kprobe *p, struct pt_regs *regs,
+					struct kprobe_ctlblk *kcb)
 {
+	union mips_instruction insn = p->opcode;
+	unsigned int dspcontrol;
+	long epc;
+
+	epc = regs->cp0_epc;
+	if (epc&  3)
+		goto unaligned;
+
+	if (p->ainsn.insn->word == 0)
+		kcb->flags |= SKIP_DELAYSLOT;
+	else
+		kcb->flags&= ~SKIP_DELAYSLOT;
+
+	switch (insn.i_format.opcode) {
+	/*
+	 * jr and jalr are in r_format format.
+	 */
+	case spec_op:
[...]
quoted
+	case bgtzl_op:
+		/* rt field assumed to be zero */
+		if ((long)regs->regs[insn.i_format.rs]>  0) {
+			epc = epc + 4 + (insn.i_format.simmediate<<  2);
+			kcb->flags |= SKIP_DELAYSLOT;
+		} else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;


Where is the handling for:

	case cop1_op:

#ifdef CONFIG_CPU_CAVIUM_OCTEON
	case lwc2_op: /* This is bbit0 on Octeon */
	case ldc2_op: /* This is bbit032 on Octeon */
	case swc2_op: /* This is bbit1 on Octeon */
	case sdc2_op: /* This is bbit132 on Octeon */
#endif

These are all defined in insn_has_delayslot() but not here.
My bad.. will include them as well. Actually as Ralf suggested,
will keep this as common code.

Thanks
Maneesh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help