From: "Abhishek Sagar" <sagar.abhishek@gmail.com>
To: "Masami Hiramatsu" <mhiramat@redhat.com>
Cc: "Harvey Harrison" <harvey.harrison@gmail.com>,
"Ingo Molnar" <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>,
LKML <linux-kernel@vger.kernel.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
qbarnes@gmail.com, ananth@in.ibm.com, jkenisto@us.ibm.com
Subject: Re: [PATCH] x86: kprobes change kprobe_handler flow
Date: Wed, 2 Jan 2008 01:54:04 +0530 [thread overview]
Message-ID: <863e9df20801011224g8a3111dg1b09ce6726759d97@mail.gmail.com> (raw)
In-Reply-To: <477A7D1F.8020703@redhat.com>
On 1/1/08, Masami Hiramatsu <mhiramat@redhat.com> wrote:
> Could you separate changing logic from cleanup and explain
> why the logic should be changed?
The major portion of logical changes is re-routing of code flow by
removing gotos. Hopefully all the cases have been covered. There are a
couple of changes that I'd like to address (see below).
> > +static __always_inline void setup_singlestep(struct kprobe *p,
> > + struct pt_regs *regs,
> > + struct kprobe_ctlblk *kcb)
> > +{
> > +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM)
> > + if (p->ainsn.boostable == 1 && !p->post_handler) {
> > + /* Boost up -- we can execute copied instructions directly */
> > + reset_current_kprobe();
> > + regs->eip = (unsigned long)p->ainsn.insn;
> > + preempt_enable_no_resched();
> > + } else {
> > + prepare_singlestep(p, regs);
> > + kcb->kprobe_status = KPROBE_HIT_SS;
> > + }
> > +#else
> > + prepare_singlestep(p, regs);
> > + kcb->kprobe_status = KPROBE_HIT_SS;
>
> please avoid code duplication.
I've addressed it in the latest patch.
> > static int __kprobes kprobe_handler(struct pt_regs *regs)
> > {
> > - struct kprobe *p;
> > int ret = 0;
> > kprobe_opcode_t *addr;
> > + struct kprobe *p, *cur;
> > struct kprobe_ctlblk *kcb;
> >
> > addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
> > + if (*addr != BREAKPOINT_INSTRUCTION) {
> > + /*
> > + * The breakpoint instruction was removed right
> > + * after we hit it. Another cpu has removed
> > + * either a probepoint or a debugger breakpoint
> > + * at this address. In either case, no further
> > + * handling of this interrupt is appropriate.
> > + * Back up over the (now missing) int3 and run
> > + * the original instruction.
> > + */
> > + regs->eip -= sizeof(kprobe_opcode_t);
> > + return 1;
> > + }
I have moved the above breakpoint removal check at the beginning of
the function. The current check is for '!p' case only, whereas IMO
this check should be performed for all cases. An external debugger may
very well plant and remove a breakpoint on an address which has probe
on it. This check is a race nevertheless, so its relative placing
within kprobe_handler() would be best where its duplication can be
avoided.
> >
> > - /* Check we're not actually recursing */
> > - if (kprobe_running()) {
> > - p = get_kprobe(addr);
> > - if (p) {
> > - if (kcb->kprobe_status == KPROBE_HIT_SS &&
> > - *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
> > - regs->eflags &= ~TF_MASK;
> > - regs->eflags |= kcb->kprobe_saved_eflags;
> > - goto no_kprobe;
> > - }
> > - /* We have reentered the kprobe_handler(), since
> > - * another probe was hit while within the handler.
> > - * We here save the original kprobes variables and
> > - * just single step on the instruction of the new probe
> > - * without calling any user handlers.
> > - */
> > - save_previous_kprobe(kcb);
> > - set_current_kprobe(p, regs, kcb);
> > - kprobes_inc_nmissed_count(p);
> > - prepare_singlestep(p, regs);
> > - kcb->kprobe_status = KPROBE_REENTER;
> > - return 1;
> > - } else {
> > - if (*addr != BREAKPOINT_INSTRUCTION) {
> > - /* The breakpoint instruction was removed by
> > - * another cpu right after we hit, no further
> > - * handling of this interrupt is appropriate
> > - */
> > - regs->eip -= sizeof(kprobe_opcode_t);
> > + if (p) {
> > + if (cur) {
> > + switch (kcb->kprobe_status) {
> > + case KPROBE_HIT_ACTIVE:
> > + case KPROBE_HIT_SSDONE:
> > + /* a probe has been hit inside a
> > + * user handler */
> > + save_previous_kprobe(kcb);
> > + set_current_kprobe(p, regs, kcb);
> > + kprobes_inc_nmissed_count(p);
> > + prepare_singlestep(p, regs);
> > + kcb->kprobe_status = KPROBE_REENTER;
> > ret = 1;
> > - goto no_kprobe;
> > - }
> > - p = __get_cpu_var(current_kprobe);
> > - if (p->break_handler && p->break_handler(p, regs)) {
> > - goto ss_probe;
> > + break;
> > + case KPROBE_HIT_SS:
> > + if (*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
> > + regs->eflags &= ~TF_MASK;
> > + regs->eflags |=
> > + kcb->kprobe_saved_eflags;
> > + } else {
> > + /* BUG? */
> > + }
> > + break;
> > + default:
> > + /* impossible cases */
> > + BUG();
> > }
> > - }
Replaced deeply nested if-elses with a switch.
Please let me know if there are any changes on which you would like
further clarification.
> --
> Masami Hiramatsu
>
> Software Engineer
> Hitachi Computer Products (America) Inc.
> Software Solutions Division
>
> e-mail: mhiramat@redhat.com, masami.hiramatsu.pt@hitachi.com
--
Thanks,
Abhishek Sagar
next prev parent reply other threads:[~2008-01-01 20:24 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-28 1:44 Harvey Harrison
2007-12-31 13:03 ` Abhishek Sagar
2008-01-01 15:35 ` Ingo Molnar
2008-01-01 19:40 ` Abhishek Sagar
2008-01-01 20:19 ` Harvey Harrison
2008-01-01 20:54 ` Abhishek Sagar
2008-01-02 18:09 ` Masami Hiramatsu
2008-01-02 19:31 ` Abhishek Sagar
2008-01-02 20:23 ` Ingo Molnar
2008-01-02 21:56 ` Masami Hiramatsu
2008-01-03 17:15 ` Masami Hiramatsu
2008-01-03 21:31 ` Masami Hiramatsu
2008-01-04 6:34 ` Abhishek Sagar
2008-01-03 18:12 ` Abhishek Sagar
2008-01-03 20:11 ` Masami Hiramatsu
2008-01-04 6:43 ` Abhishek Sagar
2008-01-01 17:49 ` Masami Hiramatsu
2008-01-01 20:24 ` Abhishek Sagar [this message]
2008-01-02 16:00 ` Masami Hiramatsu
2007-12-28 2:08 Harvey Harrison
2007-12-30 8:07 ` Masami Hiramatsu
2007-12-30 13:47 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=863e9df20801011224g8a3111dg1b09ce6726759d97@mail.gmail.com \
--to=sagar.abhishek@gmail.com \
--cc=ananth@in.ibm.com \
--cc=harvey.harrison@gmail.com \
--cc=hpa@zytor.com \
--cc=jkenisto@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@redhat.com \
--cc=mingo@elte.hu \
--cc=qbarnes@gmail.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®