Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751469AbbEMFOg (ORCPT ); Wed, 13 May 2015 01:14:36 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:11382 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750787AbbEMFOe (ORCPT ); Wed, 13 May 2015 01:14:34 -0400 X-AuditID: cbfee68f-f793b6d000005f66-a7-5552ddb7b96d Date: Wed, 13 May 2015 05:14:31 +0000 (GMT) From: Vaneet Narang Subject: Re: [EDT] [PATCH 1/1] Fix: hw watchpoint continually triggers callback To: Will Deacon Cc: Maninder Singh , "linux@arm.linux.org.uk" , "linux-kernel@vger.kernel.org" , Amit Arora , AJEET YADAV , AKHILESH KUMAR , "linux-arm-kernel@lists.infradead.org" Reply-to: v.narang@samsung.com MIME-version: 1.0 X-MTR: 20150513043343867@v.narang Msgkey: 20150513043343867@v.narang X-EPLocale: en_US.windows-1252 X-Priority: 3 X-EPWebmail-Msg-Type: personal X-EPWebmail-Reply-Demand: 0 X-EPApproval-Locale: X-EPHeader: ML X-MLAttribute: X-RootMTR: 20150513043343867@v.narang X-ParentMTR: X-ArchiveUser: X-CPGSPASS: N X-ConfirmMail: N,general Content-type: text/plain; charset=windows-1252 MIME-version: 1.0 Message-id: <1680595986.99931431494070231.JavaMail.weblogic@ep2mlwas08c> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrOIsWRmVeSWpSXmKPExsWyRsSkSnf73aBQg6WnZC0u75rD5sDo8XmT XABjFJdNSmpOZllqkb5dAldG/8KzrAUf7Cq2T5nK2sA4x7aLkZNDSEBZovPaNVYQW0LARGLW tBNsELaYxIV764FsLqCapYwST/f2MMEUzezbxwiRmMMocW7HX7AOFgFViQfr7zKD2GwC2hJv /vWygNjCAv4SZ788AouLCKhLNNwHsbk4mAU+MUlsbLvECnGGnMTfBb/AingFBCVOznzCArFN UeLyhqPsEHElibmtF6CukJNYMvUylM0rMaP9KQtMfNrXNcwQtrTE+VkbGGHeWfz9MVScX+LY 7R1QvQISU88chKpRkzh0/gqUzSexZuFbFpj6XaeWM8Psur9lLlSvhMTWlidg9zMD3Tml+yE7 hG0gcWTRHFZ0v/AKeEis2HOBFeR5CYFeDoldhxYzT2BUmoWkbhaSWbOQzEJWs4CRZRWjaGpB ckFxUnqRsV5xYm5xaV66XnJ+7iZGYHo4/e9Z/w7GuwesDzEKcDAq8fAqbAgKFWJNLCuuzD3E aAqMqInMUqLJ+cAklFcSb2hsZmRhamJqbGRuaaYkzrtQ6mewkEB6YklqdmpqQWpRfFFpTmrx IUYmDk6pBsYVLG5RK85Xc13wYfDtei+5JukCo+LMGl+exskPPooURAlaH5sm7xsUxvGxXXjp D6Vix/Ptzmf9XwTWbrq8dV6aknLUi7gbDBtO/FkxuUj9jbrgslM2ZnyqddyfWY69NJt0c/WV iUu0391Y9mLb42lX47vmH0k0+q5fGza9WKfvQ4G2uVSmpZYSS3FGoqEWc1FxIgAv85FTCgMA AA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrBKsWRmVeSWpSXmKPExsVy+t/tPt3td4NCDR7PELa4vGsOmwOjx+dN cgGMUWk2GamJKalFCql5yfkpmXnptkrewfHO8aZmBoa6hpYW5koKeYm5qbZKLj4Bum6ZOUBD lRTKEnNKgUIBicXFSvp2NkX5pSWpChn5xSW2StGG5kZ6RgZ6pkZ6hqaxVoYGBkamQDUJaRn9 C8+yFnywq9g+ZSprA+Mc2y5GTg4hAWWJzmvXWEFsCQETiZl9+xghbDGJC/fWs3UxcgHVzGGU OLfjLxtIgkVAVeLB+rvMIDabgLbEm3+9LCC2sIC/xNkvj8DiIgLqEg33QWwuDmaBT0wSG9su sUJsk5P4u+AXWBGvgKDEyZlPWCC2KUpc3nCUHSKuJDG39QITRFxOYsnUy1A2r8SM9qcsMPFp X9cwQ9jSEudnbYC7evH3x1Bxfoljt3dA9QpITD1zEKpGTeLQ+StQNp/EmoVvWWDqd51azgyz 6/6WuVC9EhJbW56A3c8MdOeU7ofsELaBxJFFc1jR/cIr4CGxYs8F1gmMsrOQpGYhaZ+FpB1Z zQJGllWMoqkFyQXFSekVRnrFibnFpXnpesn5uZsYwano2aIdjP/OWx9iFOBgVOLhVdgQFCrE mlhWXJl7iFGCg1lJhPfSbaAQb0piZVVqUX58UWlOavEhRlNgtE1klhJNzgemybySeENjE3NT Y1MLA0NzczMlcd7/53JDhATSE0tSs1NTC1KLYPqYODilGhjPlCW+8tknfMrguXnadZlP2ezH bnxbl/Ryy/lfbNVPH+S4zl6upRByZHXowdCAQKEzC8V/u2T/Myzt+ftyr8gr+TfHVxkY8Mzr 8XNibrvI/K+Me0uQAovej6nHFh0KKjG/+/+/x6u5f3SfcnM/Xcs6pb+uu6J4aoZvy5Ttaq7e CqINhQw56i+UWIozEg21mIuKEwGrl7hLWwMAAA== DLP-Filter: Pass X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by nfs id t4D5EhLw023279 Content-Length: 5922 Lines: 116 EP-2DAD0AFA905A4ACB804C4F82A001242F >On Tue, May 12, 2015 at 02:12:54PM +0100, Vaneet Narang wrote: >> On Tue, May 12, 2015 at 12:48:13PM +0100, Maninder Singh wrote: >> >> On ARM, when a watchpoint is registered using register_wide_hw_breakpoint, >> >> the callback handler endlessly runs until the watchpoint is unregistered. >> >> The reason for this issue is debug interrupts gets raised before >> >> executing the instruction, and after interrupt handling ARM tries to >> >> execute the same instruction again , which results in interrupt getting >> >> raised again. >> >> >> >> This patch fixes this issue by using KPROBES (getting the instruction >> >> executed and incrementing PC to next instruction). >> >> >> >> Signed-off-by: Vaneet Narang >> >> Signed-off-by: Maninder Singh >> >> Reviewed-by: Amit Arora >> >> Reviewed-by: Ajeet Yadav >> >> --- >> >> arch/arm/kernel/hw_breakpoint.c | 18 ++++++++++++++++++ >> >> 1 files changed, 18 insertions(+), 0 deletions(-) >> >> >> >> diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c >> >> index dc7d0a9..ec72f86 100644 >> >> --- a/arch/arm/kernel/hw_breakpoint.c >> >> +++ b/arch/arm/kernel/hw_breakpoint.c >> >> @@ -37,6 +37,9 @@ >> >> #include >> >> #include >> >> #include >> >> +#ifdef CONFIG_KPROBES >> >> +#include >> >> +#endif >> >> >> >> /* Breakpoint currently in use for each BRP. */ >> >> static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); >> >> @@ -757,6 +760,21 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, >> >> */ >> >> if (!wp->overflow_handler) >> >> enable_single_step(wp, instruction_pointer(regs)); >> >> +#ifdef CONFIG_KPROBES >> >> + else { >> >> + struct kprobe kp; >> >> + unsigned long flags; >> >> + >> >> + arch_uninstall_hw_breakpoint(wp); >> >> + kp.addr = (kprobe_opcode_t *)instruction_pointer(regs); >> >> + if (!arch_prepare_kprobe(&kp)) { >> >> + local_irq_save(flags); >> >> + kp.ainsn.insn_singlestep(&kp, regs); >> >> + local_irq_restore(flags); >> >> + } >> >> + arch_install_hw_breakpoint(wp); >> >> + } >> >> +#endif >> >> >I don't think this is the right thing to do at all; the kernel already >> >handles step exceptions using mismatched breakpoints when there is no >> >overflow handler specified (e.g. using perf mem events). If you register a >> >handler (e.g. gdb via ptrace) then you have to handle the step yourself. >> >> This fix is given for kernel developers who wants to use perf interface by >> registering callback using register_wide_hw_breakpoint API. On every >> callback trigger they have to unregister watchpoints otherwise callback >> gets called in a loop and now issue is "when to register watch point back >> ?". >If you want to solve this, I think we need a better way to expose software >single-step/emulation to the overflow handler. If we try to do this in >the hw_breakpoint code itself, we run into problems: > - What if another thread hits the same instruction whilst we are trying > to step it? > - What if there are two breakpoints or a breakpoint + watchpoint > triggered by the same instruction? Thanks for you input. I am not sure, issues which you have mentioned with this implementation will actually come. To address the issues you have raised, I need to brief about kprobe. Kprobe follows 3 steps for breakpoint (BP) handling. 1. Decode BP instruction. 2. Replace BP instruction with new instruction that will generate SWI. 3. Execute instruction & move PC to next instruction. Kprobe follows step 1 & step 2 on addition of BP and 3rd step is followed when SWI gets triggered. For this fix we have used step 1 & step 3, we have skipped step 2. As we don't know the caller of watch point & also HW generates interrupt so step 2 is not required. The only difference is since we don't know the caller we can't decode instruction in advance. We have to follow step 1 and step 3 when HWI gets triggered. Since we are not replacing instruction from memory and I assume kprobe implementation for execution of instruction in interrupt context is tested and stable, so it shouldn't produce any of the above race condition issues. > - What if the debugger didn't want to execute the instruction at all? if debugger doesn't want to execute instruction then debugger should use single step implementation without overflow handler. and even with current implementation there is no such control available but still if debugger don't want to execute this instruction, it can just move PC to next instruction. >> With this issue in place, it makes perf interface unusable. We didn't >> faced this issue with x86. >This is a good point. If perf/hw_breakpoint are supposed to hide the >Internal details of the debug architecture and make everything look and >smell like x86, I'd like to see that documented somewhere. I don't think >we'd generally be able to achieve that whilst solving the caveats I mention >above, so we'd probably just end up removing this feature altogether, which >would be a shame (and I don't think possible as it stands, since >hw_breakpoint doesn't know about its caller). >Will The issue which I can see with this fix is kprobe doesn't follow step 1 in interrupt context but we are decoding instruction interrupt context. While decoding instruction kprobe allocates instruction slot with mutex protection which is not recommended for interrupt context. This can be fixed if we allocate instruction slot per CPU during initialization and will use same slot while execution. Thanks Vaneet Narang????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?