From patchwork Wed Jan 4 17:44:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 639098 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95686C4332F for ; Wed, 4 Jan 2023 17:44:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229845AbjADRou (ORCPT ); Wed, 4 Jan 2023 12:44:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235249AbjADRot (ORCPT ); Wed, 4 Jan 2023 12:44:49 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35F961B1DB for ; Wed, 4 Jan 2023 09:44:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E34A8B81898 for ; Wed, 4 Jan 2023 17:44:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B519C43392; Wed, 4 Jan 2023 17:44:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672854285; bh=RVLeuAkGJfKugExBOTAaGVn7MhDxBZ6OszcRfikiIro=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pSdvXAAnY0thUFsfEFE3i6d7TySSnCTea2lnKMr1SPPDZMr9ugTFebaOzyQuh+l9a 5BzEDkXbieHARhpxTShMS+wrUwBZIIq1HO1+87oVxeL7TeDCH/vwlbUJ/GzMmej8G/ auKTy3K5ekouLtSgu/htyp76fvdBdcI1UhQO58guFz5sSfeyfFEK9vJpjqtqD5Sd8x nmQU22Fm001K85zFU27fVT8+2glFw38YaGRKydZPplrlxoZcxSqbgcYnEzcLGNc3ZJ I9mU4ez+Y8Buh0eBsyNTESSTU7Qx50v2U1KvMTosZNanuHH1VB8z8auP/mIwH/Gimg /i8ClM3b499Bw== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: linux-efi@vger.kernel.org, catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel Subject: [PATCH v2 1/2] arm64: efi: Avoid workqueue to check whether EFI runtime is live Date: Wed, 4 Jan 2023 18:44:32 +0100 Message-Id: <20230104174433.1259428-2-ardb@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230104174433.1259428-1-ardb@kernel.org> References: <20230104174433.1259428-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2657; i=ardb@kernel.org; h=from:subject; bh=RVLeuAkGJfKugExBOTAaGVn7MhDxBZ6OszcRfikiIro=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjtbr+QOODKPbw4hN1P+ENAtcWsFVB38vpvhOozwm/ jnXFxlOJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY7W6/gAKCRDDTyI5ktmPJGadDA CVh1U+IQ/212TL9laa6eRsl6tdRloJ4Cn8L6yheLZWah7jbBqdN9VSBuEn3vXBvvIZrmuYjqXleS4u Cb8teqn+WP1TJEiTst3LBi0/LkZFpOnNAJ6IvIO3csHDFEBe3hZvDeaoWEb/ytSNU9p5yGB1ER6NJP +YuiHav8vipnmORCTJeqcylHOM6lim4f0W3Yx1MZVeBz8/b6aHdxz1lXXWEcCb5WSr9OT6MDm2eghK JEjr30IgY5q3RMT1JDXSo+Ki5QbL7mLwf+szutC0wvg0PdpUjr0bAyjP4tkI7NtVnD5bsqRfnCCbgy PgJi4eaME6N25fUMu/WNU/L+h8XMm+G8Cu1whWWPiSbGqIeFj2/z86GgG8c/ZrDF7/xJl6A1sSwH5n /bPNWM/1M3dmwlrotUFJuY2riwI2rtbEpvSjUxUm/m9EPj5kGcrTBQ7emKVVU7rdQtcS3J4WWSLyYT GVNFsFguURec36NLAnENB1dpNCQzGMNuxmqX7Lw1YLhbI= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Comparing current_work() against efi_rts_work.work is sufficient to decide whether current is currently running EFI runtime services code at any level in its call stack. However, there are other potential users of the EFI runtime stack, such as the ACPI subsystem, which may invoke efi_call_virt_pointer() directly, and so any sync exceptions occurring in firmware during those calls are currently misidentified. So instead, let's check whether the spinlock is locked, and whether the stashed value of the thread stack pointer points into current's thread stack. This can only be the case if current was interrupted while running EFI runtime code. Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/efi.h | 10 ++++++++++ arch/arm64/kernel/efi.c | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 31d13a6001df49c4..aca6dcaa33efbac4 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -42,14 +42,24 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_teardown() \ ({ \ + efi_rt_stack_top[-1] = 0; \ spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ }) extern spinlock_t efi_rt_lock; +extern u64 *efi_rt_stack_top; efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); +/* + * efi_rt_stack_top[-1] contains the value the stack pointer had before + * switching to the EFI runtime stack. + */ +#define current_in_efi() \ + (!preemptible() && spin_is_locked(&efi_rt_lock) && \ + on_task_stack(current, efi_rt_stack_top[-1], 1)) + #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) /* diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index fab05de2e12dd5d8..b273900f45668587 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -11,6 +11,7 @@ #include #include +#include static bool region_is_misaligned(const efi_memory_desc_t *md) { @@ -154,7 +155,7 @@ asmlinkage efi_status_t __efi_rt_asm_recover(void); bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg) { /* Check whether the exception occurred while running the firmware */ - if (current_work() != &efi_rts_work.work || regs->pc >= TASK_SIZE_64) + if (!current_in_efi() || regs->pc >= TASK_SIZE_64) return false; pr_err(FW_BUG "Unable to handle %s in EFI runtime service\n", msg); From patchwork Wed Jan 4 17:44:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 639577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86189C4708D for ; Wed, 4 Jan 2023 17:44:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235338AbjADRow (ORCPT ); Wed, 4 Jan 2023 12:44:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235135AbjADRou (ORCPT ); Wed, 4 Jan 2023 12:44:50 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7B9E1AA2A for ; Wed, 4 Jan 2023 09:44:49 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5F894B817B0 for ; Wed, 4 Jan 2023 17:44:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 039DBC433D2; Wed, 4 Jan 2023 17:44:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672854287; bh=zLoq7rh6ScCHPZAIwnMyOMYtt4LObBNVb50PEjsCMO4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TkjjtbVhvm7y6BrLK/JIutVKbhkb/iI1jjqXaMaqMPwJXwXmHOQIoFHs6voBFXfpD sNWCT1yyxH0Xm8mE6qnOdOBXbWehGPV8mb3r986AKkEfdG0KAafREr/KMi+6sTlbVj 2pyn4l6IdTiLnbb6GBk9af8s0beoNYM33lICoDcbvOoTogLpOEmiCHrdH05GcJyh86 Aa3raCWj778enkKGLJSSK84oKmQ5xcbg93M75kdBrmwon3lzH9Tp0VZlTtTY3jc1FX zZbCJKMpm4nytUW7QG7iGE4FhyXBmI5biS3H+LuzkqvET4ihfCnWRrfIGhskXR4lq6 HT7HuyV7ptFmA== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: linux-efi@vger.kernel.org, catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel Subject: [PATCH v2 2/2] arm64: efi: Account for the EFI runtime stack in stack unwinder Date: Wed, 4 Jan 2023 18:44:33 +0100 Message-Id: <20230104174433.1259428-3-ardb@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230104174433.1259428-1-ardb@kernel.org> References: <20230104174433.1259428-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2451; i=ardb@kernel.org; h=from:subject; bh=zLoq7rh6ScCHPZAIwnMyOMYtt4LObBNVb50PEjsCMO4=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjtbsAKsux2GnbGItRO4bTstltLeejaKlQ2jZlbxHU duGvq9GJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY7W7AAAKCRDDTyI5ktmPJH/QC/ 40BVyTgbU9WcPUL8vgnzKPNg6kfH6vVDQQIh1M1j5otlrcinpjKMg92e3wPYMBq11w1+CRStzBjKSr gudVIrmYmDsohFZDDVxWixMU8WTR92mN6Rh7YwXRYL0ASsrbvFaRVeBqFPUTz8NDk0s3gueljAuZM9 EkFYAOmigpNc33dUtIhnPhti6ir4TqnD7yFPczbu+cJ6kgz6ZLXAnTUykmeJZYmG8s3OByZpDfa7Ff E9vfRnXEXI4teGqRpp3Yk1XLQdbLoFwLQ5BWdu4mGW50ZM5R+fhpHrPSzSxbHsngJHPpgfUlYzqgOe 99wIZMUNjaDHtfavtf7FQHvNbHhstqzdF2c5nkXZR1SxkCBIsJ30l9pyNQJ9KDQP6gAQ8wMl0sRpUs bSjl9v31a4mY9yCAO7HPnuF1tz6hewx3E/LxDzJi2tHe+w1X/2PJXb6aF2G8tq/5EnLW+ZRIDuMblv KzEY9PBIQY1xv0kbGQ1fodLuyNSCAkU4WlnCDmWDe5t8I= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The EFI runtime services run from a dedicated stack now, and so the stack unwinder needs to be informed about this. Signed-off-by: Ard Biesheuvel Acked-by: Mark Rutland --- arch/arm64/include/asm/stacktrace.h | 15 +++++++++++++++ arch/arm64/kernel/stacktrace.c | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 4e5354beafb01bac..66ec8caa6ac07fa0 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -106,4 +106,19 @@ static inline struct stack_info stackinfo_get_sdei_critical(void) #define stackinfo_get_sdei_critical() stackinfo_get_unknown() #endif +#ifdef CONFIG_EFI +extern u64 *efi_rt_stack_top; + +static inline struct stack_info stackinfo_get_efi(void) +{ + unsigned long high = (u64)efi_rt_stack_top; + unsigned long low = high - THREAD_SIZE; + + return (struct stack_info) { + .low = low, + .high = high, + }; +} +#endif + #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 117e2c180f3c77d8..83154303e682c8b6 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -5,6 +5,7 @@ * Copyright (C) 2012 ARM Ltd. */ #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include +#include #include #include #include @@ -186,6 +188,13 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) : stackinfo_get_unknown(); \ }) +#define STACKINFO_EFI \ + ({ \ + ((task == current) && current_in_efi()) \ + ? stackinfo_get_efi() \ + : stackinfo_get_unknown(); \ + }) + noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct task_struct *task, struct pt_regs *regs) @@ -199,6 +208,9 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, #if defined(CONFIG_VMAP_STACK) && defined(CONFIG_ARM_SDE_INTERFACE) STACKINFO_SDEI(normal), STACKINFO_SDEI(critical), +#endif +#ifdef CONFIG_EFI + STACKINFO_EFI, #endif }; struct unwind_state state = {