Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965523AbbEMPlw (ORCPT ); Wed, 13 May 2015 11:41:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34933 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964937AbbEMPlr (ORCPT ); Wed, 13 May 2015 11:41:47 -0400 Message-ID: <555370B9.2070203@redhat.com> Date: Wed, 13 May 2015 11:41:45 -0400 From: William Cohen User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Masami Hiramatsu , David Long , Will Deacon CC: "linux-arm-kernel@lists.infradead.org" , Russell King , "sandeepa.s.prabhu@gmail.com" , Steve Capper , Catalin Marinas , "Jon Medhurst (Tixy)" , Ananth N Mavinakayanahalli , Anil S Keshavamurthy , "davem@davemloft.net" , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH v6 0/6] arm64: Add kernel probes (kprobes) support References: <1429561187-3661-1-git-send-email-dave.long@linaro.org> <55363791.4070706@hitachi.com> <553AB222.50609@redhat.com> <553EF74D.8020706@redhat.com> <20150429102346.GK8236@arm.com> <55442BFA.50101@redhat.com> <554851CB.2010909@linaro.org> <20150505154830.GI1550@arm.com> <55519583.9020507@linaro.org> <5551F693.8050100@redhat.com> <555317E8.2000502@hitachi.com> In-Reply-To: <555317E8.2000502@hitachi.com> Content-Type: multipart/mixed; boundary="------------020606040707010302040602" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5975 Lines: 179 This is a multi-part message in MIME format. --------------020606040707010302040602 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 05/13/2015 05:22 AM, Masami Hiramatsu wrote: > On 2015/05/12 21:48, William Cohen wrote: >> Hi Dave, >> >> In some of the previous diagnostic output it looked like things would go wrong >> in the entry.S when the D bit was cleared and the debug interrupts were >> unmasksed. I wonder if some of the issue might be due to the starting the >> kprobe for the trampoline, but leaving things in an odd state when another >> set of krpobe/kretporbes are hit when the trampoline is running. > > Hmm, does this mean we have a trouble if a user kprobe handler calls the > function which is probed by other kprobe? Or, is this just a problem > only for kretprobes? Hi Masami, I wrote an example based off of sample/kprobes/kprobes_sample.c to force the reentry issue for kprobes (the attached kprobe_rentry_example.c). That seemed to run fine. I think the reason that the trampoline handler got into trouble is because of the reset_current_kprobe() before the possible call to kfree, but I haven't verified it. It seems like that should be at the end of trampoline handler just before the return. Other architectures have similar trampoline handlers, so I am surprised that the other architectures haven't encountered this issue with kretprobes. Maybe this is due to specific of arm64 exception handling. # modprobe kprobe_reentry_example [ 909.617295] Planted kprobe at fffffe00000b7b34 [ 909.623873] Planted kprobe at fffffe000032d34c # rmmod kprobe_reentry_example [ 1482.647504] kprobe at fffffe00000b7b34 unregistered [ 1482.687506] kprobe at fffffe000032d34c unregistered [ 1482.692361] y = 42 [ 1482.694361] z = 0 # grep \ int_sqrt$ /proc/kallsyms fffffe000032d34c T int_sqrt # grep \ do_fork$ /proc/kallsyms fffffe00000b7b34 T do_fork > >> As Dave >> mentioned the proposed trampoline patch avoids using a kprobe in the >> trampoline and directly calls the trampoline handler. Attached is the >> current version of the patch which was able to run the systemtap testsuite. >> Systemtap does exercise the kprobe/kretprobe infrastructure, but it would >> be good to have additional raw kprobe tests to check that kprobe reentry >> works as expected. > > Actually, Will's patch looks like the same thing what I did on x86, > as the kretprobe-booster. So I'm OK for that. But if the above problem > is not solved, we need to fix that, since kprobes can be used from > different sources. The patch should look similar to the x86 code. The x86 code was used as a model. -Will --------------020606040707010302040602 Content-Type: text/x-csrc; name="kprobe_reentry_example.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kprobe_reentry_example.c" /* * NOTE: This example is designed to check that the kprobe reentry work. * * For more information on theory of operation of kprobes, see * Documentation/kprobes.txt * */ #include #include #include /* For each probe you need to allocate a kprobe structure */ static struct kprobe kp = { .symbol_name = "do_fork", }; static struct kprobe kp_re = { .symbol_name = "int_sqrt", }; static unsigned long y=0; static unsigned long z=0; /* kprobe pre_handler: called just before the probed instruction is executed */ static int handler_pre(struct kprobe *p, struct pt_regs *regs) { /* call another function that is instrumented with a kprobe to ensure that reentry works */ unsigned long x=1764; y = int_sqrt(x); return 0; } /* kprobe post_handler: called after the probed instruction is executed */ static void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) { return; } /* kprobe pre_handler: called just before the probed instruction is executed */ static int handler_pre_re(struct kprobe *p, struct pt_regs *regs) { /* if reentry is working as expected this code may not be executed */ z = 0xdeadbeef; return 0; } /* kprobe post_handler: called after the probed instruction is executed */ static void handler_post_re(struct kprobe *p, struct pt_regs *regs, unsigned long flags) { return; } /* * fault_handler: this is called if an exception is generated for any * instruction within the pre- or post-handler, or when Kprobes * single-steps the probed instruction. */ static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) { printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr); /* Return 0 because we don't handle the fault. */ return 0; } static int __init kprobe_init(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; ret = register_kprobe(&kp); if (ret < 0) { printk(KERN_INFO "register_kprobe failed, returned %d\n", ret); return ret; } printk(KERN_INFO "Planted kprobe at %p\n", kp.addr); kp_re.pre_handler = handler_pre_re; kp_re.post_handler = handler_post_re; kp_re.fault_handler = handler_fault; ret = register_kprobe(&kp_re); if (ret < 0) { printk(KERN_INFO "register_kprobe failed, returned %d\n", ret); return ret; } printk(KERN_INFO "Planted kprobe at %p\n", kp_re.addr); return 0; } static void __exit kprobe_exit(void) { unregister_kprobe(&kp); printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr); unregister_kprobe(&kp_re); printk(KERN_INFO "kprobe at %p unregistered\n", kp_re.addr); printk(KERN_INFO "y = %ld\n", y); printk(KERN_INFO "z = %lx\n", z); } module_init(kprobe_init) module_exit(kprobe_exit) MODULE_LICENSE("GPL"); --------------020606040707010302040602-- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/