From patchwork Tue Oct 18 12:43:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Li Huafei X-Patchwork-Id: 4154 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1941762wrs; Tue, 18 Oct 2022 05:52:06 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4e+3IRwzkS2K8kTo4KF/QuN7326GivIQX39OyZuxej+Z4ECErMlI0kdiD3mBFHjVzEwXnW X-Received: by 2002:a17:907:16a7:b0:78d:f5d4:a74e with SMTP id hc39-20020a17090716a700b0078df5d4a74emr2277465ejc.9.1666097526317; Tue, 18 Oct 2022 05:52:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666097526; cv=none; d=google.com; s=arc-20160816; b=0Dv6zHWU0uf3/d6pzyDcXlnBKuE5iBqy/s2i2FowemPoXaM1Sbzod8nm1M4zQPCmKy K4sSNsP93W4DOWMR+O0hBD87qEkjPa+t2zcpQO2i11aipJMNrAyWb1nH9V67x2vjeABF aGFoSfksSLY86ME4ShW2ax5eoS2yL5eJZeggjQzIyU4/7KrLWl7my8nIAQ6m0dkfYS/n xkN4d46iLQR3KU+O9LJjH6I989FEWk8ugNFnV9GgY7nYC6vCiu34ZlYOFqwD8i2ZqFR+ VkNQ5MLz3cuD6RTDogOfgOLpkPNt7RvUWoRe5MXGKDw/8MisrYteztMd3w85OzIKlBuZ TV3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=YUC5LM2VxtwUJ0vyXY4q51Hk3AV5BtV65tIocSt0M4c=; b=FIoVTmmdcHWp6/6ai/3wTuh3REQAzIwJyezmya8vpTuTvYISY+NmiHDl0soZRjkMub Wd3HZhx7RmL/xQ+QUxX6oPR9Koh1a9ha78d+0CZbViccFXy5vpMmCuYY8ny9s/l56/hm qrsd380GFJ8mnc2s2QQeTc+kve+JFHf8w/+jCRXcomGUlww40OAgEmPOTgxpUQ0tG/2r CxeUe1VDtllYy+Yr2WtdmxfA5Dfy2aHU3jArgA2YCp8jA193QfyMIweIGUiJWHaZ5uYC CSishE8IyrjlFdCN1G/xNuleylkXsPLs0aCoa4DVMYi1iRa49FH7urMVYfq/ewJbNCu5 WAWA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l15-20020a170906794f00b007882926848bsi12390832ejo.818.2022.10.18.05.51.40; Tue, 18 Oct 2022 05:52:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230173AbiJRMrV (ORCPT + 99 others); Tue, 18 Oct 2022 08:47:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230177AbiJRMrR (ORCPT ); Tue, 18 Oct 2022 08:47:17 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3ACA6BA923; Tue, 18 Oct 2022 05:47:10 -0700 (PDT) Received: from dggemv703-chm.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4MsD5r1dvKzmVCP; Tue, 18 Oct 2022 20:42:24 +0800 (CST) Received: from kwepemm600010.china.huawei.com (7.193.23.86) by dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 18 Oct 2022 20:47:06 +0800 Received: from ubuntu1804.huawei.com (10.67.174.174) by kwepemm600010.china.huawei.com (7.193.23.86) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 18 Oct 2022 20:47:05 +0800 From: Li Huafei To: , CC: , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH v4 2/2] ARM: stacktrace: Convert stacktrace to generic ARCH_STACKWALK Date: Tue, 18 Oct 2022 20:43:39 +0800 Message-ID: <20221018124339.115793-3-lihuafei1@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221018124339.115793-1-lihuafei1@huawei.com> References: <20221018124339.115793-1-lihuafei1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.174.174] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemm600010.china.huawei.com (7.193.23.86) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747029880038237091?= X-GMAIL-MSGID: =?utf-8?q?1747029880038237091?= Historically architectures have had duplicated code in their stack trace implementations for filtering what gets traced. In order to avoid this duplication some generic code has been provided using a new interface arch_stack_walk(), enabled by selecting ARCH_STACKWALK in Kconfig, which factors all this out into the generic stack trace code. Convert ARM to use this common infrastructure. When initializing the stack frame of the current task, arm64 uses __builtin_frame_address(1) to initialize the frame pointer, skipping arch_stack_walk(), see the commit c607ab4f916d ("arm64: stacktrace: don't trace arch_stack_walk()"). Since __builtin_frame_address(1) does not work on ARM, unwind_frame() is used to unwind the stack one layer forward before calling walk_stackframe(). Signed-off-by: Li Huafei Reviewed-by: Linus Walleij --- arch/arm/Kconfig | 1 + arch/arm/kernel/stacktrace.c | 114 ++++++++++------------------------- 2 files changed, 33 insertions(+), 82 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a08c9d092a33..16920f2215f2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -17,6 +17,7 @@ config ARM select ARCH_HAS_PTE_SPECIAL if ARM_LPAE select ARCH_HAS_SETUP_DMA_OPS select ARCH_HAS_SET_MEMORY + select ARCH_STACKWALK select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL select ARCH_HAS_STRICT_MODULE_RWX if MMU select ARCH_HAS_SYNC_DMA_FOR_DEVICE diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index d05968bc7812..620aa82e3bdd 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -142,40 +142,32 @@ void notrace walk_stackframe(struct stackframe *frame, EXPORT_SYMBOL(walk_stackframe); #ifdef CONFIG_STACKTRACE -struct stack_trace_data { - struct stack_trace *trace; - unsigned int no_sched_functions; - unsigned int skip; -}; - -static bool save_trace(void *d, unsigned long addr) +static void start_stack_trace(struct stackframe *frame, struct task_struct *task, + unsigned long fp, unsigned long sp, + unsigned long lr, unsigned long pc) { - struct stack_trace_data *data = d; - struct stack_trace *trace = data->trace; - - if (data->no_sched_functions && in_sched_functions(addr)) - return true; - if (data->skip) { - data->skip--; - return true; - } - - trace->entries[trace->nr_entries++] = addr; - return trace->nr_entries < trace->max_entries; + frame->fp = fp; + frame->sp = sp; + frame->lr = lr; + frame->pc = pc; +#ifdef CONFIG_KRETPROBES + frame->kr_cur = NULL; + frame->tsk = task; +#endif +#ifdef CONFIG_UNWINDER_FRAME_POINTER + frame->ex_frame = in_entry_text(frame->pc); +#endif } -/* This must be noinline to so that our skip calculation works correctly */ -static noinline void __save_stack_trace(struct task_struct *tsk, - struct stack_trace *trace, unsigned int nosched) +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, + struct task_struct *task, struct pt_regs *regs) { - struct stack_trace_data data; struct stackframe frame; - data.trace = trace; - data.skip = trace->skip; - data.no_sched_functions = nosched; - - if (tsk != current) { + if (regs) { + start_stack_trace(&frame, NULL, regs->ARM_fp, regs->ARM_sp, + regs->ARM_lr, regs->ARM_pc); + } else if (task != current) { #ifdef CONFIG_SMP /* * What guarantees do we have here that 'tsk' is not @@ -184,64 +176,22 @@ static noinline void __save_stack_trace(struct task_struct *tsk, */ return; #else - frame.fp = thread_saved_fp(tsk); - frame.sp = thread_saved_sp(tsk); - frame.lr = 0; /* recovered from the stack */ - frame.pc = thread_saved_pc(tsk); + start_stack_trace(&frame, task, thread_saved_fp(task), + thread_saved_sp(task), 0, + thread_saved_pc(task)); #endif } else { - /* We don't want this function nor the caller */ - data.skip += 2; - frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; - frame.lr = (unsigned long)__builtin_return_address(0); here: - frame.pc = (unsigned long)&&here; + start_stack_trace(&frame, task, + (unsigned long)__builtin_frame_address(0), + current_stack_pointer, + (unsigned long)__builtin_return_address(0), + (unsigned long)&&here); + /* skip this function */ + if (unwind_frame(&frame)) + return; } -#ifdef CONFIG_KRETPROBES - frame.kr_cur = NULL; - frame.tsk = tsk; -#endif -#ifdef CONFIG_UNWINDER_FRAME_POINTER - frame.ex_frame = false; -#endif - walk_stackframe(&frame, save_trace, &data); -} - -void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) -{ - struct stack_trace_data data; - struct stackframe frame; - - data.trace = trace; - data.skip = trace->skip; - data.no_sched_functions = 0; - - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; -#ifdef CONFIG_KRETPROBES - frame.kr_cur = NULL; - frame.tsk = current; -#endif -#ifdef CONFIG_UNWINDER_FRAME_POINTER - frame.ex_frame = in_entry_text(frame.pc); -#endif - - walk_stackframe(&frame, save_trace, &data); -} - -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) -{ - __save_stack_trace(tsk, trace, 1); -} -EXPORT_SYMBOL(save_stack_trace_tsk); - -void save_stack_trace(struct stack_trace *trace) -{ - __save_stack_trace(current, trace, 0); + walk_stackframe(&frame, consume_entry, cookie); } -EXPORT_SYMBOL_GPL(save_stack_trace); #endif