Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp2047598rwb; Sun, 18 Sep 2022 21:05:55 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7E8S24wrYQyJqR0TCxSzWAgbr3wa/FEEnxBTYXA/Bmfg7xZyZ7z1utcFUjCJ3DXDYX0gBy X-Received: by 2002:a63:d0b:0:b0:439:72d7:ef81 with SMTP id c11-20020a630d0b000000b0043972d7ef81mr13933021pgl.605.1663560355071; Sun, 18 Sep 2022 21:05:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663560355; cv=none; d=google.com; s=arc-20160816; b=l102CPMrT56rbQ7c8/QI8gpGQklhKLV7tz5Lwyr22+cEN//ho7upT69SL+me/fuPl0 I515JpZjJgEi1rZzQO8Qwq2fGRJ4qJcsTuRbFQ5iVYh0PPiB9kSX1owD7hhLpbucOmT9 3Krq2pKXZf/eCP+m4q2JOCul1mGz5YBSzZcAQUvZl0QEqWTduEJlNSoXFcqurtkxVbSI DH5NMNnOPMyQhIVV0t/PpNB1STvm+Ilg+Fj0MCt3C16lI6sPQxRgq/msTeeP6DHXlNvo b3V3e5CI4td6Xnc740+njqF/VpovcY3Zr5wox2sNf7kVNl8DBG9LIyvIracM/WwnU5bM 4kcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=w7h1g4Lxm2DtqKwjHUGk15sDLdA1wz/pisgXWv8jiYs=; b=UsYpI0wgKR40HV7QLwf4AWNvf1PfZlMpS8KKDFYTI1U1yKCBP67O3YPC3E7iyZo1fH 2scbSHzd+N0xqd07Mm4LH9meFopSUXmYbSWc0ErqWVDsHkU1bvJ+bBqcXjJ0lPvWQmjF 6yJMunNhjncWPePynWNb6JWRTw36tu3EM0iylCY2XhUrD8iEAaMYa3kjwTLtHymeLhNe kpLxQVTM4FLERQpNbO+URNTXX1BUmVZEdGloC7yXgXeukIqEoYA8QNMGR2KSYPr8M9Et l1BuQ/5aeCiHf/fu9wvJxvIEDYwd4SFGnGwVQAqZBIPuO6ZduumHadPnuk+s/Ria7n3d saNw== 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b8-20020a056a000cc800b0052e677b7056si30919317pfv.279.2022.09.18.21.05.43; Sun, 18 Sep 2022 21:05:55 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229492AbiISDUC (ORCPT + 99 others); Sun, 18 Sep 2022 23:20:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229769AbiISDTm (ORCPT ); Sun, 18 Sep 2022 23:19:42 -0400 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6DEB513D04 for ; Sun, 18 Sep 2022 20:19:16 -0700 (PDT) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxYOKv3ydj8W4dAA--.46332S2; Mon, 19 Sep 2022 11:19:12 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jeff Xie , Jinyang He Subject: [PATCH v5 10/10] LoongArch/ftrace: Fix unwind state when option func_stack_trace Date: Mon, 19 Sep 2022 11:19:10 +0800 Message-Id: <20220919031910.15512-1-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: AQAAf8CxYOKv3ydj8W4dAA--.46332S2 X-Coremail-Antispam: 1UD129KBjvJXoWxWFyUtFWxKF4kGFWDXrW5Wrg_yoWrXFW8pF 95CF95Wr4Fgr92grnrXr1j9rn5Grnayr17KF9rJw1rCFnFqryfJrnYya4DZFs8J3ykGF1x X3ZYkrya9w4UJaUanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvK14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxV WxJr0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2Wl Yx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbV WUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7CjxVAaw2AF wI0_JF0_Jw1lc2xSY4AK67AK6r48MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r 1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CE b7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0x vE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF 0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxh VjvjDU0xZFpf9x0JU689_UUUUU= X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS, 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 Ftrace plays like function head exception, prologue analysis will stop soon because PC is at entry. 90000000004c5a54 : 90000000004c5a54: 03400000 andi $zero, $zero, 0x0 ==>move t0, ra 90000000004c5a58: 03400000 andi $zero, $zero, 0x0 ==>bl callsite ==>90000000004c5a5c: 02fcc063 addi.d $sp, $sp, -208(0xf30) ... When encountering ftrace_call, save trace function ra at PT_ERA, save parent ra at PT_R1, At this time, pc is the position after the two nops of callee. There is no conventional prologue operation between this position and the function entry, so we need to reset the first flag to make the caller continue to unwind. testing method: echo path_openat > ./set_ftrace_filter echo 1 > ./options/func_stack_trace echo function > ./current_tracer Reported-by: Jeff Xie Tested-by: Jinyang He Tested-by: Jeff Xie Signed-off-by: Qing Zhang --- arch/loongarch/include/asm/unwind.h | 2 +- arch/loongarch/kernel/unwind_prologue.c | 35 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h index f66b07c3e6a1..f2b52b9ea93d 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -20,7 +20,7 @@ struct unwind_state { char type; /* UNWINDER_XXX */ struct stack_info stack_info; struct task_struct *task; - bool first, error; + bool first, error, is_ftrace; int graph_idx; unsigned long sp, pc, ra; }; diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index f77f3b6f3f06..4fb4923b68cc 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -14,9 +14,7 @@ unsigned long unwind_get_return_address(struct unwind_state *state) if (unwind_done(state)) return 0; - else if (state->type) - return state->pc; - else if (state->first) + else if (state->type || state->first) return state->pc; return *(unsigned long *)(state->sp); @@ -42,16 +40,41 @@ static bool unwind_by_guess(struct unwind_state *state) return false; } +static inline void unwind_state_fixup(struct unwind_state *state) +{ +#ifdef CONFIG_FUNCTION_TRACER + static unsigned long ftrace_case = (unsigned long)ftrace_call + 4; + + if (state->pc == ftrace_case) + state->is_ftrace = true; +#endif +} + static bool unwind_by_prologue(struct unwind_state *state) { struct stack_info *info = &state->stack_info; union loongarch_instruction *ip, *ip_end; unsigned long frame_size = 0, frame_ra = -1; unsigned long size, offset, pc = state->pc; + struct pt_regs *regs; if (state->sp >= info->end || state->sp < info->begin) return false; + if (state->is_ftrace) { + /* + * As we meet ftrace_regs_entry, reset first flag like first doing + * tracing, Prologue analysis will stop soon because PC is at entry. + */ + regs = (struct pt_regs *)state->sp; + state->pc = regs->csr_era; + state->ra = regs->regs[1]; + state->sp = regs->regs[3]; + state->first = true; + state->is_ftrace = false; + return true; + } + if (!kallsyms_lookup_size_offset(pc, &size, &offset)) return false; @@ -97,7 +120,7 @@ static bool unwind_by_prologue(struct unwind_state *state) state->pc = *(unsigned long *)(state->sp + frame_ra); state->sp = state->sp + frame_size; - return !!__kernel_text_address(state->pc); + goto out; first: state->first = false; @@ -106,7 +129,9 @@ static bool unwind_by_prologue(struct unwind_state *state) state->pc = state->ra; - return !!__kernel_text_address(state->ra); +out: + unwind_state_fixup(state); + return !!__kernel_text_address(state->pc); } void unwind_start(struct unwind_state *state, struct task_struct *task, -- 2.36.1