From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44BCBC433E0 for ; Sat, 27 Feb 2021 10:51:45 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F096F64EAF for ; Sat, 27 Feb 2021 10:51:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F096F64EAF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ZwnlX2yMpTPZdHBc5gbRnT7h7o2e0toH0iVQfZzloDo=; b=D8LsaiH7TGn9LynGzondjY06z IMARaCGUQ6kzZlAu1GDlbNLgqP9zKwLzoX/W4NaRQZCFRcB3sGDsIIx1Gq4m94WmFowYHfbmoCgJv N4w/xdaNAHL+KY1cQxQkcuUVAFFBW+5Ak0R5Av1RenZV20faYJc2IWuMtwayVrPSYffBVYTjQtfT1 PG6Dzqc/pjOcPNYSgE1CO4SCIHarE3CHJvt7BER38LY1hfpRvRZml+Ei4+00hKEtZrJ3maPcMBUz6 2WidUatJF3J3x1whxKsJVdJsY65s4YQfyvGtSJIBCI7UJhs0WpWVkQN0m/ANDqIn8wColulnQ3eMa ZewNw97Qw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1lFxB7-0006hk-HK; Sat, 27 Feb 2021 10:50:29 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1lFxB1-0006gN-Rf for linux-arm-kernel@lists.infradead.org; Sat, 27 Feb 2021 10:50:25 +0000 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4Dnjsz3vy0zMfLt; Sat, 27 Feb 2021 18:48:07 +0800 (CST) Received: from DESKTOP-E0KHRBE.china.huawei.com (10.67.103.82) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.498.0; Sat, 27 Feb 2021 18:50:04 +0800 From: Shaobo Huang To: Subject: Re: [PATCH 4.4.y] arm: kprobes: Allow to handle reentered kprobe on single-stepping Date: Sat, 27 Feb 2021 18:50:04 +0800 Message-ID: <20210227105004.14876-1-huangshaobo6@huawei.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20210227091701.23944-1-huangshaobo6@huawei.com> References: <20210227091701.23944-1-huangshaobo6@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.103.82] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210227_055024_492892_6B65EC31 X-CRM114-Status: GOOD ( 22.86 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tixy@linaro.org, young.liuyang@huawei.com, linux@arm.linux.org.uk, liucheng32@huawei.com, gregkh@linuxfoundation.org, xiaoqian9@huawei.com, linux-kernel@vger.kernel.org, zengweilin@huawei.com, mhiramat@kernel.org, kepler.chenxin@huawei.com, chenzefeng2@huawei.com, nixiaoming@huawei.com, linux-arm-kernel@lists.infradead.org Content-Type: multipart/mixed; boundary="===============5337100022881259389==" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org --===============5337100022881259389== Content-Transfer-Encoding: 8bit Content-Type: text/plain > > From: Masami Hiramatsu > > commit f3fbd7ec62dec1528fb8044034e2885f2b257941 upstream > > This is arm port of commit 6a5022a56ac3 ("kprobes/x86: Allow to > handle reentered kprobe on single-stepping") > > Since the FIQ handlers can interrupt in the single stepping > (or preparing the single stepping, do_debug etc.), we should > consider a kprobe is hit in the NMI handler. Even in that > case, the kprobe is allowed to be reentered as same as the > kprobes hit in kprobe handlers > (KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE). > > The real issue will happen when a kprobe hit while another > reentered kprobe is processing (KPROBE_REENTER), because > we already consumed a saved-area for the previous kprobe. > > Signed-off-by: Masami Hiramatsu > Signed-off-by: Jon Medhurst > Fixes: 24ba613c9d6c ("ARM kprobes: core code") > Cc: stable@vger.kernel.org #v2.6.25~v4.11 > Signed-off-by: huangshaobo arm32 jprobe does not handle interrupt reentry correctly. When jprobe is running in singlestep, jprobe is triggered again in system interrupt, it will run to the BUG function to cause panic. jprobe needs to enter the kprobe_handler function twice, the first time to enter kprobe_handler to save the context environment; the second time to enter kprobe_handler to simulate the replaced instruction and restore the context environment of the probed function.But the system interrupt is not closed when the kprobe_handler is entered for the second time in jprobe_return. the code of jprobe_return is as follows: void __kprobes jprobe_return(void) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); __asm__ __volatile__ ( /* * Setup an empty pt_regs. Fill SP and PC fields as * they're needed by longjmp_break_handler. * * We allocate some slack between the original SP and start of * our fabricated regs. To be precise we want to have worst case * covered which is STMFD with all 16 regs so we allocate 2 * * sizeof(struct_pt_regs)). * * This is to prevent any simulated instruction from writing * over the regs when they are accessing the stack. */ #ifdef CONFIG_THUMB2_KERNEL ... #else "sub sp, %0, %1 \n\t" #endif "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t" "str %0, [sp, %2] \n\t" "str r0, [sp, %3] \n\t" "mov r0, sp \n\t" "bl kprobe_handler \n\t" /* * Return to the context saved by setjmp_pre_handler * and restored by longjmp_break_handler. */ #ifdef CONFIG_THUMB2_KERNEL ... #else "ldr r0, [sp, %4] \n\t" "msr cpsr_cxsf, r0 \n\t" "ldmia sp, {r0 - pc} \n\t" #endif : : "r" (kcb->jprobe_saved_regs.ARM_sp), "I" (sizeof(struct pt_regs) * 2), "J" (offsetof(struct pt_regs, ARM_sp)), "J" (offsetof(struct pt_regs, ARM_pc)), "J" (offsetof(struct pt_regs, ARM_cpsr)), "J" (offsetof(struct pt_regs, ARM_lr)) : "memory", "cc"); } If the execution reaches the singlestep, the jprobe status is KPROBE_HIT_SS. If an interrupt is generated at this time, and jprobe is triggered again in the interrupt, jprobe reentry will be generated, at this time kcb->kprobe_status==KPROBE_HIT_SS, Enter the default branch to execute the BUG function, causing the system to panic. The partial code of kprobe_handler is as follows: void __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p, *cur; struct kprobe_ctlblk *kcb; kcb = get_kprobe_ctlblk(); cur = kprobe_running(); #ifdef CONFIG_THUMB2_KERNEL /* * First look for a probe which was registered using an address with * bit 0 set, this is the usual situation for pointers to Thumb code. * If not found, fallback to looking for one with bit 0 clear. */ p = get_kprobe((kprobe_opcode_t *)(regs->ARM_pc | 1)); if (!p) p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); #else /* ! CONFIG_THUMB2_KERNEL */ p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); #endif if (p) { if (cur) { /* Kprobe is pending, so we're recursing. */ switch (kcb->kprobe_status) { case KPROBE_HIT_ACTIVE: case KPROBE_HIT_SSDONE: /* A pre- or post-handler probe got us here. */ kprobes_inc_nmissed_count(p); save_previous_kprobe(kcb); set_current_kprobe(p); kcb->kprobe_status = KPROBE_REENTER; singlestep(p, regs, kcb); restore_previous_kprobe(kcb); break; default: /* impossible cases */ BUG(); …… } At this time, it is necessary to increase the processing of the KPROBE_HIT_SS state, that is, jprobe only executes the simulation instruction, and does not execute the user callback function. For example, use jprobe to register arm_dma_map_page, arm_dma_map_page will be called by gmac_recv in the interrupt, the system will panic, and the log is as follows: kernel BUG at arch/arm/probes/kprobes/core.c:296! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM Modules linked in:…… CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.4.236 #15 Hardware name: Hisilicon A15 task: c0a25220 task.stack: c0a00000 PC is at kprobe_handler+0x120/0x288 LR is at kprobe_handler+0x120/0x288 pc : [] lr : [] psr: 600f0193 sp : c0a01b08 ip : 00000007 fp : c0602088 r10: eeb1a26c r9 : 2e2b1000 r8 : c0a32530 r7 : c0a01be8 r6 : c086926c r5 : bf4c3000 r4 : c0869268 r3 : c0a2244c r2 : 00000000 r1 : 00000104 r0 : 00000032 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 30c5387d Table: 2c1dfd00 DAC: 55555555 Process swapper/0 (pid: 0, stack limit = 0xc0a00210) Stack: (0xc0a01b08 to 0xc0a02000) …… [] (kprobe_handler) from [] (kprobe_trap_handler+0x24/0x48) [] (kprobe_trap_handler) from [] (do_undefinstr+0x1a8/0x234) [] (do_undefinstr) from [] (__und_svc_finish+0x0/0x30) Exception stack(0xc0a01be8 to 0xc0a01c30) 1be0: ed8523f8 ef1cdc20 00000540 00000080 eaac8540 00000080 1c00: c02159ec c0a265e0 00000002 00000000 bf3f9000 c0602088 0002b4c8 c0a01c78 1c20: bf3e4b38 c02159ec a00f0113 ffffffff [] (__und_svc_finish) from [] (arm_dma_map_page+0x0/0xe4) [] (arm_dma_map_page) from [] (kprobe_handler+0x250/0x288) [] (kprobe_handler) from [] (gmac_recv+0xc0/0x858 [Drv_Gmac_K]) [] (gmac_recv [Drv_Gmac_K]) from [] (net_rx_action+0x130/0x3d4) [] (net_rx_action) from [] (__do_softirq+0x1b0/0x418) [] (__do_softirq) from [] (irq_exit+0xc0/0x188) [] (irq_exit) from [] (msa_irq_exit+0x130/0x220) [] (msa_irq_exit) from [] (__handle_domain_irq+0xec/0x1b4) [] (__handle_domain_irq) from [] (gic_handle_irq+0xcc/0x104) [] (gic_handle_irq) from [] (__irq_svc+0x40/0x58) Exception stack(0xc0a01e78 to 0xc0a01ec0) 1e60: 00000000 c0a32530 1e80: 2e2b1000 c0869268 c0a72500 00000000 e9a7f4a8 c0a25220 c0591b08 00000040 1ea0: c0a22a34 c0a01f34 00000000 c0a01ec8 c02c08e0 c044a498 200f0013 ffffffff [] (__irq_svc) from [] (debug_smp_processor_id+0x0/0x14) [] (debug_smp_processor_id) from [] (kprobe_busy_begin+0x38/0x6c) [] (kprobe_busy_begin) from [] (kprobe_flush_task+0x38/0x120) [] (kprobe_flush_task) from [] (finish_task_switch+0x19c/0x2a4) [] (finish_task_switch) from [] (__schedule+0x5a4/0x6b4) [] (__schedule) from [] (schedule+0x98/0xc4) [] (schedule) from [] (schedule_preempt_disabled+0x14/0x20) [] (schedule_preempt_disabled) from [] (cpu_startup_entry+0x3c/0x33c) [] (cpu_startup_entry) from [] (rest_init+0xac/0xf0) [] (rest_init) from [] (start_kernel+0x484/0x534) Code: e59f016c ebf57071 e1a00005 ebf49e8a (e7f001f2) --===============5337100022881259389== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel --===============5337100022881259389==--