Received: by 2002:a05:6358:a55:b0:ec:fcf4:3ecf with SMTP id 21csp4403438rwb; Mon, 16 Jan 2023 23:49:38 -0800 (PST) X-Google-Smtp-Source: AMrXdXuAR1s/mhzsjkvIiBzc92YNI1bo/quoIgYyLohxh5f+ublSOdOg14D4IUPrfNTYZeJ5p+2T X-Received: by 2002:a17:903:2405:b0:194:5116:c3ee with SMTP id e5-20020a170903240500b001945116c3eemr3200666plo.37.1673941777877; Mon, 16 Jan 2023 23:49:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673941777; cv=none; d=google.com; s=arc-20160816; b=HlM+z+AJ5EIY/sh82Fxlz5J8zH76UnSG7lhNezSuWY4dfEye6W7MjuMBYyvJHuV2K8 +klFmnQl/e59em2dloZ/qonYoinoCwrUMPBhQhwJeDA2+u5wj8UXg/ds6nImq8rfb1ZD fjuqiYx8Z3qG/XAp6OaYzrhophnlaV7UD4srfNefZWr9C2rSclIMjZSJ4GIYyj+ASPBY fpbThDDF3XSHJTk1iR7BPkiy2NqEwAg5TsJHhJEmHn4ArEA0LG8pIHkNTIFDoetUjz5R rvhjBHywM0ORttkFwUopWhmRFZiqhsJNcbOwbZPy+BdfzsupY8A/vSeSdJ2AoAz+0RD+ MHmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=q83sDzr8m9dpwQN3JTADcVSqY1S2IsaPIUTv2j1y5Fo=; b=emn3GdPtQz/r3APLpanKAbgnlURwluvNLC0riQSLuQLiS1w7TnwlN5pmIAfcqjjfip ssRhl5LI5EPfUgHDJl48klfvIMQ5P+W0Hy0qfotd9V+KqSqqcG2FAGWBYIFb8vUVjvWa TDynVX7kE+Zdp0rJa7l8mWOImufRB07e0Gu2RD3yH7D6V+0mbhMEBmi+MjQErI9wtwKS DNgtHuxh6ZszDqJ2PwIoOmnKU44N6ot07GPdVhNNxlvoZoQg4e1tsAkUztlH6Y4HWbYN YNgB27crjaQhMX2jkNjxELXOo6zcmit4cT36oCpNKig+lG3+AweF9l+53Z4NQXSZIOwy U8jA== 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 m16-20020a63f610000000b00477fbd59895si32464676pgh.852.2023.01.16.23.49.31; Mon, 16 Jan 2023 23:49:37 -0800 (PST) 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 S235607AbjAQHsC (ORCPT + 49 others); Tue, 17 Jan 2023 02:48:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235869AbjAQHrZ (ORCPT ); Tue, 17 Jan 2023 02:47:25 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BE075244A4 for ; Mon, 16 Jan 2023 23:47:22 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Bxa+qJUsZjuQoCAA--.6161S3; Tue, 17 Jan 2023 15:47:21 +0800 (CST) Received: from [10.130.0.63] (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Cxf+SHUsZjJqMaAA--.15695S3; Tue, 17 Jan 2023 15:47:20 +0800 (CST) Subject: Re: [PATCH v3 5/5] LoongArch: Add generic ex-handler unwind in prologue unwinder To: Huacai Chen , Jinyang He Cc: WANG Xuerui , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Steven Rostedt , Masami Hiramatsu , Mark Rutland References: <20230112004048.26191-1-hejinyang@loongson.cn> From: Qing Zhang Message-ID: Date: Tue, 17 Jan 2023 15:47:19 +0800 User-Agent: Mozilla/5.0 (X11; Linux mips64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-CM-TRANSID: AQAAf8Cxf+SHUsZjJqMaAA--.15695S3 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxKrWrGryUAw1xAF1fZFy5Jwb_yoW3Gr1fpF 95CFn5GF48Kry2qryUXryDur95Aw1kCr17KF9rKa4rGFnFvryfWr1vy34v9FWDJrW8WryI vFn5Xr9I9a13ta7anT9S1TB71UUUUbDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bqkYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1q6r43M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IY64vIr41lc7I2V7IY0V AS07AlzVAYIcxG8wCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCF s4IE7xkEbVWUJVW8JwCFI7km07C267AKxVWUtVW8ZwC20s026c02F40E14v26r1j6r18MI 8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41l IxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIx AIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07jTq2NUUUUU= X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,NICE_REPLY_A, 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 On 2023/1/17 下午2:25, Huacai Chen wrote: > On Thu, Jan 12, 2023 at 8:41 AM Jinyang He wrote: >> >> When exception is triggered, code flow go handle_\exception in some >> cases. One of stackframe in this case as follows, >> >> high -> +-------+ >> | REGS | <- a pt_regs >> | | >> | | <- ex trigger >> | REGS | <- ex pt_regs <-+ >> | | | >> | | | >> low -> +-------+ ->unwind-+ >> >> When unwinder unwind to handler_\exception it cannot go on prologue >> analysis. It is asynchronous code flow, we should get the next frame >> PC from regs->csr_era but not from regs->regs[1]. And we copy the >> handler codes to eentry in the early time and copy the handler codes >> to NUMA-relative memory named pcpu_handlers if NUMA is enabled. Thus, >> unwinder cannot unwind normally. Therefore, try to give some hint in >> handler_\exception and fixup it in unwind_next_frame. >> >> Reported-by: Qing Zhang >> Signed-off-by: Jinyang He >> --- >> arch/loongarch/include/asm/unwind.h | 2 +- >> arch/loongarch/kernel/genex.S | 3 + >> arch/loongarch/kernel/unwind_prologue.c | 100 +++++++++++++++++++++--- >> arch/loongarch/mm/tlb.c | 2 +- >> 4 files changed, 92 insertions(+), 15 deletions(-) >> >> diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h >> index cb428e1b19af..a38eb152aefb 100644 >> --- a/arch/loongarch/include/asm/unwind.h >> +++ b/arch/loongarch/include/asm/unwind.h >> @@ -22,7 +22,7 @@ struct unwind_state { >> char type; /* UNWINDER_XXX */ >> struct stack_info stack_info; >> struct task_struct *task; >> - bool first, error, is_ftrace; >> + bool first, error, reset; > Hi, Qing, > Do you think is_reset is better than reset here? > >> int graph_idx; >> unsigned long sp, pc, ra; >> }; >> diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S >> index 75e5be807a0d..7e5c293ed89f 100644 >> --- a/arch/loongarch/kernel/genex.S >> +++ b/arch/loongarch/kernel/genex.S >> @@ -67,14 +67,17 @@ SYM_FUNC_END(except_vec_cex) >> .macro BUILD_HANDLER exception handler prep >> .align 5 >> SYM_FUNC_START(handle_\exception) >> + 666: >> BACKUP_T0T1 >> SAVE_ALL >> build_prep_\prep >> move a0, sp >> la.abs t0, do_\handler >> jirl ra, t0, 0 >> + 668: >> RESTORE_ALL_AND_RET > I think the 668 label should be after RESTORE_ALL_AND_RET, right? This means that the value of ra after do_\handler is called, the 668 label should come after jirl. Thanks -Qing > > Huacai > >> SYM_FUNC_END(handle_\exception) >> + SYM_DATA(unwind_hint_\exception, .word 668b - 666b) >> .endm >> >> BUILD_HANDLER ade ade badv >> diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c >> index e6c3f2ee507c..e52c18c2b604 100644 >> --- a/arch/loongarch/kernel/unwind_prologue.c >> +++ b/arch/loongarch/kernel/unwind_prologue.c >> @@ -2,21 +2,100 @@ >> /* >> * Copyright (C) 2022 Loongson Technology Corporation Limited >> */ >> +#include >> #include >> #include >> >> #include >> +#include >> #include >> +#include >> #include >> >> -static inline void unwind_state_fixup(struct unwind_state *state) >> +extern const int unwind_hint_ade; >> +extern const int unwind_hint_ale; >> +extern const int unwind_hint_bp; >> +extern const int unwind_hint_fpe; >> +extern const int unwind_hint_fpu; >> +extern const int unwind_hint_lsx; >> +extern const int unwind_hint_lasx; >> +extern const int unwind_hint_lbt; >> +extern const int unwind_hint_ri; >> +extern const int unwind_hint_watch; >> +extern unsigned long eentry; >> +#ifdef CONFIG_NUMA >> +extern unsigned long pcpu_handlers[NR_CPUS]; >> +#endif >> + >> +static inline bool scan_handler(unsigned long entry_offset) >> { >> -#ifdef CONFIG_DYNAMIC_FTRACE >> - static unsigned long ftrace = (unsigned long)ftrace_call + 4; >> + int idx, offset; >> >> - if (state->pc == ftrace) >> - state->is_ftrace = true; >> + if (entry_offset >= EXCCODE_INT_START * VECSIZE) >> + return false; >> + >> + idx = entry_offset / VECSIZE; >> + offset = entry_offset % VECSIZE; >> + switch (idx) { >> + case EXCCODE_ADE: >> + return offset == unwind_hint_ade; >> + case EXCCODE_ALE: >> + return offset == unwind_hint_ale; >> + case EXCCODE_BP: >> + return offset == unwind_hint_bp; >> + case EXCCODE_FPE: >> + return offset == unwind_hint_fpe; >> + case EXCCODE_FPDIS: >> + return offset == unwind_hint_fpu; >> + case EXCCODE_LSXDIS: >> + return offset == unwind_hint_lsx; >> + case EXCCODE_LASXDIS: >> + return offset == unwind_hint_lasx; >> + case EXCCODE_BTDIS: >> + return offset == unwind_hint_lbt; >> + case EXCCODE_INE: >> + return offset == unwind_hint_ri; >> + case EXCCODE_WATCH: >> + return offset == unwind_hint_watch; >> + default: >> + return false; >> + } >> +} >> + >> +static inline bool fix_exceptions(unsigned long pc) >> +{ >> +#ifdef CONFIG_NUMA >> + int cpu; >> + >> + for_each_possible_cpu(cpu) { >> + if (!pcpu_handlers[cpu]) >> + continue; >> + if (scan_handler(pc - pcpu_handlers[cpu])) >> + return true; >> + } >> #endif >> + return scan_handler(pc - eentry); >> +} >> + >> +/* >> + * As we meet ftrace_regs_entry, reset first flag like first doing >> + * tracing. Prologue analysis will stop soon because PC is at entry. >> + */ >> +static inline bool fix_ftrace(unsigned long pc) >> +{ >> +#ifdef CONFIG_DYNAMIC_FTRACE >> + return pc == (unsigned long)ftrace_call + LOONGARCH_INSN_SIZE; >> +#else >> + return false; >> +#endif >> +} >> + >> +static inline bool unwind_state_fixup(struct unwind_state *state) >> +{ >> + if (!fix_exceptions(state->pc) && !fix_ftrace(state->pc)) >> + return false; >> + state->reset = true; >> + return true; >> } >> >> /* >> @@ -39,14 +118,10 @@ static bool unwind_by_prologue(struct unwind_state *state) >> 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. >> - */ >> + if (state->reset) { >> regs = (struct pt_regs *)state->sp; >> state->first = true; >> - state->is_ftrace = false; >> + state->reset = false; >> state->pc = regs->csr_era; >> state->ra = regs->regs[1]; >> state->sp = regs->regs[3]; >> @@ -111,8 +186,7 @@ static bool unwind_by_prologue(struct unwind_state *state) >> >> out: >> state->first = false; >> - unwind_state_fixup(state); >> - return !!__kernel_text_address(state->pc); >> + return unwind_state_fixup(state) || __kernel_text_address(state->pc); >> } >> >> static bool next_frame(struct unwind_state *state) >> diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c >> index da3681f131c8..8bad6b0cff59 100644 >> --- a/arch/loongarch/mm/tlb.c >> +++ b/arch/loongarch/mm/tlb.c >> @@ -251,7 +251,7 @@ static void output_pgtable_bits_defines(void) >> } >> >> #ifdef CONFIG_NUMA >> -static unsigned long pcpu_handlers[NR_CPUS]; >> +unsigned long pcpu_handlers[NR_CPUS]; >> #endif >> extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; >> >> -- >> 2.34.3 >> >>