From patchwork Mon Mar 15 16:57:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140093 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 904CEC433E0 for ; Mon, 15 Mar 2021 17:00:34 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 332FE64D9D for ; Mon, 15 Mar 2021 17:00:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 332FE64D9D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=q9Ufyi+cRGP0LGk+i1ixlFvELTU4tbECE1Cu5zjqPuc=; b=R/SGs8TwU4jqKOoF0dT/SO3AU 1dfkibudjFiU/e/enaI+jxJNK/SYsLN5JPSeet/KlOrfO+JmbcXR6d3H+gRt8Q/eRtnNrpngV/u1b G+A63tqDVyo3/QgzKkQgOZ1uhYdYxv0Q0/b5XmZIOoSlY2241S4BXqGB34AhyxSrxLEZpQTnmpCZD XqbmSOFwXKDsZnWsaBTQwwe1M5wqmNaj3KZyR5S6b6arvOQrVoSgNdXxM3l7rHryMy6s9npgifEXm z2x9jtoxoYH7WMNHuzZMHOmnEfU6ZPtNvJz/ySiH+yNq3P6P13hIFkRpmdjWWrxkH7C536QKY1FkI sY+flou1w==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqYO-00GPun-Ts; Mon, 15 Mar 2021 16:58:53 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXm-00GPn7-Ox for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:17 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 5F1FE20B26F3; Mon, 15 Mar 2021 09:58:11 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5F1FE20B26F3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827492; bh=igOSjDRkpU/MUXtVWxKHwm0pSTVl31mBseRDsjPu/Gg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cL7Rj7O+LK/CGWZQFwUQgPXIsAeH7PHuH6bV2e4xsfOmcEQaB4eiA+7kmCdppZ2Px CVV4wEMZDQmdZoVdSPmRXnwXRyykAausL2E5bkXJCWlYWyW4cOlTXZ2q9LUL6f5+8u RzI6aRQD7v+3B4go8wwoGxnTZnveDVIPsxRNztLM= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 1/8] arm64: Implement stack trace termination record Date: Mon, 15 Mar 2021 11:57:53 -0500 Message-Id: <20210315165800.5948-2-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165815_291179_C237AC2A X-CRM114-Status: GOOD ( 19.57 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" The unwinder needs to be able to reliably tell when it has reached the end of a stack trace. One way to do this is to have the last stack frame at a fixed offset from the base of the task stack. When the unwinder reaches that offset, it knows it is done. Kernel Tasks ============ All tasks except the idle task have a pt_regs structure right after the task stack. This is called the task pt_regs. The pt_regs structure has a special stackframe field. Make this stackframe field the last frame in the task stack. This needs to be done in copy_thread() which initializes a new task's pt_regs and initial CPU context. For the idle task, there is no task pt_regs. For our purpose, we need one. So, create a pt_regs just like other kernel tasks and make pt_regs->stackframe the last frame in the idle task stack. This needs to be done at two places: - On the primary CPU, the boot task runs. It calls start_kernel() and eventually becomes the idle task for the primary CPU. Just before start_kernel() is called, set up the last frame. - On each secondary CPU, a startup task runs that calls secondary_startup_kernel() and eventually becomes the idle task on the secondary CPU. Just before secondary_start_kernel() is called, set up the last frame. User Tasks ========== User tasks are initially set up like kernel tasks when they are created. Then, they return to userland after fork via ret_from_fork(). After that, they enter the kernel only on an EL0 exception. (In arm64, system calls are also EL0 exceptions). The EL0 exception handler stores state in the task pt_regs and calls different functions based on the type of exception. The stack trace for an EL0 exception must end at the task pt_regs. So, make task pt_regs->stackframe as the last frame in the EL0 exception stack. In summary, task pt_regs->stackframe is where a successful stack trace ends. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/entry.S | 8 +++++--- arch/arm64/kernel/head.S | 28 ++++++++++++++++++++++++---- arch/arm64/kernel/process.c | 5 +++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index a31a0a713c85..e2dc2e998934 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -261,16 +261,18 @@ alternative_else_nop_endif stp lr, x21, [sp, #S_LR] /* - * For exceptions from EL0, terminate the callchain here. + * For exceptions from EL0, terminate the callchain here at + * task_pt_regs(current)->stackframe. + * * For exceptions from EL1, create a synthetic frame record so the * interrupted code shows up in the backtrace. */ .if \el == 0 - mov x29, xzr + stp xzr, xzr, [sp, #S_STACKFRAME] .else stp x29, x22, [sp, #S_STACKFRAME] - add x29, sp, #S_STACKFRAME .endif + add x29, sp, #S_STACKFRAME #ifdef CONFIG_ARM64_SW_TTBR0_PAN alternative_if_not ARM64_HAS_PAN diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 66b0e0b66e31..2769b20934d4 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -393,6 +393,28 @@ SYM_FUNC_START_LOCAL(__create_page_tables) ret x28 SYM_FUNC_END(__create_page_tables) + /* + * The boot task becomes the idle task for the primary CPU. The + * CPU startup task on each secondary CPU becomes the idle task + * for the secondary CPU. + * + * The idle task does not require pt_regs. But create a dummy + * pt_regs so that task_pt_regs(idle_task)->stackframe can be + * set up to be the last frame on the idle task stack just like + * all the other kernel tasks. This helps the unwinder to + * terminate the stack trace at a well-known stack offset. + * + * Also, set up the last return PC to be ret_from_fork() just + * like all the other kernel tasks so that the stack trace of + * all kernel tasks ends with the same function. + */ + .macro setup_last_frame + sub sp, sp, #PT_REGS_SIZE + stp xzr, xzr, [sp, #S_STACKFRAME] + add x29, sp, #S_STACKFRAME + ldr x30, =ret_from_fork + .endm + /* * The following fragment of code is executed with the MMU enabled. * @@ -447,8 +469,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) #endif bl switch_to_vhe // Prefer VHE if possible add sp, sp, #16 - mov x29, #0 - mov x30, #0 + setup_last_frame b start_kernel SYM_FUNC_END(__primary_switched) @@ -606,8 +627,7 @@ SYM_FUNC_START_LOCAL(__secondary_switched) cbz x2, __secondary_too_slow msr sp_el0, x2 scs_load x2, x3 - mov x29, #0 - mov x30, #0 + setup_last_frame #ifdef CONFIG_ARM64_PTR_AUTH ptrauth_keys_init_cpu x2, x3, x4, x5 diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 325c83b1a24d..7ffa689e8b60 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -437,6 +437,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, } p->thread.cpu_context.pc = (unsigned long)ret_from_fork; p->thread.cpu_context.sp = (unsigned long)childregs; + /* + * For the benefit of the unwinder, set up childregs->stackframe + * as the last frame for the new task. + */ + p->thread.cpu_context.fp = (unsigned long)childregs->stackframe; ptrace_hw_copy_thread(p); From patchwork Mon Mar 15 16:57:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140095 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 B6284C433DB for ; Mon, 15 Mar 2021 17:00:49 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 426D164D9A for ; Mon, 15 Mar 2021 17:00:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 426D164D9A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=U2tNj0DEPkapmkCrtzTZWoz1CXrFtZWBjNdWUMUAtow=; b=Dk0FvZ9cZL/ZQcO8zwR9MfCQh YhLpQhCu2RUKnEEbEhFxM0UfXitCD5LDAzWqgwQY6y6nH+SDEpW7NyIwd3xC3CEzG8njbZ0Qb8WYI Aa3+AC6Plz7LXWBNLApL6spBCCFoC6UcLa9V2hOicmS8UOZvvJpyTkNJC9gJ+8qLK7sdp8F8Wa5FG q5bPVv7YCBDbeVTxC7RfzXyIG80bvqHH3jF/epoPYc7H366XYOrqix0qLHNtGEpSTe5j1ipUDqYFd HXsHbOUDZ0krU0HPK1JE6VMc16q6KBSUxYU+ga4BNJhUE8V/wEzk6VRvqFtTrfMkJXva8j6C6MEJL 769fTeraw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqYa-00GPx9-R3; Mon, 15 Mar 2021 16:59:05 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXn-00GPn9-HU for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:18 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 3630820B26F8; Mon, 15 Mar 2021 09:58:12 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3630820B26F8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827492; bh=qE4wUVCottpC6OUoMey65bhVUQHyQSW6OJCRVnCqmyI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=qcShqILZn2RFuMEzBnNQGUxawP+n3KpVRU9ekjmACp8JPyBl8O8aQ7ZZtjbGYhNW0 QmVVU62xg5Rej96hxmbhhfPIaKLbFu6N6hZn/kv6oUUBkfhNIj/gBI3nvXnKifPc30 ahGTTi4/g5aC9aKlei+peesBEW7rzgY4Hlb4hbt8= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 2/8] arm64: Implement frame types Date: Mon, 15 Mar 2021 11:57:54 -0500 Message-Id: <20210315165800.5948-3-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165816_143880_485B9CA0 X-CRM114-Status: GOOD ( 18.92 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" Apart from the task pt_regs, pt_regs is also created on the stack for other other cases: - EL1 exception. A pt_regs is created on the stack to save register state. In addition, pt_regs->stackframe is set up for the interrupted kernel function so that the function shows up in the EL1 exception stack trace. - When a traced function calls the ftrace infrastructure at the beginning of the function, ftrace creates a pt_regs on the stack at that point to save register state. In addition, it sets up pt_regs->stackframe for the traced function so that the traced function shows up in the stack trace taken from anywhere in the ftrace code after that point. When the ftrace code returns to the traced function, the pt_regs is removed from the stack. To summarize, pt_regs->stackframe is used (or will be used) as a marker frame in stack traces. To enable the unwinder to detect these frames, tag each pt_regs->stackframe with a type. To record the type, use the unused2 field in struct pt_regs and rename it to frame_type. The types are: TASK_FRAME Terminating frame for a normal stack trace. EL0_FRAME Terminating frame for an EL0 exception. EL1_FRAME EL1 exception frame. FTRACE_FRAME FTRACE frame. These frame types will be used by the unwinder later to validate frames. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/include/asm/ptrace.h | 15 +++++++++++++-- arch/arm64/kernel/asm-offsets.c | 1 + arch/arm64/kernel/entry.S | 4 ++++ arch/arm64/kernel/head.S | 2 ++ arch/arm64/kernel/process.c | 1 + 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index e58bca832dff..a75211ce009a 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -117,6 +117,17 @@ */ #define NO_SYSCALL (-1) +/* + * pt_regs->stackframe is a marker frame that is used in different + * situations. These are the different types of frames. Use patterns + * for the frame types instead of (0, 1, 2, 3, ..) so that it is less + * likely to find them on the stack. + */ +#define TASK_FRAME 0xDEADBEE0 /* Task stack termination frame */ +#define EL0_FRAME 0xDEADBEE1 /* EL0 exception frame */ +#define EL1_FRAME 0xDEADBEE2 /* EL1 exception frame */ +#define FTRACE_FRAME 0xDEADBEE3 /* FTrace frame */ + #ifndef __ASSEMBLY__ #include #include @@ -187,11 +198,11 @@ struct pt_regs { }; u64 orig_x0; #ifdef __AARCH64EB__ - u32 unused2; + u32 frame_type; s32 syscallno; #else s32 syscallno; - u32 unused2; + u32 frame_type; #endif u64 sdei_ttbr1; /* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */ diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index a36e2fc330d4..43f97dbc7dfc 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -75,6 +75,7 @@ int main(void) DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); + DEFINE(S_FRAME_TYPE, offsetof(struct pt_regs, frame_type)); DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); BLANK(); #ifdef CONFIG_COMPAT diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index e2dc2e998934..ecc3507d9cdd 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -269,8 +269,12 @@ alternative_else_nop_endif */ .if \el == 0 stp xzr, xzr, [sp, #S_STACKFRAME] + ldr w17, =EL0_FRAME + str w17, [sp, #S_FRAME_TYPE] .else stp x29, x22, [sp, #S_STACKFRAME] + ldr w17, =EL1_FRAME + str w17, [sp, #S_FRAME_TYPE] .endif add x29, sp, #S_STACKFRAME diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 2769b20934d4..d2ee78f8f97f 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -410,6 +410,8 @@ SYM_FUNC_END(__create_page_tables) */ .macro setup_last_frame sub sp, sp, #PT_REGS_SIZE + ldr w17, =TASK_FRAME + str w17, [sp, #S_FRAME_TYPE] stp xzr, xzr, [sp, #S_STACKFRAME] add x29, sp, #S_STACKFRAME ldr x30, =ret_from_fork diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 7ffa689e8b60..5c152fd60503 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -442,6 +442,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, * as the last frame for the new task. */ p->thread.cpu_context.fp = (unsigned long)childregs->stackframe; + childregs->frame_type = TASK_FRAME; ptrace_hw_copy_thread(p); From patchwork Mon Mar 15 16:57:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140097 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,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 EAEF7C433DB for ; Mon, 15 Mar 2021 17:00:54 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 995DA64DC4 for ; Mon, 15 Mar 2021 17:00:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 995DA64DC4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=EB3TaxRrbmi0lY4UlfaUF70U65nQ/DWonN6Jv3MDYDw=; b=IEkDwIcx1ZGMC/VgQUoh08E22 /J+XzkCADg9kHs2ceH29cRl0nUsz7cuZUZcuzzSg+Li7buyF6ztGICNq+9aHTosi5j5YM85p7Mm1n S8Peenl8XyZHdoNVkSPJGK4jaidvE3aok3xIxbHgZ3KsS11zDhHx3cjpd3Qzt4crxg6sqE/B8jyIT 9Qidcf6vrf6GxmhTV88kO/eE2CqPy9IMH1DTYDEFLbDqAdC6bWLlAftiVaSj4mIYi6cPVYA5lIMf3 qjBOS4vK3fDAXWvY5yQdoQ4z2v/vyVMFPFeRp17Ue++dMe9iAwLtSgvp3XVfjZHoWPv4+AZ5GWXR1 O5RNCNMig==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqYi-00GPzK-Ba; Mon, 15 Mar 2021 16:59:12 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXo-00GPnS-2h for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:18 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 0D28B20B26FA; Mon, 15 Mar 2021 09:58:12 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 0D28B20B26FA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827493; bh=0gTjptmyQZ07PiZCSnD/YKcvyyL392ig4rm2FEjYn/Y=; h=From:To:Subject:Date:In-Reply-To:References:From; b=R91XTzYfYCb0ZGw7P5w4k2c0wPMwNZx0Cb+QOzipMegJEzUGor2RF4EgdBmkFiCl2 myKycQk1amy6owG1HVBpw2L8EDnrxOhlsmEcvGJNMcxBmYgdrTzwMJWJ4ZHWh8xB4g +vEDShINtXTKrHlAz0KkHIh8BpePpQG/nsUveU70= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 3/8] arm64: Terminate the stack trace at TASK_FRAME and EL0_FRAME Date: Mon, 15 Mar 2021 11:57:55 -0500 Message-Id: <20210315165800.5948-4-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165816_314072_EF667302 X-CRM114-Status: GOOD ( 11.06 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" Implement the following checks in the unwinder to detect the terminating frame reliably: - The frame must end in task_pt_regs(task)->stackframe. - The frame type must be either TASK_FRAME or EL0_FRAME. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/stacktrace.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index ad20981dfda4..504cd161339d 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -43,16 +43,22 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) { unsigned long fp = frame->fp; struct stack_info info; + struct pt_regs *regs; - /* Terminal record; nothing to unwind */ - if (!fp) - return -ENOENT; + if (!tsk) + tsk = current; + regs = task_pt_regs(tsk); - if (fp & 0xf) + /* Terminal record, nothing to unwind */ + if (fp == (unsigned long) regs->stackframe) { + if (regs->frame_type == TASK_FRAME || + regs->frame_type == EL0_FRAME) + return -ENOENT; return -EINVAL; + } - if (!tsk) - tsk = current; + if (!fp || fp & 0xf) + return -EINVAL; if (!on_accessible_stack(tsk, fp, &info)) return -EINVAL; From patchwork Mon Mar 15 16:57:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140089 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 5A81BC433E0 for ; Mon, 15 Mar 2021 17:00:22 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 D98BB64D9D for ; Mon, 15 Mar 2021 17:00:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D98BB64D9D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=3fynzt+gvtuzWbxRtoU2ccRLq4rKkRBIhktZsM9Shug=; b=oWfX3kcmDM1S0/wHgpG6JkwMH E7Vvkv5rbab8o+48v3KCm9QcT/BAHmlIJfJHo88m4uVFrWzmDsjWt2s+Z7C7isBDrISunvJJFi+0g yogyF6yWMNa6nsp5p4ptKrgCkvtjEvFWppK7TNL5vyNnNk1uxmQzficfo/QVpJVI2lPhSdwt/6O+T rnAiWuMmXjn9oCrlW0h89/kYpRJxOFVdDXZBH9YO4wOtb1L3D6sKWTUpB0u1pIWhMp5WxazH3A2/Z 7Bnjcs1BVJuuBGeHq1HTgML/gQWmr5126Zw/LwUvsONvArL+sHW0rgxpoZenBxxVij2b38weyCoNz hZqWVC/Sg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXv-00GPqf-50; Mon, 15 Mar 2021 16:58:28 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXn-00GPnU-5E for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:17 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id D836E20B26FB; Mon, 15 Mar 2021 09:58:13 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D836E20B26FB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827494; bh=W6ZISsydraSfmBUaXZNZybizasn9n7l3dqdjWeTYpVk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cWlQpsTTPGAf6UKT9Dc4VnlDB8pEVFGxPTAOmNjt8A2GFyUZ4PG5FTB7X1JJVDaG+ rWlmv16kWUtpD37wEVcrbBXKi6z2DOg7bdRJrbJyhWpRVbqZnj4XvzyE8qA8OOvcFm gciSTE831gidSSlkGJ5YQ7SvGPMllIY4f83HYNA4= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 4/8] arm64: Detect an EL1 exception frame and mark a stack trace unreliable Date: Mon, 15 Mar 2021 11:57:56 -0500 Message-Id: <20210315165800.5948-5-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165815_596395_C25D25FD X-CRM114-Status: GOOD ( 25.40 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" EL1 exceptions can happen on any instruction including instructions in the frame pointer prolog or epilog. Depending on where exactly they happen, they could render the stack trace unreliable. If an EL1 exception frame is found on the stack, mark the stack trace as unreliable. Now, the EL1 exception frame is not at any well-known offset on the stack. It can be anywhere on the stack. In order to properly detect an EL1 exception frame the following checks must be done: - The frame type must be EL1_FRAME. - When the register state is saved in the EL1 pt_regs, the frame pointer x29 is saved in pt_regs->regs[29] and the return PC is saved in pt_regs->pc. These must match with the current frame. Interrupts encountered in kernel code are also EL1 exceptions. At the end of an interrupt, the interrupt handler checks if the current task must be preempted for any reason. If so, it calls the preemption code which takes the task off the CPU. A stack trace taken on the task after the preemption will show the EL1 frame and will be considered unreliable. This is correct behavior as preemption can happen practically at any point in code including the frame pointer prolog and epilog. Breakpoints encountered in kernel code are also EL1 exceptions. The probing infrastructure uses breakpoints for executing probe code. While in the probe code, the stack trace will show an EL1 frame and will be considered unreliable. This is also correct behavior. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/include/asm/stacktrace.h | 2 + arch/arm64/kernel/stacktrace.c | 57 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index eb29b1fe8255..684f65808394 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -59,6 +59,7 @@ struct stackframe { #ifdef CONFIG_FUNCTION_GRAPH_TRACER int graph; #endif + bool reliable; }; extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame); @@ -169,6 +170,7 @@ static inline void start_backtrace(struct stackframe *frame, bitmap_zero(frame->stacks_done, __NR_STACK_TYPES); frame->prev_fp = 0; frame->prev_type = STACK_TYPE_UNKNOWN; + frame->reliable = true; } #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 504cd161339d..6ae103326f7b 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -18,6 +18,58 @@ #include #include +static void check_if_reliable(unsigned long fp, struct stackframe *frame, + struct stack_info *info) +{ + struct pt_regs *regs; + unsigned long regs_start, regs_end; + + /* + * If the stack trace has already been marked unreliable, just + * return. + */ + if (!frame->reliable) + return; + + /* + * Assume that this is an intermediate marker frame inside a pt_regs + * structure created on the stack and get the pt_regs pointer. Other + * checks will be done below to make sure that this is a marker + * frame. + */ + regs_start = fp - offsetof(struct pt_regs, stackframe); + if (regs_start < info->low) + return; + regs_end = regs_start + sizeof(*regs); + if (regs_end > info->high) + return; + regs = (struct pt_regs *) regs_start; + + /* + * When an EL1 exception happens, a pt_regs structure is created + * on the stack and the register state is recorded. Part of the + * state is the FP and PC at the time of the exception. + * + * In addition, the FP and PC are also stored in pt_regs->stackframe + * and pt_regs->stackframe is chained with other frames on the stack. + * This is so that the interrupted function shows up in the stack + * trace. + * + * The exception could have happened during the frame pointer + * prolog or epilog. This could result in a missing frame in + * the stack trace so that the caller of the interrupted + * function does not show up in the stack trace. + * + * So, mark the stack trace as unreliable if an EL1 frame is + * detected. + */ + if (regs->frame_type == EL1_FRAME && regs->pc == frame->pc && + regs->regs[29] == frame->fp) { + frame->reliable = false; + return; + } +} + /* * AArch64 PCS assigns the frame pointer to x29. * @@ -114,6 +166,11 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) frame->pc = ptrauth_strip_insn_pac(frame->pc); + /* + * Check for features that render the stack trace unreliable. + */ + check_if_reliable(fp, frame, &info); + return 0; } NOKPROBE_SYMBOL(unwind_frame); From patchwork Mon Mar 15 16:57:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140099 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 37376C433E0 for ; Mon, 15 Mar 2021 17:01:33 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 D2A3F64DE0 for ; Mon, 15 Mar 2021 17:01:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D2A3F64DE0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=jFefturVfjiVoM7WhOY1zPW3V5yEUyy0jNPUMposATc=; b=KJhYtObWkPFngdST8SLUU5Ble n3akujMrGpL5jXhxyavNLhsfeyoRg2wXimAnE5ixszk18oVPH8AuwXcMrHjb+KQe1aHn8Js00E2HX B1c8wjmHi69Z8WwJRvH1HTZyxxEoJfFpRauywQSUt6Opar4JKH3JYE28aLpLlc+Zn5KNl1ovDq7vM 6gbL3YFOkIviud78w/n7kvlf1wLPvRrbBF7i7Uo7xPuNJ795cRP5vYMT6FsbSZ2VLlXWaf+xVWYIc yjLsrRQVq6lUYXHC3Gep3IqKPnBRBzV/PSxngDSBGABQX7f6Wt7gP2QmqlNe1iGVp2Ab+Hv/xicnV 5NmDfjBbg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqZ9-00GQAF-Qi; Mon, 15 Mar 2021 16:59:39 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXq-00GPos-Ep for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:22 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id AF36C20B26FC; Mon, 15 Mar 2021 09:58:14 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com AF36C20B26FC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827495; bh=TPMn1YTK7zzFM7ywn8W1+RGydSCGcujwty9kEX/anVI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Nx301mR2PlY4Cw21cjxPBVPLKynmTKQ3bXAU1qjHdCodL6b9mqIIkgNKjbfH55NgH ICEPIZtTE9mGjfBxI85Gand/ox/arvN5X8A55FxaktvHkThxUlGy8u3VJvQcZAW8K0 8Q4EJfVX1W29IbQUoKEuo5d0iBV7x8bLbf8v/818= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 5/8] arm64: Detect an FTRACE frame and mark a stack trace unreliable Date: Mon, 15 Mar 2021 11:57:57 -0500 Message-Id: <20210315165800.5948-6-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165820_476368_22A30900 X-CRM114-Status: GOOD ( 18.46 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" When CONFIG_DYNAMIC_FTRACE_WITH_REGS is enabled and tracing is activated for a function, the ftrace infrastructure is called for the function at the very beginning. Ftrace creates two frames: - One for the traced function - One for the caller of the traced function That gives a reliable stack trace while executing in the ftrace infrastructure code. When ftrace returns to the traced function, the frames are popped and everything is back to normal. However, in cases like live patch, execution is redirected to a different function when ftrace returns. A stack trace taken while still in the ftrace infrastructure code will not show the target function. The target function is the real function that we want to track. So, if an FTRACE frame is detected on the stack, just mark the stack trace as unreliable. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/entry-ftrace.S | 2 ++ arch/arm64/kernel/stacktrace.c | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S index b3e4f9a088b1..1ec8c5180fc0 100644 --- a/arch/arm64/kernel/entry-ftrace.S +++ b/arch/arm64/kernel/entry-ftrace.S @@ -74,6 +74,8 @@ /* Create our frame record within pt_regs. */ stp x29, x30, [sp, #S_STACKFRAME] add x29, sp, #S_STACKFRAME + ldr w17, =FTRACE_FRAME + str w17, [sp, #S_FRAME_TYPE] .endm SYM_CODE_START(ftrace_regs_caller) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 6ae103326f7b..594806a0c225 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -23,6 +23,7 @@ static void check_if_reliable(unsigned long fp, struct stackframe *frame, { struct pt_regs *regs; unsigned long regs_start, regs_end; + unsigned long caller_fp; /* * If the stack trace has already been marked unreliable, just @@ -68,6 +69,38 @@ static void check_if_reliable(unsigned long fp, struct stackframe *frame, frame->reliable = false; return; } + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS + /* + * When tracing is active for a function, the ftrace code is called + * from the function even before the frame pointer prolog and + * epilog. ftrace creates a pt_regs structure on the stack to save + * register state. + * + * In addition, ftrace sets up two stack frames and chains them + * with other frames on the stack. One frame is pt_regs->stackframe + * that is for the traced function. The other frame is set up right + * after the pt_regs structure and it is for the caller of the + * traced function. This is done to ensure a proper stack trace. + * + * If the ftrace code returns to the traced function, then all is + * fine. But if it transfers control to a different function (like + * in livepatch), then a stack walk performed while still in the + * ftrace code will not find the target function. + * + * So, mark the stack trace as unreliable if an ftrace frame is + * detected. + */ + if (regs->frame_type == FTRACE_FRAME && frame->fp == regs_end && + frame->fp < info->high) { + /* Check the traced function's caller's frame. */ + caller_fp = READ_ONCE_NOCHECK(*(unsigned long *)(frame->fp)); + if (caller_fp == regs->regs[29]) { + frame->reliable = false; + return; + } + } +#endif } /* From patchwork Mon Mar 15 16:57:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140101 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,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 66408C433DB for ; Mon, 15 Mar 2021 17:01:34 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 0A09664DDE for ; Mon, 15 Mar 2021 17:01:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0A09664DDE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=BgETyyczWkEQ2R4SLasPoR17aBZYjMB4DtEM3Xdpyk0=; b=M75YwhxfZ4QlYHpgSFYqmZ7uI S0L/xbzOSU+C7CcBY9ZQ8geAiCEGIChIMIsGxLzWrK2ymbfEliThfOlsdED5U7/mdlvEOcF368idy G4S3zoS5DtkufMClzJihLjAODe0xkdPEgy265M4VGV5O+yb5o2gVL4UhNV2l1QEjnKu8QZLQCYJOu nGbmQJ/6fNRDLSjcK7AakhTvzwj7z57Qi6KZ/RenUx1c0K0qZWm9m4fNiB+j1cRpu0ZawCndOXHV2 QrLU0PR+h46XmsCXfc7SAfZjSDbzyJdj/azPUzzF10x11SPHz+uOy//gefE6bgxmnk1OIfGHIb9DN bPLx5EzDA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqYu-00GQ4B-Qu; Mon, 15 Mar 2021 16:59:31 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXq-00GPor-Ei for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:21 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 8650420B26FE; Mon, 15 Mar 2021 09:58:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8650420B26FE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827496; bh=jheyVZ/lUkxf4Ht1TtTUL0sobQn62YR0CVwzSLRcRdA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=QJ42h8pS1O+0cURPnA4fdCqupwkpfS259xG/1wglI00VOExTU1uQoa03R3XOzBYrb lkMnRDAYrogw1NMDoZ7NnPHshtec1eFkIan34A5ppztxARo+x+Rg7Y2tjMJDA+p1am cYsgch6qRqbr/azncTfOJfhMUWYyvtO0UgZt21SI= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 6/8] arm64: Check the return PC of every stack frame Date: Mon, 15 Mar 2021 11:57:58 -0500 Message-Id: <20210315165800.5948-7-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165820_457747_90934DE7 X-CRM114-Status: UNSURE ( 9.41 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" If a function encountered in a stack trace is not a valid kernel text address, the stack trace is considered unreliable. Mark the stack trace as not reliable. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/stacktrace.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 594806a0c225..358aae3906d7 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -101,6 +101,16 @@ static void check_if_reliable(unsigned long fp, struct stackframe *frame, } } #endif + + /* + * A NULL or invalid return address probably means there's some + * generated code which __kernel_text_address() doesn't know about. + * Mark the stack trace as not reliable. + */ + if (!__kernel_text_address(frame->pc)) { + frame->reliable = false; + return; + } } /* From patchwork Mon Mar 15 16:57:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140131 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 BC5AEC433DB for ; Mon, 15 Mar 2021 17:02:09 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 5205664D9A for ; Mon, 15 Mar 2021 17:02:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5205664D9A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=usdfoZSejBi2Pkg+wQzuhgdUTe95Xld5qwdqmxF2mAM=; b=WWvRQdQKAX9CiTIm+KQsbtcDO JbMuPByVGAUvf020nEtLAdW+s74jrT8mWKtN065kZPAFl3yZUym3U2hpJK/XkAJ7IqCjpNn5QjCaP 9GMdY9UgiZPB5C16bVlFdpWwPS6YNwVAeCk1GrCpQyJXlwwE/ZmZeARE0a6R0pOXTArvTsYSSw7rx C4um2uWQACxNJWJL/2qBiXmVlCuwEge4btyIZ66YEeqXcT8cnbnyLw+3bu8hn+JJLUdzlrsxwN2vw qnKHYzIBn6ekjKd9cROStM+4DuetaZZWpUFcqGOf0HbBYZIWXzejOZUSie/EUVGEizNQMs9RKONfT Ohr2Wp3Tw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqZq-00GQOA-IG; Mon, 15 Mar 2021 17:00:22 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXr-00GPox-Vv for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:23 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 5D3FD20B24C9; Mon, 15 Mar 2021 09:58:16 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5D3FD20B24C9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827497; bh=U+g0k+CbNn5bvnLnkW0oWUHs8xX5CpmhC3AM4YySraA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TTELecyPokPX3waxtRE8n2B5zh3IpIDfunnF9vcMo7BWdiR0m16rpdEVxyRQlm2dZ hDRqbTIGUQi+Vqa+j2lzZgmXt37RIVSxofNatCRvnfdBaUXPtihaj4L5Ro3QBv30SO qNLTLIpLbXSzPFynG2eQVOxPrVDjTpRf+Lrccos0= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 7/8] arm64: Detect kretprobed functions in stack trace Date: Mon, 15 Mar 2021 11:57:59 -0500 Message-Id: <20210315165800.5948-8-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165820_771405_47671EA9 X-CRM114-Status: GOOD ( 18.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" When a kretprobe is active for a function, the function's return address in its stack frame is modified to point to the kretprobe trampoline. When the function returns, the frame is popped and control is transferred to the trampoline. The trampoline eventually returns to the original return address. If a stack walk is done within the function (or any functions that get called from there), the stack trace will only show the trampoline and the not the original caller. Detect this and mark the stack trace as unreliable. Also, if the trampoline and the functions it calls do a stack trace, that stack trace will also have the same problem. Detect this as well. This is done by looking up the symbol table entry for the trampoline and checking if the return PC in a frame falls anywhere in the trampoline function. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/stacktrace.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 358aae3906d7..752b77f11c61 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -18,6 +18,26 @@ #include #include +#ifdef CONFIG_KRETPROBES +static bool kretprobe_detected(struct stackframe *frame) +{ + static char kretprobe_name[KSYM_NAME_LEN]; + static unsigned long kretprobe_pc, kretprobe_end_pc; + unsigned long pc, offset, size; + + if (!kretprobe_pc) { + pc = (unsigned long) kretprobe_trampoline; + if (!kallsyms_lookup(pc, &size, &offset, NULL, kretprobe_name)) + return false; + + kretprobe_pc = pc - offset; + kretprobe_end_pc = kretprobe_pc + size; + } + + return frame->pc >= kretprobe_pc && frame->pc < kretprobe_end_pc; +} +#endif + static void check_if_reliable(unsigned long fp, struct stackframe *frame, struct stack_info *info) { @@ -111,6 +131,29 @@ static void check_if_reliable(unsigned long fp, struct stackframe *frame, frame->reliable = false; return; } + +#ifdef CONFIG_KRETPROBES + /* + * The return address of a function that has an active kretprobe + * is modified in the stack frame to point to a trampoline. So, + * the original return address is not available on the stack. + * + * A stack trace taken while executing the function (and its + * descendants) will not show the original caller. So, mark the + * stack trace as unreliable if the trampoline shows up in the + * stack trace. (Obtaining the original return address from + * task->kretprobe_instances seems problematic and not worth the + * effort). + * + * The stack trace taken while inside the trampoline and functions + * called by the trampoline have the same problem as above. This + * is also covered by kretprobe_detected() using a range check. + */ + if (kretprobe_detected(frame)) { + frame->reliable = false; + return; + } +#endif } /* From patchwork Mon Mar 15 16:58:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140129 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 196C9C433E0 for ; Mon, 15 Mar 2021 17:02:09 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 A957864D9D for ; Mon, 15 Mar 2021 17:02:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A957864D9D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.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=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type: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:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=foxNKzF9wwtm77Q0CBuViqvLJRbPEI/Qhz9EppVcZ9c=; b=MafWuWLPMS7AU2Yv6TxYh79i9 b4FFmGaNEEPoADfNWbNxhaRi4h3VeX8hMnQSTJcugpWJlb+FGh8F8018I7/kfT8gJxaKqA/v3PPQB wF/YP3KKUfR53LWsbEjSuR8yvtGyhEP9wJ6q5e25uGd0bU0ojb7Tk6sgh4HDo/ZGEqzU1UF/junyU sntEmJNlSYQzJDqbwY+gnZV68bdK6LhqBSOnUpLQuusumZ56UpavHMBw1DQzLgsKZUBPtn4QRqNxW 64MOJlGN3BGWRWjUClAeKiRi7m9tDt5XY2F6NS/68R9oJCfOk2hi7i1ya7m5o5O5cu+JqYw8BnCoi aW/BIuhzw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqZa-00GQIs-E2; Mon, 15 Mar 2021 17:00:12 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXs-00GPoy-4N for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:23 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 342EA20B24E6; Mon, 15 Mar 2021 09:58:17 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 342EA20B24E6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827497; bh=NS3hnkt5UwYxkTgE05jIzpsdhEjTfgYuj02sn7S/gpA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tAnL8saAEHYVh93a0MZLgmdvKOze1VnSLCDAbic/wGmkeCijxnPAq5lTPrRz8Ym2d vNKgQxWEXET4xIPrffDDVSiyrv1y+QAUGA23mId8BWJX8hcAPSMFZsBdetjv8x/XZk SwRPm1jyxHk0hECp4kkPwzjDSMWfBy4P/6WwNoj0= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 8/8] arm64: Implement arch_stack_walk_reliable() Date: Mon, 15 Mar 2021 11:58:00 -0500 Message-Id: <20210315165800.5948-9-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165820_777407_0CC89475 X-CRM114-Status: GOOD ( 12.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: "Madhavan T. Venkataraman" unwind_frame() already sets the reliable flag in the stack frame during a stack walk to indicate whether the stack trace is reliable or not. Implement arch_stack_walk_reliable() like arch_stack_walk() but abort the stack walk as soon as the reliable flag is set to false for any reason. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/stacktrace.c | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1f212b47a48a..954f60c35b26 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -167,6 +167,7 @@ config ARM64 if $(cc-option,-fpatchable-function-entry=2) select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ if DYNAMIC_FTRACE_WITH_REGS + select HAVE_RELIABLE_STACKTRACE select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_FAST_GUP select HAVE_FTRACE_MCOUNT_RECORD diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 752b77f11c61..5d15c111f3aa 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -361,4 +361,39 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, walk_stackframe(task, &frame, consume_entry, cookie); } +/* + * Walk the stack like arch_stack_walk() but stop the walk as soon as + * some unreliability is detected in the stack. + */ +int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, + void *cookie, struct task_struct *task) +{ + struct stackframe frame; + int ret = 0; + + if (task == current) { + start_backtrace(&frame, + (unsigned long)__builtin_frame_address(0), + (unsigned long)arch_stack_walk_reliable); + } else { + /* + * The task must not be running anywhere for the duration of + * arch_stack_walk_reliable(). The caller must guarantee + * this. + */ + start_backtrace(&frame, thread_saved_fp(task), + thread_saved_pc(task)); + } + + while (!ret) { + if (!frame.reliable) + return -EINVAL; + if (!consume_entry(cookie, frame.pc)) + return -EINVAL; + ret = unwind_frame(task, &frame); + } + + return ret == -ENOENT ? 0 : -EINVAL; +} + #endif