From patchwork Fri Aug 18 11:37:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715263 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 2433EC71136 for ; Fri, 18 Aug 2023 11:38:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376689AbjHRLhq (ORCPT ); Fri, 18 Aug 2023 07:37:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376691AbjHRLhk (ORCPT ); Fri, 18 Aug 2023 07:37:40 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4000B30F6 for ; Fri, 18 Aug 2023 04:37:39 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C9F6263F2E for ; Fri, 18 Aug 2023 11:37:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64F01C43391; Fri, 18 Aug 2023 11:37:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358658; bh=lKrYL3uoj3AftwTA+wum5aWk6rB9/ZdGJQ5n+b0lnqQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nYR5I1HVsuaTIyIdrO/Vrmp0f3Qm6VncRC5NuhmVKulcbQpouVSFNRwSSKev2lddZ u/nTR0Z+YsHEKbMugiY3LXiIO0/wRXfQxczqmTdsyE8LYJNUrSGnrXDLi2MbW6HxgW ImVXRsH7cz6dCM+2Not7wYIGiA3u0DxUE4Et2saVvls8D7y7D1DaAZKboLtkrqWnu0 Ow4TftKPO6W+LaIU0G/XDVlIeRb0Ji235BuSWYq1xEhL63hf0V1LDeVY+RV4bjNFNJ fJkufAB2sQon5DVz6uyntzCXjwOwV6JAPCD6DlwqxG1EpiOkZTIsycCvZKNEGyee4b ipbG2LNrkVqUA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 01/11] efi/x86: Move EFI runtime call setup/teardown helpers out of line Date: Fri, 18 Aug 2023 13:37:14 +0200 Message-Id: <20230818113724.368492-2-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4172; i=ardb@kernel.org; h=from:subject; bh=lKrYL3uoj3AftwTA+wum5aWk6rB9/ZdGJQ5n+b0lnqQ=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++JvG5tZIe822p0rH2c46zxX49MS4Inp2rfSMI16F2 rpsDo86SlkYxDgYZMUUWQRm/3238/REqVrnWbIwc1iZQIYwcHEKwEQuPmT471rvGzfNRJ/9eISe 1Xy2Z5rRRkxtjn/K18xb5nzk7Mek24wMiwIv326oSLtvwsW5ZIuZy3P98BuhN30nvmbO/On7hH0 PFwA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Only the arch_efi_call_virt() macro that some architectures override needs to be a macro, given that it is variadic and encapsulates calls via function pointers that have different prototypes. The associated setup and teardown code are not special in this regard, and don't need to be instantiated at each call site. So turn them into ordinary C functions and move them out of line. Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/efi.h | 32 ++------------------ arch/x86/platform/efi/efi_32.c | 12 ++++++++ arch/x86/platform/efi/efi_64.c | 19 ++++++++++-- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index b0994ae3bc23f84d..c4555b269a1b2474 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -91,19 +91,6 @@ static inline void efi_fpu_end(void) #ifdef CONFIG_X86_32 #define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) - -#define arch_efi_call_virt_setup() \ -({ \ - efi_fpu_begin(); \ - firmware_restrict_branch_speculation_start(); \ -}) - -#define arch_efi_call_virt_teardown() \ -({ \ - firmware_restrict_branch_speculation_end(); \ - efi_fpu_end(); \ -}) - #else /* !CONFIG_X86_32 */ #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT @@ -116,14 +103,6 @@ extern bool efi_disable_ibt_for_runtime; __efi_call(__VA_ARGS__); \ }) -#define arch_efi_call_virt_setup() \ -({ \ - efi_sync_low_kernel_mappings(); \ - efi_fpu_begin(); \ - firmware_restrict_branch_speculation_start(); \ - efi_enter_mm(); \ -}) - #undef arch_efi_call_virt #define arch_efi_call_virt(p, f, args...) ({ \ u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ @@ -132,13 +111,6 @@ extern bool efi_disable_ibt_for_runtime; ret; \ }) -#define arch_efi_call_virt_teardown() \ -({ \ - efi_leave_mm(); \ - firmware_restrict_branch_speculation_end(); \ - efi_fpu_end(); \ -}) - #ifdef CONFIG_KASAN /* * CONFIG_KASAN may redefine memset to __memset. __memset function is present @@ -168,8 +140,8 @@ extern void efi_delete_dummy_variable(void); extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); extern void efi_free_boot_services(void); -void efi_enter_mm(void); -void efi_leave_mm(void); +void arch_efi_call_virt_setup(void); +void arch_efi_call_virt_teardown(void); /* kexec external ABI */ struct efi_setup_data { diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index e06a199423c0fedd..b2cc7b4552a16630 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -140,3 +140,15 @@ void __init efi_runtime_update_mappings(void) } } } + +void arch_efi_call_virt_setup(void) +{ + efi_fpu_begin(); + firmware_restrict_branch_speculation_start(); +} + +void arch_efi_call_virt_teardown(void) +{ + firmware_restrict_branch_speculation_end(); + efi_fpu_end(); +} diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 77f7ac3668cb4ac0..91d31ac422d6cde7 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -474,19 +474,34 @@ void __init efi_dump_pagetable(void) * can not change under us. * It should be ensured that there are no concurrent calls to this function. */ -void efi_enter_mm(void) +static void efi_enter_mm(void) { efi_prev_mm = current->active_mm; current->active_mm = &efi_mm; switch_mm(efi_prev_mm, &efi_mm, NULL); } -void efi_leave_mm(void) +static void efi_leave_mm(void) { current->active_mm = efi_prev_mm; switch_mm(&efi_mm, efi_prev_mm, NULL); } +void arch_efi_call_virt_setup(void) +{ + efi_sync_low_kernel_mappings(); + efi_fpu_begin(); + firmware_restrict_branch_speculation_start(); + efi_enter_mm(); +} + +void arch_efi_call_virt_teardown(void) +{ + efi_leave_mm(); + firmware_restrict_branch_speculation_end(); + efi_fpu_end(); +} + static DEFINE_SPINLOCK(efi_runtime_lock); /* From patchwork Fri Aug 18 11:37:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715264 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 106CAC05052 for ; Fri, 18 Aug 2023 11:38:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376691AbjHRLhq (ORCPT ); Fri, 18 Aug 2023 07:37:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376692AbjHRLhn (ORCPT ); Fri, 18 Aug 2023 07:37:43 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81E6C30F6 for ; Fri, 18 Aug 2023 04:37:42 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1784863FB9 for ; Fri, 18 Aug 2023 11:37:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A9DBFC433CC; Fri, 18 Aug 2023 11:37:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358661; bh=Iq7X6ZDY43lbw90pcqL5PNnyIedzbRO+mGLLwYciL/g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LVQKNaz12Bb3UlujJs7Zs4EsR/FaEbKNcVdrau4dtvj8MSQKw3aq7Q/5NKRJiS/cs qzm0EBpHozey3YU6O95V0STSTxBAexm0Ok9CuiPww/lf3Xb4X6hcbVunAhiyB84gCn 2eS4RgyIuzXfOpMzjuUPwZkQs7hH8K2F3N5cl4poymB+D+Lm1WEALTCk8hs1KODddG 72G+BZyryuVk61f8E86Ztk10+KHsp5AEaVuTr7zFLEkyVWZ7DLIBnKDYyToOrCToPc whnpB9KyvBH76JA3u979th8C6jLbDLJvqBr0EctJ0XvErubtLvOLeH+KCPpXsVq9Oz +o9ZwHQjI5nPg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 02/11] efi/arm64: Move EFI runtime call setup/teardown helpers out of line Date: Fri, 18 Aug 2023 13:37:15 +0200 Message-Id: <20230818113724.368492-3-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2507; i=ardb@kernel.org; h=from:subject; bh=Iq7X6ZDY43lbw90pcqL5PNnyIedzbRO+mGLLwYciL/g=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++BuniLQvC1eta5jN/qbXPfnucbGbHJ13NTbph0988 vf+EauOjlIWBjEOBlkxRRaB2X/f7Tw9UarWeZYszBxWJpAhDFycAjAR9mSG//FR2z5HWf44Pkc3 gVs94NlqG/1stQozQx6DWJ/e2KcrHjIyNBr8N9l05+aMQ1otMp82dNo8+qMVeeB+VFqxfMx9qdP 7uAE= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Only the arch_efi_call_virt() macro that some architectures override needs to be a macro, given that it is variadic and encapsulates calls via function pointers that have different prototypes. The associated setup and teardown code are not special in this regard, and don't need to be instantiated at each call site. So turn them into ordinary C functions and move them out of line. Signed-off-by: Ard Biesheuvel Acked-by: Catalin Marinas --- arch/arm64/include/asm/efi.h | 18 +++--------------- arch/arm64/kernel/efi.c | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 4cf2cb053bc8df95..f482b994c608ccf3 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -30,28 +30,16 @@ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool has_bti); -#define arch_efi_call_virt_setup() \ -({ \ - efi_virtmap_load(); \ - __efi_fpsimd_begin(); \ - raw_spin_lock(&efi_rt_lock); \ -}) - #undef arch_efi_call_virt #define arch_efi_call_virt(p, f, args...) \ __efi_rt_asm_wrapper((p)->f, #f, args) -#define arch_efi_call_virt_teardown() \ -({ \ - raw_spin_unlock(&efi_rt_lock); \ - __efi_fpsimd_end(); \ - efi_virtmap_unload(); \ -}) - -extern raw_spinlock_t efi_rt_lock; extern u64 *efi_rt_stack_top; efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); +void arch_efi_call_virt_setup(void); +void arch_efi_call_virt_teardown(void); + /* * efi_rt_stack_top[-1] contains the value the stack pointer had before * switching to the EFI runtime stack. diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index baab8dd3ead3c27a..49efbdbd6f7ae766 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -158,7 +158,21 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f) return s; } -DEFINE_RAW_SPINLOCK(efi_rt_lock); +static DEFINE_RAW_SPINLOCK(efi_rt_lock); + +void arch_efi_call_virt_setup(void) +{ + efi_virtmap_load(); + __efi_fpsimd_begin(); + raw_spin_lock(&efi_rt_lock); +} + +void arch_efi_call_virt_teardown(void) +{ + raw_spin_unlock(&efi_rt_lock); + __efi_fpsimd_end(); + efi_virtmap_unload(); +} asmlinkage u64 *efi_rt_stack_top __ro_after_init; From patchwork Fri Aug 18 11:37:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715261 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 3FC1DC001DE for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376703AbjHRLiR (ORCPT ); Fri, 18 Aug 2023 07:38:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376695AbjHRLhq (ORCPT ); Fri, 18 Aug 2023 07:37:46 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A76F92112 for ; Fri, 18 Aug 2023 04:37:45 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 46E2861182 for ; Fri, 18 Aug 2023 11:37:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4AEFC433CB; Fri, 18 Aug 2023 11:37:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358664; bh=AlXtUSfmgQDJEeIgIXVb9iOmWqjJa0RzB4mpyp7T7lM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FrGmOczGoissiN/pI1DaGIsRVgfXqWev0Y+jtQ4l9nsIx3ad2Pka3iS9FQkAw64Ar VmqUhvc8NOcbnGe4tkvSOUjDgDSA8pjbRn1r1NW58CY2AgrEgiIcE5iIk6Fe/j00eC 7f5o0F+d2UOHuEeDSse0xmyOBIb7b2pQYOU3CsDtD0fs1lbkF0oXV/W+uQ3E3MzFy3 IR5uwwskiNWP0I+NlHkoEGivE8TTPE3EtSNNEnyD1iFX+wlMc1ILIh5pSjyGNsdHJU ZsBJZhi44FLaKb97hg2P9UrDXfMqlMsSlp7b/glSLtEhTYO+uq76y1G55L/QEs3v41 cUg8Jcbgi2IUg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 03/11] efi/riscv: Move EFI runtime call setup/teardown helpers out of line Date: Fri, 18 Aug 2023 13:37:16 +0200 Message-Id: <20230818113724.368492-4-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2494; i=ardb@kernel.org; h=from:subject; bh=AlXtUSfmgQDJEeIgIXVb9iOmWqjJa0RzB4mpyp7T7lM=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++NsN17ikehRWH1t32K3rpZOlx/pVgpaui5oi/26Re 6uU9pG5o5SFQYyDQVZMkUVg9t93O09PlKp1niULM4eVCWQIAxenAEzk+15GhlW/VOM/sQk/jtr7 8ej02PIQx+rCU+opJuWLo/+c0lXgSmNkeHZojekzZUlrl9l746V6PBgqXzKdXh/9vofR/DdnrvY cNgA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Only the arch_efi_call_virt() macro that some architectures override needs to be a macro, given that it is variadic and encapsulates calls via function pointers that have different prototypes. The associated setup and teardown code are not special in this regard, and don't need to be instantiated at each call site. So turn them into ordinary C functions and move them out of line. Signed-off-by: Ard Biesheuvel --- arch/riscv/include/asm/efi.h | 10 ++-------- drivers/firmware/efi/riscv-runtime.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h index 29e9a0d84b16682f..8a6a128ec57fc02b 100644 --- a/arch/riscv/include/asm/efi.h +++ b/arch/riscv/include/asm/efi.h @@ -21,12 +21,6 @@ extern void efi_init(void); int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool); -#define arch_efi_call_virt_setup() ({ \ - sync_kernel_mappings(efi_mm.pgd); \ - efi_virtmap_load(); \ - }) -#define arch_efi_call_virt_teardown() efi_virtmap_unload() - #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) /* Load initrd anywhere in system RAM */ @@ -46,8 +40,8 @@ static inline unsigned long efi_get_kimg_min_align(void) #define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_min_align() -void efi_virtmap_load(void); -void efi_virtmap_unload(void); +void arch_efi_call_virt_setup(void); +void arch_efi_call_virt_teardown(void); unsigned long stext_offset(void); diff --git a/drivers/firmware/efi/riscv-runtime.c b/drivers/firmware/efi/riscv-runtime.c index d0daacd2c903f182..09525fb5c240e668 100644 --- a/drivers/firmware/efi/riscv-runtime.c +++ b/drivers/firmware/efi/riscv-runtime.c @@ -130,14 +130,25 @@ static int __init riscv_enable_runtime_services(void) } early_initcall(riscv_enable_runtime_services); -void efi_virtmap_load(void) +static void efi_virtmap_load(void) { preempt_disable(); switch_mm(current->active_mm, &efi_mm, NULL); } -void efi_virtmap_unload(void) +static void efi_virtmap_unload(void) { switch_mm(&efi_mm, current->active_mm, NULL); preempt_enable(); } + +void arch_efi_call_virt_setup(void) +{ + sync_kernel_mappings(efi_mm.pgd); + efi_virtmap_load(); +} + +void arch_efi_call_virt_teardown(void) +{ + efi_virtmap_unload(); +} From patchwork Fri Aug 18 11:37:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 714845 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 2A63AC05052 for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376695AbjHRLiS (ORCPT ); Fri, 18 Aug 2023 07:38:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376683AbjHRLhu (ORCPT ); Fri, 18 Aug 2023 07:37:50 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDCB32112 for ; Fri, 18 Aug 2023 04:37:48 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7FCA561182 for ; Fri, 18 Aug 2023 11:37:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29DFDC433C7; Fri, 18 Aug 2023 11:37:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358667; bh=hIrpLUZn61H+w4Z7crgigBTzE60wQK9ejIhnxwawVW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mKxv9Mq1AmgwkeMpHQvH4vvzjyfDrkbvtEWhAZRk7CWTDYlh2Xnht6vGM8k8lkT0d ZGAVwwdO++uJyHoQq0k76QDgOmihkrnNVeiIaFYS8GvVQRCCH3QhAIoR8g3DWYW2rZ uGwqE0WaLxa6rf+lhr9j5qSgaKDhVb6djSDiVsxNBVErRA04Xdzi32fpmka5qB/7Jl hHwuJoDtLKxksXXJReN/iMUaUQHLIVpJ9zHxmfW1KcW4P+oIdHonUUV3cWAk8/E4M4 y8EuLOtDC8+Q5p01L5hx1jMiVgploPefRMPXcldh1lO6pKxY5YGTfGCLqCrciPzSex ynhb7fD1ZMKdA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 04/11] efi/runtime-wrappers: Use type safe encapsulation of call arguments Date: Fri, 18 Aug 2023 13:37:17 +0200 Message-Id: <20230818113724.368492-5-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=13469; i=ardb@kernel.org; h=from:subject; bh=hIrpLUZn61H+w4Z7crgigBTzE60wQK9ejIhnxwawVW4=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++Lvs1bK/Pr84UV+6eVWNsHTG2uoLrPMOn951IjbjT mLkWiW5jlIWBjEOBlkxRRaB2X/f7Tw9UarWeZYszBxWJpAhDFycAjCRn6cZ/nBb9QbN4/4189PG yEWCd3qFmKPT5n4qPVSdl6dSu1erLo+RYXUMV2XFfJ+8/esS89plJWt//5CTnmn2dV7TnSxVwUl LGAA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The current code that marshalls the EFI runtime call arguments to hand them off to a async helper does so in a type unsafe and slightly messy manner - everything is cast to void* except for some integral types that are passed by reference and dereferenced on the receiver end. Let's clean this up a bit, and record the arguments of each runtime service invocation exactly as they are issued, in a manner that permits the compiler to check the types of the arguments at both ends. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/runtime-wrappers.c | 196 +++++++++++++------- include/linux/efi.h | 18 +- 2 files changed, 138 insertions(+), 76 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index a400c4312c829f18..66066e058757c1b5 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -44,20 +44,90 @@ #define __efi_call_virt(f, args...) \ __efi_call_virt_pointer(efi.runtime, f, args) +union efi_rts_args { + struct { + efi_time_t *time; + efi_time_cap_t *capabilities; + } GET_TIME; + + struct { + efi_time_t *time; + } SET_TIME; + + struct { + efi_bool_t *enabled; + efi_bool_t *pending; + efi_time_t *time; + } GET_WAKEUP_TIME; + + struct { + efi_bool_t enable; + efi_time_t *time; + } SET_WAKEUP_TIME; + + struct { + efi_char16_t *name; + efi_guid_t *vendor; + u32 *attr; + unsigned long *data_size; + void *data; + } GET_VARIABLE; + + struct { + unsigned long *name_size; + efi_char16_t *name; + efi_guid_t *vendor; + } GET_NEXT_VARIABLE; + + struct { + efi_char16_t *name; + efi_guid_t *vendor; + u32 attr; + unsigned long data_size; + void *data; + } SET_VARIABLE; + + struct { + u32 attr; + u64 *storage_space; + u64 *remaining_space; + u64 *max_variable_size; + } QUERY_VARIABLE_INFO; + + struct { + u32 *high_count; + } GET_NEXT_HIGH_MONO_COUNT; + + struct { + efi_capsule_header_t **capsules; + unsigned long count; + unsigned long sg_list; + } UPDATE_CAPSULE; + + struct { + efi_capsule_header_t **capsules; + unsigned long count; + u64 *max_size; + int *reset_type; + } QUERY_CAPSULE_CAPS; +}; + struct efi_runtime_work efi_rts_work; /* - * efi_queue_work: Queue efi_runtime_service() and wait until it's done - * @rts: efi_runtime_service() function identifier - * @rts_arg<1-5>: efi_runtime_service() function arguments + * efi_queue_work: Queue EFI runtime service call and wait for completion + * @_rts: EFI runtime service function identifier + * @_args: Arguments to pass to the EFI runtime service * * Accesses to efi_runtime_services() are serialized by a binary * semaphore (efi_runtime_lock) and caller waits until the work is * finished, hence _only_ one work is queued at a time and the caller * thread waits for completion. */ -#define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5) \ +#define efi_queue_work(_rts, _args...) \ ({ \ + efi_rts_work.efi_rts_id = EFI_ ## _rts; \ + efi_rts_work.args = &(union efi_rts_args){ ._rts = { _args }}; \ efi_rts_work.status = EFI_ABORTED; \ \ if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \ @@ -68,12 +138,6 @@ struct efi_runtime_work efi_rts_work; \ init_completion(&efi_rts_work.efi_rts_comp); \ INIT_WORK(&efi_rts_work.work, efi_call_rts); \ - efi_rts_work.arg1 = _arg1; \ - efi_rts_work.arg2 = _arg2; \ - efi_rts_work.arg3 = _arg3; \ - efi_rts_work.arg4 = _arg4; \ - efi_rts_work.arg5 = _arg5; \ - efi_rts_work.efi_rts_id = _rts; \ \ /* \ * queue_work() returns 0 if work was already on queue, \ @@ -170,73 +234,78 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock); /* * Calls the appropriate efi_runtime_service() with the appropriate * arguments. - * - * Semantics followed by efi_call_rts() to understand efi_runtime_work: - * 1. If argument was a pointer, recast it from void pointer to original - * pointer type. - * 2. If argument was a value, recast it from void pointer to original - * pointer type and dereference it. */ static void efi_call_rts(struct work_struct *work) { - void *arg1, *arg2, *arg3, *arg4, *arg5; + const union efi_rts_args *args = efi_rts_work.args; efi_status_t status = EFI_NOT_FOUND; - arg1 = efi_rts_work.arg1; - arg2 = efi_rts_work.arg2; - arg3 = efi_rts_work.arg3; - arg4 = efi_rts_work.arg4; - arg5 = efi_rts_work.arg5; - switch (efi_rts_work.efi_rts_id) { case EFI_GET_TIME: - status = efi_call_virt(get_time, (efi_time_t *)arg1, - (efi_time_cap_t *)arg2); + status = efi_call_virt(get_time, + args->GET_TIME.time, + args->GET_TIME.capabilities); break; case EFI_SET_TIME: - status = efi_call_virt(set_time, (efi_time_t *)arg1); + status = efi_call_virt(set_time, + args->SET_TIME.time); break; case EFI_GET_WAKEUP_TIME: - status = efi_call_virt(get_wakeup_time, (efi_bool_t *)arg1, - (efi_bool_t *)arg2, (efi_time_t *)arg3); + status = efi_call_virt(get_wakeup_time, + args->GET_WAKEUP_TIME.enabled, + args->GET_WAKEUP_TIME.pending, + args->GET_WAKEUP_TIME.time); break; case EFI_SET_WAKEUP_TIME: - status = efi_call_virt(set_wakeup_time, *(efi_bool_t *)arg1, - (efi_time_t *)arg2); + status = efi_call_virt(set_wakeup_time, + args->SET_WAKEUP_TIME.enable, + args->SET_WAKEUP_TIME.time); break; case EFI_GET_VARIABLE: - status = efi_call_virt(get_variable, (efi_char16_t *)arg1, - (efi_guid_t *)arg2, (u32 *)arg3, - (unsigned long *)arg4, (void *)arg5); + status = efi_call_virt(get_variable, + args->GET_VARIABLE.name, + args->GET_VARIABLE.vendor, + args->GET_VARIABLE.attr, + args->GET_VARIABLE.data_size, + args->GET_VARIABLE.data); break; case EFI_GET_NEXT_VARIABLE: - status = efi_call_virt(get_next_variable, (unsigned long *)arg1, - (efi_char16_t *)arg2, - (efi_guid_t *)arg3); + status = efi_call_virt(get_next_variable, + args->GET_NEXT_VARIABLE.name_size, + args->GET_NEXT_VARIABLE.name, + args->GET_NEXT_VARIABLE.vendor); break; case EFI_SET_VARIABLE: - status = efi_call_virt(set_variable, (efi_char16_t *)arg1, - (efi_guid_t *)arg2, *(u32 *)arg3, - *(unsigned long *)arg4, (void *)arg5); + status = efi_call_virt(set_variable, + args->SET_VARIABLE.name, + args->SET_VARIABLE.vendor, + args->SET_VARIABLE.attr, + args->SET_VARIABLE.data_size, + args->SET_VARIABLE.data); break; case EFI_QUERY_VARIABLE_INFO: - status = efi_call_virt(query_variable_info, *(u32 *)arg1, - (u64 *)arg2, (u64 *)arg3, (u64 *)arg4); + status = efi_call_virt(query_variable_info, + args->QUERY_VARIABLE_INFO.attr, + args->QUERY_VARIABLE_INFO.storage_space, + args->QUERY_VARIABLE_INFO.remaining_space, + args->QUERY_VARIABLE_INFO.max_variable_size); break; case EFI_GET_NEXT_HIGH_MONO_COUNT: - status = efi_call_virt(get_next_high_mono_count, (u32 *)arg1); + status = efi_call_virt(get_next_high_mono_count, + args->GET_NEXT_HIGH_MONO_COUNT.high_count); break; case EFI_UPDATE_CAPSULE: status = efi_call_virt(update_capsule, - (efi_capsule_header_t **)arg1, - *(unsigned long *)arg2, - *(unsigned long *)arg3); + args->UPDATE_CAPSULE.capsules, + args->UPDATE_CAPSULE.count, + args->UPDATE_CAPSULE.sg_list); break; case EFI_QUERY_CAPSULE_CAPS: status = efi_call_virt(query_capsule_caps, - (efi_capsule_header_t **)arg1, - *(unsigned long *)arg2, (u64 *)arg3, - (int *)arg4); + args->QUERY_CAPSULE_CAPS.capsules, + args->QUERY_CAPSULE_CAPS.count, + args->QUERY_CAPSULE_CAPS.max_size, + args->QUERY_CAPSULE_CAPS.reset_type); break; default: /* @@ -256,7 +325,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_TIME, tm, tc, NULL, NULL, NULL); + status = efi_queue_work(GET_TIME, tm, tc); up(&efi_runtime_lock); return status; } @@ -267,7 +336,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm) if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_TIME, tm, NULL, NULL, NULL, NULL); + status = efi_queue_work(SET_TIME, tm); up(&efi_runtime_lock); return status; } @@ -280,8 +349,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_WAKEUP_TIME, enabled, pending, tm, NULL, - NULL); + status = efi_queue_work(GET_WAKEUP_TIME, enabled, pending, tm); up(&efi_runtime_lock); return status; } @@ -292,8 +360,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_WAKEUP_TIME, &enabled, tm, NULL, NULL, - NULL); + status = efi_queue_work(SET_WAKEUP_TIME, enabled, tm); up(&efi_runtime_lock); return status; } @@ -308,7 +375,7 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_VARIABLE, name, vendor, attr, data_size, + status = efi_queue_work(GET_VARIABLE, name, vendor, attr, data_size, data); up(&efi_runtime_lock); return status; @@ -322,8 +389,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_NEXT_VARIABLE, name_size, name, vendor, - NULL, NULL); + status = efi_queue_work(GET_NEXT_VARIABLE, name_size, name, vendor); up(&efi_runtime_lock); return status; } @@ -338,7 +404,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_VARIABLE, name, vendor, &attr, &data_size, + status = efi_queue_work(SET_VARIABLE, name, vendor, attr, data_size, data); up(&efi_runtime_lock); return status; @@ -373,8 +439,8 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_QUERY_VARIABLE_INFO, &attr, storage_space, - remaining_space, max_variable_size, NULL); + status = efi_queue_work(QUERY_VARIABLE_INFO, attr, storage_space, + remaining_space, max_variable_size); up(&efi_runtime_lock); return status; } @@ -405,8 +471,7 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_NEXT_HIGH_MONO_COUNT, count, NULL, NULL, - NULL, NULL); + status = efi_queue_work(GET_NEXT_HIGH_MONO_COUNT, count); up(&efi_runtime_lock); return status; } @@ -437,8 +502,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_UPDATE_CAPSULE, capsules, &count, &sg_list, - NULL, NULL); + status = efi_queue_work(UPDATE_CAPSULE, capsules, count, sg_list); up(&efi_runtime_lock); return status; } @@ -455,8 +519,8 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_QUERY_CAPSULE_CAPS, capsules, &count, - max_size, reset_type, NULL); + status = efi_queue_work(QUERY_CAPSULE_CAPS, capsules, count, + max_size, reset_type); up(&efi_runtime_lock); return status; } diff --git a/include/linux/efi.h b/include/linux/efi.h index ab088c662e88d07b..b8c446da608371d2 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1265,23 +1265,21 @@ enum efi_rts_ids { EFI_QUERY_CAPSULE_CAPS, }; +union efi_rts_args; + /* * efi_runtime_work: Details of EFI Runtime Service work - * @arg<1-5>: EFI Runtime Service function arguments + * @args: Pointer to union describing the arguments * @status: Status of executing EFI Runtime Service * @efi_rts_id: EFI Runtime Service function identifier * @efi_rts_comp: Struct used for handling completions */ struct efi_runtime_work { - void *arg1; - void *arg2; - void *arg3; - void *arg4; - void *arg5; - efi_status_t status; - struct work_struct work; - enum efi_rts_ids efi_rts_id; - struct completion efi_rts_comp; + union efi_rts_args *args; + efi_status_t status; + struct work_struct work; + enum efi_rts_ids efi_rts_id; + struct completion efi_rts_comp; }; extern struct efi_runtime_work efi_rts_work; From patchwork Fri Aug 18 11:37:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 714844 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 6195DC7112B for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376683AbjHRLiS (ORCPT ); Fri, 18 Aug 2023 07:38:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376704AbjHRLhx (ORCPT ); Fri, 18 Aug 2023 07:37:53 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36A9C2112 for ; Fri, 18 Aug 2023 04:37:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C30E3640F0 for ; Fri, 18 Aug 2023 11:37:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63734C433CD; Fri, 18 Aug 2023 11:37:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358671; bh=dRh3NP8y7a8E3QhMbZav03QbCefaGbpm8c96PU7BZH8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rxzrJqvII/pxST2il3WC4fPsuEGWSj52YkKw/yP4WH9LKI7MzFJsERmDG2CgsgXA+ PT/Vuf9VRWy07yIu8VP2Pcbcvbs61jsEtsfH7HLxIbZ15E8LLq3UHLojVdzQK65jLV uJS5vfDEMUdfGfrUwfXo+Q+6H1QYdRpkG6ThXKqIht2LfJAEdwRQVoM36eaYJ1rFF/ 69/msHMrTTzMoHLLlK9tnjicA43DBsXQNYGODNhtNolQlaTodiAhFFX71r4Oqn6hSu CkIfNx1WaxMVScd3Stlppkh7UPwhstPq7oJ0OD8uuuZ9fxsdka3aHlES6UTYuUukiU KdcVyHBKuWdLQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 05/11] efi/runtime-wrapper: Move workqueue manipulation out of line Date: Fri, 18 Aug 2023 13:37:18 +0200 Message-Id: <20230818113724.368492-6-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3197; i=ardb@kernel.org; h=from:subject; bh=dRh3NP8y7a8E3QhMbZav03QbCefaGbpm8c96PU7BZH8=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++PvXDsnl/h+ZZts4L5/xhfWTnucfFrV4UYvU/MWb2 C1uhh3rKGVhEONgkBVTZBGY/ffdztMTpWqdZ8nCzGFlAhnCwMUpABMRuMrwTzUw9vIc1uX+J/6Z 3E/YqSFlbNOrx7KNd6s0w4e1p+9cqWH47/m36Yhke8b3RIeJFlkbmXmVraSMNYOv79hs3hUz0XA RGwA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org efi_queue_work() is a macro that implements the non-trivial manipulation of the EFI runtime workqueue and completion data structure, most of which is generic, and could be shared between all the users of the macro. So move it out of the macro and into a new helper function. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/runtime-wrappers.c | 61 +++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 66066e058757c1b5..ee5c9a3e50604398 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -125,34 +125,8 @@ struct efi_runtime_work efi_rts_work; * thread waits for completion. */ #define efi_queue_work(_rts, _args...) \ -({ \ - efi_rts_work.efi_rts_id = EFI_ ## _rts; \ - efi_rts_work.args = &(union efi_rts_args){ ._rts = { _args }}; \ - efi_rts_work.status = EFI_ABORTED; \ - \ - if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \ - pr_warn_once("EFI Runtime Services are disabled!\n"); \ - efi_rts_work.status = EFI_DEVICE_ERROR; \ - goto exit; \ - } \ - \ - init_completion(&efi_rts_work.efi_rts_comp); \ - INIT_WORK(&efi_rts_work.work, efi_call_rts); \ - \ - /* \ - * queue_work() returns 0 if work was already on queue, \ - * _ideally_ this should never happen. \ - */ \ - if (queue_work(efi_rts_wq, &efi_rts_work.work)) \ - wait_for_completion(&efi_rts_work.efi_rts_comp); \ - else \ - pr_err("Failed to queue work to efi_rts_wq.\n"); \ - \ - WARN_ON_ONCE(efi_rts_work.status == EFI_ABORTED); \ -exit: \ - efi_rts_work.efi_rts_id = EFI_NONE; \ - efi_rts_work.status; \ -}) + __efi_queue_work(EFI_ ## _rts, \ + &(union efi_rts_args){ ._rts = { _args }}) #ifndef arch_efi_save_flags #define arch_efi_save_flags(state_flags) local_save_flags(state_flags) @@ -319,6 +293,37 @@ static void efi_call_rts(struct work_struct *work) complete(&efi_rts_work.efi_rts_comp); } +static efi_status_t __efi_queue_work(enum efi_rts_ids id, + union efi_rts_args *args) +{ + efi_rts_work.efi_rts_id = id; + efi_rts_work.args = args; + efi_rts_work.status = EFI_ABORTED; + + if (!efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_warn_once("EFI Runtime Services are disabled!\n"); + efi_rts_work.status = EFI_DEVICE_ERROR; + goto exit; + } + + init_completion(&efi_rts_work.efi_rts_comp); + INIT_WORK(&efi_rts_work.work, efi_call_rts); + + /* + * queue_work() returns 0 if work was already on queue, + * _ideally_ this should never happen. + */ + if (queue_work(efi_rts_wq, &efi_rts_work.work)) + wait_for_completion(&efi_rts_work.efi_rts_comp); + else + pr_err("Failed to queue work to efi_rts_wq.\n"); + + WARN_ON_ONCE(efi_rts_work.status == EFI_ABORTED); +exit: + efi_rts_work.efi_rts_id = EFI_NONE; + return efi_rts_work.status; +} + static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { efi_status_t status; From patchwork Fri Aug 18 11:37:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715262 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 4FE74C71136 for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376704AbjHRLiT (ORCPT ); Fri, 18 Aug 2023 07:38:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376705AbjHRLh4 (ORCPT ); Fri, 18 Aug 2023 07:37:56 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AAE32112 for ; Fri, 18 Aug 2023 04:37:55 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0145062F79 for ; Fri, 18 Aug 2023 11:37:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F5FFC433C8; Fri, 18 Aug 2023 11:37:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358674; bh=hgE6UrRP8JhmGUqEbClx3EvIR+KJAiCIBIzs1bVLSaU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uIbtsvXsTjFwTzG0UcPwIMPGi0gM520bdx5l0GeZTWZM1q0qI42VT81D403+y0/DZ 8ClmfqQQBvMTIsf9k7gPABYoOckK9a7JKkVWChuwhVVJsX7osGjBllZOMkyqeusuGn vFzFnp1/t7jWPxllgYy6SSVObHXC/0W3Sy5As2rfPe+YKYT7docmm58l2XSDAb+zgc JfFts2het6nlvm9b45cWO+gBjRJ13YKLiTEz6KYgwyxa1nwJqRajc8Pek6TP4b6pXU 9CQ8Xh6lF8fSF+j+LWlh0qQoYFcrFbRAdkhJauEhlhawJVvh/CKYR9WDr9kez8cOw9 hSgm/pbumW0cg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 06/11] efi/runtime-wrappers: Remove duplicated macro for service returning void Date: Fri, 18 Aug 2023 13:37:19 +0200 Message-Id: <20230818113724.368492-7-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4864; i=ardb@kernel.org; h=from:subject; bh=hgE6UrRP8JhmGUqEbClx3EvIR+KJAiCIBIzs1bVLSaU=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++If7M0Iq1mhl13+dsH9RlmxXsLckm+ziRXWs9/9/C +qvkrvSUcrCIMbBICumyCIw+++7nacnStU6z5KFmcPKBDKEgYtTACbyPY3hv1MO0+RTAp2SmUq2 Txz+a91buyTpWeO2abo5U/VSvt77xMbIcLvpF2Ob/Je4bcvLGvX+Xpj7qSlnutCK0MxYTQH/J78 YOAA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org __efi_call_virt() exists as an alternative for efi_call_virt() for the sole reason that ResetSystem() returns void, and so we cannot use a call to it in the RHS of an assignment. Given that there is only a single user, let's drop the macro, and expand it into the caller. That way, the remaining macro can be tightened somewhat in terms of type safety too. Note that the use of typeof() on the runtime service invocation does not result in an actual call being made, but it does require a few pointer types to be fixed up and converted into the proper function pointer prototypes. Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/uv/bios.h | 3 ++- drivers/acpi/prmt.c | 2 +- drivers/firmware/efi/runtime-wrappers.c | 9 +++++--- include/linux/efi.h | 23 ++++---------------- 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/uv/bios.h b/arch/x86/include/asm/uv/bios.h index 1b6455f881f90e9c..501409f1258a196d 100644 --- a/arch/x86/include/asm/uv/bios.h +++ b/arch/x86/include/asm/uv/bios.h @@ -115,7 +115,8 @@ struct uv_arch_type_entry { struct uv_systab { char signature[4]; /* must be UV_SYSTAB_SIG */ u32 revision; /* distinguish different firmware revs */ - u64 function; /* BIOS runtime callback function ptr */ + u64 (__efiapi *function)(enum uv_bios_cmd, ...); + /* BIOS runtime callback function ptr */ u32 size; /* systab size (starting with _VERSION_UV4) */ struct { u32 type:8; /* type of entry */ diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 3d4c4620f9f95309..71b9adaaf33b93cf 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -53,7 +53,7 @@ static LIST_HEAD(prm_module_list); struct prm_handler_info { guid_t guid; - void *handler_addr; + efi_status_t (__efiapi *handler_addr)(u64, void *); u64 static_data_buffer_addr; u64 acpi_param_buffer_addr; diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index ee5c9a3e50604398..c5e0c73cc000ed25 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -41,8 +41,6 @@ */ #define efi_call_virt(f, args...) \ efi_call_virt_pointer(efi.runtime, f, args) -#define __efi_call_virt(f, args...) \ - __efi_call_virt_pointer(efi.runtime, f, args) union efi_rts_args { struct { @@ -491,8 +489,13 @@ static void virt_efi_reset_system(int reset_type, "could not get exclusive access to the firmware\n"); return; } + + arch_efi_call_virt_setup(); efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM; - __efi_call_virt(reset_system, reset_type, status, data_size, data); + arch_efi_call_virt(efi.runtime, reset_system, reset_type, status, + data_size, data); + arch_efi_call_virt_teardown(); + up(&efi_runtime_lock); } diff --git a/include/linux/efi.h b/include/linux/efi.h index b8c446da608371d2..ebb9671ed15ee3cb 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1171,8 +1171,7 @@ static inline void efi_check_for_embedded_firmwares(void) { } #define arch_efi_call_virt(p, f, args...) ((p)->f(args)) /* - * Arch code can implement the following three template macros, avoiding - * reptition for the void/non-void return cases of {__,}efi_call_virt(): + * Arch code must implement the following three routines: * * * arch_efi_call_virt_setup() * @@ -1181,9 +1180,8 @@ static inline void efi_check_for_embedded_firmwares(void) { } * * * arch_efi_call_virt() * - * Performs the call. The last expression in the macro must be the call - * itself, allowing the logic to be shared by the void and non-void - * cases. + * Performs the call. This routine takes a variable number of arguments so + * it must be implemented as a variadic preprocessor macro. * * * arch_efi_call_virt_teardown() * @@ -1192,7 +1190,7 @@ static inline void efi_check_for_embedded_firmwares(void) { } #define efi_call_virt_pointer(p, f, args...) \ ({ \ - efi_status_t __s; \ + typeof((p)->f(args)) __s; \ unsigned long __flags; \ \ arch_efi_call_virt_setup(); \ @@ -1206,19 +1204,6 @@ static inline void efi_check_for_embedded_firmwares(void) { } __s; \ }) -#define __efi_call_virt_pointer(p, f, args...) \ -({ \ - unsigned long __flags; \ - \ - arch_efi_call_virt_setup(); \ - \ - __flags = efi_call_virt_save_flags(); \ - arch_efi_call_virt(p, f, args); \ - efi_call_virt_check_flags(__flags, __stringify(f)); \ - \ - arch_efi_call_virt_teardown(); \ -}) - #define EFI_RANDOM_SEED_SIZE 32U // BLAKE2S_HASH_SIZE struct linux_efi_random_seed { From patchwork Fri Aug 18 11:37:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 714843 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 724D9C7113D for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376705AbjHRLiT (ORCPT ); Fri, 18 Aug 2023 07:38:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376706AbjHRLh7 (ORCPT ); Fri, 18 Aug 2023 07:37:59 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E6AF2112 for ; Fri, 18 Aug 2023 04:37:58 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3D45361DD9 for ; Fri, 18 Aug 2023 11:37:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D6AFCC433C7; Fri, 18 Aug 2023 11:37:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358677; bh=gupJBs1lJenWEdQdfCpvOfI2K/VV4o0bjxCM20K6qUY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OJkOj5K/UbTDWb+vX79Qbk0rA0RdXRE61Sw14IUSg/YX4nZwz9sn5agwCAadr4voY k/c10UqHjMxVCRHrrcNxrlFQswE0sALDHXb2Liecfs4Zvs/Y8Eh+/CRtKFUGLG/7qO P2/UfwglOlm0T098bQx08FJKx/jYXgGSJSLZzf6HXgZ3+lhnm1mXAv9ONza5ylU3uy uk4nSWgGncoV+fiwlZvwrclJpFM9CmEvKl42f2Q4Z2edao65lTQmXDMR2g40tlpDoC whlp0sFpfVRSBazcZNxJY5hUoNk+54imDull+kJS/RDkXCzN5z9DwE2k9pDJhc+0+H gYKazAcwMfLDA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 07/11] efi/runtime-wrappers: Don't duplicate setup/teardown code Date: Fri, 18 Aug 2023 13:37:20 +0200 Message-Id: <20230818113724.368492-8-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4983; i=ardb@kernel.org; h=from:subject; bh=gupJBs1lJenWEdQdfCpvOfI2K/VV4o0bjxCM20K6qUY=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++Iec064Z5ff2LBHO3T3LKuoNZ/JR/zWTjzjmcOSXs xw0CmLvKGVhEONgkBVTZBGY/ffdztMTpWqdZ8nCzGFlAhnCwMUpABPJNGD4Z/6ytuBQWkBP0qE7 6z1+2713FRNW8T9693tn7PYtz91/ZzP84Uy3nSju3f3KVOlMp/8LvSslE50+rGC15/dyWiB+xnE WOwA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Avoid duplicating the EFI arch setup and teardown routine calls numerous times in efi_call_rts(). Instead, expand the efi_call_virt_pointer() macro into efi_call_rts(), taking the pre and post parts out of the switch. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/runtime-wrappers.c | 26 ++++++++++++++------ include/linux/efi.h | 6 +++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index c5e0c73cc000ed25..afe9248cc5bc61ba 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -40,7 +40,7 @@ * code doesn't get too cluttered: */ #define efi_call_virt(f, args...) \ - efi_call_virt_pointer(efi.runtime, f, args) + arch_efi_call_virt(efi.runtime, f, args) union efi_rts_args { struct { @@ -139,7 +139,7 @@ unsigned long efi_call_virt_save_flags(void) return flags; } -void efi_call_virt_check_flags(unsigned long flags, const char *call) +void efi_call_virt_check_flags(unsigned long flags, const void *caller) { unsigned long cur_flags, mismatch; @@ -150,8 +150,8 @@ void efi_call_virt_check_flags(unsigned long flags, const char *call) return; add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_NOW_UNRELIABLE); - pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI %s\n", - flags, cur_flags, call); + pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI call from %pS\n", + flags, cur_flags, caller ?: __builtin_return_address(0)); arch_efi_restore_flags(flags); } @@ -211,6 +211,10 @@ static void efi_call_rts(struct work_struct *work) { const union efi_rts_args *args = efi_rts_work.args; efi_status_t status = EFI_NOT_FOUND; + unsigned long flags; + + arch_efi_call_virt_setup(); + flags = efi_call_virt_save_flags(); switch (efi_rts_work.efi_rts_id) { case EFI_GET_TIME: @@ -287,6 +291,10 @@ static void efi_call_rts(struct work_struct *work) */ pr_err("Requested executing invalid EFI Runtime Service.\n"); } + + efi_call_virt_check_flags(flags, efi_rts_work.caller); + arch_efi_call_virt_teardown(); + efi_rts_work.status = status; complete(&efi_rts_work.efi_rts_comp); } @@ -296,6 +304,7 @@ static efi_status_t __efi_queue_work(enum efi_rts_ids id, { efi_rts_work.efi_rts_id = id; efi_rts_work.args = args; + efi_rts_work.caller = __builtin_return_address(0); efi_rts_work.status = EFI_ABORTED; if (!efi_enabled(EFI_RUNTIME_SERVICES)) { @@ -423,8 +432,8 @@ virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; - status = efi_call_virt(set_variable, name, vendor, attr, data_size, - data); + status = efi_call_virt_pointer(efi.runtime, set_variable, name, vendor, + attr, data_size, data); up(&efi_runtime_lock); return status; } @@ -462,8 +471,9 @@ virt_efi_query_variable_info_nonblocking(u32 attr, if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; - status = efi_call_virt(query_variable_info, attr, storage_space, - remaining_space, max_variable_size); + status = efi_call_virt_pointer(efi.runtime, query_variable_info, attr, + storage_space, remaining_space, + max_variable_size); up(&efi_runtime_lock); return status; } diff --git a/include/linux/efi.h b/include/linux/efi.h index ebb9671ed15ee3cb..cf450b6fbfd20aa5 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1130,7 +1130,7 @@ extern bool efi_runtime_disabled(void); static inline bool efi_runtime_disabled(void) { return true; } #endif -extern void efi_call_virt_check_flags(unsigned long flags, const char *call); +extern void efi_call_virt_check_flags(unsigned long flags, const void *caller); extern unsigned long efi_call_virt_save_flags(void); enum efi_secureboot_mode { @@ -1197,7 +1197,7 @@ static inline void efi_check_for_embedded_firmwares(void) { } \ __flags = efi_call_virt_save_flags(); \ __s = arch_efi_call_virt(p, f, args); \ - efi_call_virt_check_flags(__flags, __stringify(f)); \ + efi_call_virt_check_flags(__flags, NULL); \ \ arch_efi_call_virt_teardown(); \ \ @@ -1258,6 +1258,7 @@ union efi_rts_args; * @status: Status of executing EFI Runtime Service * @efi_rts_id: EFI Runtime Service function identifier * @efi_rts_comp: Struct used for handling completions + * @caller: The caller of the runtime service */ struct efi_runtime_work { union efi_rts_args *args; @@ -1265,6 +1266,7 @@ struct efi_runtime_work { struct work_struct work; enum efi_rts_ids efi_rts_id; struct completion efi_rts_comp; + const void *caller; }; extern struct efi_runtime_work efi_rts_work; From patchwork Fri Aug 18 11:37:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 714841 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 BBDBCC71140 for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376706AbjHRLiU (ORCPT ); Fri, 18 Aug 2023 07:38:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376707AbjHRLiD (ORCPT ); Fri, 18 Aug 2023 07:38:03 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 173BF2112 for ; Fri, 18 Aug 2023 04:38:02 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9D0C1611F0 for ; Fri, 18 Aug 2023 11:38:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1BBCFC433CD; Fri, 18 Aug 2023 11:37:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358681; bh=h29N0feBCav5r5bx0a4iK0yWxYcrWfDbXT4psaOKqR8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NbkpZNYei9X+OpHern2zrvsSUsfRucH3f1ylsg07jLvAVE0koW2TOHXEkB7BcdCqX luNxc3/mfZv4tHLuQgwEAkK3cfsgfB9mL1xvB+suvYyQKjeBeNDCDa7XR49XzeVLMn yQE6lSwbgRzf9y5L1whs8fLzECjlnM1JDg63Zfq2IBKuy1cXmCqfrDgjAH5ERpna6p 7lKkSB1PVGkiTQ91HQ5uvl27Q+mJvWa5tFHrkLvi2C7Zy9u/S2vh0AMKwJMEhLbmRJ OIL+O5qn7bwIbrc1LjohkFjnj28Cr+59lfeekAZIj9ATYLbFbMOTCwBY/JtRelewTS D0iUxiJSXh23A== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers , "Rafael J . Wysocki" Subject: [PATCH v2 08/11] acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers Date: Fri, 18 Aug 2023 13:37:21 +0200 Message-Id: <20230818113724.368492-9-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4465; i=ardb@kernel.org; h=from:subject; bh=h29N0feBCav5r5bx0a4iK0yWxYcrWfDbXT4psaOKqR8=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++MevzoGn1iSu2tCTdqFzi9XRJz8mveVPr1yQ6a44O 45n2cwlHaUsDGIcDLJiiiwCs/++23l6olSt8yxZmDmsTCBDGLg4BWAic2wZ/ul6Z8WeN7n00ycy duPO3j9Bm5qy1nr8PfHCrueG+dr3ezYzMvxT+evL8XzxoU/1foJ3L6hXGjwsW6y3NmRWiUFW/Rl LUyYA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Instead of bypassing the kernel's adaptation layer for performing EFI runtime calls, wire up ACPI PRM handling into it. This means these calls can no longer occur concurrently with EFI runtime calls, and will be made from the EFI runtime workqueue. It also means any page faults occurring during PRM handling will be identified correctly as originating in firmware code. While at it, give the function pointer struct member a more descriptive name so it will stand out in diagnostic messages if any issues do occur. Acked-by: Rafael J. Wysocki Signed-off-by: Ard Biesheuvel --- drivers/acpi/Kconfig | 2 +- drivers/acpi/prmt.c | 6 ++-- drivers/firmware/efi/runtime-wrappers.c | 32 ++++++++++++++++++++ include/linux/efi.h | 5 +++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 00dd309b66828182..cee82b473dc50921 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -581,7 +581,7 @@ config ACPI_VIOT config ACPI_PRMT bool "Platform Runtime Mechanism Support" - depends on EFI && (X86_64 || ARM64) + depends on EFI_RUNTIME_WRAPPERS && (X86_64 || ARM64) default y help Platform Runtime Mechanism (PRM) is a firmware interface exposing a diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 71b9adaaf33b93cf..7020584096bfaaaf 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -260,9 +260,9 @@ static acpi_status acpi_platformrt_space_handler(u32 function, context.static_data_buffer = handler->static_data_buffer_addr; context.mmio_ranges = module->mmio_info; - status = efi_call_virt_pointer(handler, handler_addr, - handler->acpi_param_buffer_addr, - &context); + status = efi_call_acpi_prm_handler(handler->handler_addr, + handler->acpi_param_buffer_addr, + &context); if (status == EFI_SUCCESS) { buffer->prm_status = PRM_HANDLER_SUCCESS; } else { diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index afe9248cc5bc61ba..71d3c70f0705e1b9 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -108,6 +108,12 @@ union efi_rts_args { u64 *max_size; int *reset_type; } QUERY_CAPSULE_CAPS; + + struct { + efi_status_t (__efiapi *acpi_prm_handler)(u64, void *); + u64 param_buffer_addr; + void *context; + } ACPI_PRM_HANDLER; }; struct efi_runtime_work efi_rts_work; @@ -283,6 +289,14 @@ static void efi_call_rts(struct work_struct *work) args->QUERY_CAPSULE_CAPS.max_size, args->QUERY_CAPSULE_CAPS.reset_type); break; + case EFI_ACPI_PRM_HANDLER: +#ifdef CONFIG_ACPI_PRMT + status = arch_efi_call_virt(&args->ACPI_PRM_HANDLER, + acpi_prm_handler, + args->ACPI_PRM_HANDLER.param_buffer_addr, + args->ACPI_PRM_HANDLER.context); + break; +#endif default: /* * Ideally, we should never reach here because a caller of this @@ -560,3 +574,21 @@ void efi_native_runtime_setup(void) efi.update_capsule = virt_efi_update_capsule; efi.query_capsule_caps = virt_efi_query_capsule_caps; } + +#ifdef CONFIG_ACPI_PRMT + +efi_status_t +efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *), + u64 param_buffer_addr, void *context) +{ + efi_status_t status; + + if (down_interruptible(&efi_runtime_lock)) + return EFI_ABORTED; + status = efi_queue_work(ACPI_PRM_HANDLER, handler_addr, + param_buffer_addr, context); + up(&efi_runtime_lock); + return status; +} + +#endif diff --git a/include/linux/efi.h b/include/linux/efi.h index cf450b6fbfd20aa5..15b94dad5091b406 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1229,6 +1229,10 @@ extern int efi_tpm_final_log_size; extern unsigned long rci2_table_phys; +efi_status_t +efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *), + u64 param_buffer_addr, void *context); + /* * efi_runtime_service() function identifiers. * "NONE" is used by efi_recover_from_page_fault() to check if the page @@ -1248,6 +1252,7 @@ enum efi_rts_ids { EFI_RESET_SYSTEM, EFI_UPDATE_CAPSULE, EFI_QUERY_CAPSULE_CAPS, + EFI_ACPI_PRM_HANDLER, }; union efi_rts_args; From patchwork Fri Aug 18 11:37:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715259 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 AA83FC71143 for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376715AbjHRLiV (ORCPT ); Fri, 18 Aug 2023 07:38:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376708AbjHRLiG (ORCPT ); Fri, 18 Aug 2023 07:38:06 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F1A52112 for ; Fri, 18 Aug 2023 04:38:05 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D891263F2E for ; Fri, 18 Aug 2023 11:38:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EC3FC433C7; Fri, 18 Aug 2023 11:38:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358684; bh=aTNkd9tJBUR27+EUWkFHx594koq8HrLGzC3YyVAbhZQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CE+f9y1xSfOEZyDSfi3bJFZa9a5dPkU/mkoxOjiQSsHVV/iD0+tnTvdUgsDI4tUVg LTNf4uVWhepFDx4GKx1Z/nuZzqIQhCNd7ard7Y8+zerHKjinxciAkkkrIS1jNaHqXz TNAhokc0iiHskJ1a2l681hb3LEyycChnooV088HEN6XP73JHFdQKCVA58xo/Ean6kI Ki5e3apkotca7iBY0B0QdVu1LYRqZgnIDefT9TGs6lBHUDY6msp1Acnf8LUgaTUPBW 4LFsYVmZoaTYJgnvMy45Nh8RdBHDqe+vWQBEIvVSX3WHqWYeMBSXe+zpFJkXoHv4aZ SvPa8tQ8JglFg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [PATCH v2 09/11] efi/runtime-wrappers: Clean up white space and add __init annotation Date: Fri, 18 Aug 2023 13:37:22 +0200 Message-Id: <20230818113724.368492-10-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3096; i=ardb@kernel.org; h=from:subject; bh=aTNkd9tJBUR27+EUWkFHx594koq8HrLGzC3YyVAbhZQ=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++Cc/wXzm4Jr+t7L6/D2z7vJZWR3lkGg9GsC+7amE8 Tn/SJWOUhYGMQ4GWTFFFoHZf9/tPD1RqtZ5lizMHFYmkCEMXJwCMJGn4owMO+4fCEo08f6tL/pr zofJ+kmXmCsDGb+aHfoy+V/yd1arywz/NI+2bfbOtGj2qu5699S+kdlBX5A7XP837/aTGXu9wlU YAQ== X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Some cosmetic changes as well as a missing __init annotation. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/runtime-wrappers.c | 41 +++++++++----------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 71d3c70f0705e1b9..dfec5969dbaba417 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -437,9 +437,8 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, } static efi_status_t -virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, - u32 attr, unsigned long data_size, - void *data) +virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr, + unsigned long data_size, void *data) { efi_status_t status; @@ -472,10 +471,8 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, } static efi_status_t -virt_efi_query_variable_info_nonblocking(u32 attr, - u64 *storage_space, - u64 *remaining_space, - u64 *max_variable_size) +virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space, + u64 *remaining_space, u64 *max_variable_size) { efi_status_t status; @@ -557,22 +554,22 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, return status; } -void efi_native_runtime_setup(void) +void __init efi_native_runtime_setup(void) { - efi.get_time = virt_efi_get_time; - efi.set_time = virt_efi_set_time; - efi.get_wakeup_time = virt_efi_get_wakeup_time; - efi.set_wakeup_time = virt_efi_set_wakeup_time; - efi.get_variable = virt_efi_get_variable; - efi.get_next_variable = virt_efi_get_next_variable; - efi.set_variable = virt_efi_set_variable; - efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking; - efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; - efi.reset_system = virt_efi_reset_system; - efi.query_variable_info = virt_efi_query_variable_info; - efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking; - efi.update_capsule = virt_efi_update_capsule; - efi.query_capsule_caps = virt_efi_query_capsule_caps; + efi.get_time = virt_efi_get_time; + efi.set_time = virt_efi_set_time; + efi.get_wakeup_time = virt_efi_get_wakeup_time; + efi.set_wakeup_time = virt_efi_set_wakeup_time; + efi.get_variable = virt_efi_get_variable; + efi.get_next_variable = virt_efi_get_next_variable; + efi.set_variable = virt_efi_set_variable; + efi.set_variable_nonblocking = virt_efi_set_variable_nb; + efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; + efi.reset_system = virt_efi_reset_system; + efi.query_variable_info = virt_efi_query_variable_info; + efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nb; + efi.update_capsule = virt_efi_update_capsule; + efi.query_capsule_caps = virt_efi_query_capsule_caps; } #ifdef CONFIG_ACPI_PRMT From patchwork Fri Aug 18 11:37:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 714842 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 9AA11C7113E for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376708AbjHRLiV (ORCPT ); Fri, 18 Aug 2023 07:38:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376709AbjHRLiK (ORCPT ); Fri, 18 Aug 2023 07:38:10 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CC172112 for ; Fri, 18 Aug 2023 04:38:08 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1B0C564074 for ; Fri, 18 Aug 2023 11:38:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5001C433CD; Fri, 18 Aug 2023 11:38:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358687; bh=F5N2BWCw5LXSqWAwGduHWB8UYKK7GwBQ9TfTdKH2KyQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uinUEGFQ7AN0uE+14o0o0c4NeUBqlN91QNkD/YqOxz+bTjZ5YdqE49VbAKMVuDvuK es1iYXTVBvxVQjDHgpOoknY1HpX0whrUcdObPPwvmB6XXW5/JxFvpj/x3Hc1O8p3CG RccY7I8t9sC5X0gk1WxuKzyACYxuXFUcKtTuGLtgi0vM2O1xqs2nagOIzpiiIl/25C IH1BgG8tdQy7VluYao0FFA082aMjn9zDwXKuW2nLFezqUvYPGGA7iFCMYpjvD13Ppw xuC2vlnuPoNYxhBg4w0jXN5y8dyhlL8G2L9NtJb3c7TK1FmBbRX5GIiYevLh2o5kEh OnRZHPhZdLTBA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [RFC PATCH v2 10/11] efi/x86: Realign EFI runtime stack Date: Fri, 18 Aug 2023 13:37:23 +0200 Message-Id: <20230818113724.368492-11-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6508; i=ardb@kernel.org; h=from:subject; bh=F5N2BWCw5LXSqWAwGduHWB8UYKK7GwBQ9TfTdKH2KyQ=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++Gd7h/AZwmJd8/t0VKzlgxM2Zl/g2cTk91z7av61T 1K1oZ4dpSwMYhwMsmKKLAKz/77beXqiVK3zLFmYOaxMIEMYuDgFYCKhBxn+iqourWHP3PVEo/C6 kV2G1DaJcxVnjt0r3uAoxnBGW3dhOCPD5oKGuKuPX7We7VSok1p4a//xnCO/b3c+uWPLfZPHcFk JAwA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Instruct the compiler to realign the stack to 16 bytes, as required by the UEFI specification for x86_64. This will allow us to drop the asm helper that converts between MS and SysV calling conventions in a future patch. Signed-off-by: Ard Biesheuvel --- arch/x86/Makefile | 3 +++ arch/x86/include/asm/efi.h | 2 ++ arch/x86/platform/efi/Makefile | 2 ++ arch/x86/platform/efi/efi_64.c | 2 +- arch/x86/platform/uv/Makefile | 1 + arch/x86/platform/uv/bios_uv.c | 4 ++-- drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/runtime-wrappers.c | 17 ++++++++++------- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index fdc2e3abd6152f53..debc43fb9a2e6d36 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -36,10 +36,13 @@ export RETPOLINE_VDSO_CFLAGS ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) cc_stack_align4 := -mpreferred-stack-boundary=2 cc_stack_align8 := -mpreferred-stack-boundary=3 + EFI_STACK_ALIGN := -mpreferred-stack-boundary=4 else ifneq ($(call cc-option, -mstack-alignment=16),) cc_stack_align4 := -mstack-alignment=4 cc_stack_align8 := -mstack-alignment=8 + EFI_STACK_ALIGN := -mstack-alignment=16 endif +export EFI_STACK_ALIGN # How to compile the 16-bit code. Note we always compile for -march=i386; # that way we can complain to the user if the CPU is insufficient. diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index c4555b269a1b2474..c47f2d49e6bc6a09 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -111,6 +111,8 @@ extern bool efi_disable_ibt_for_runtime; ret; \ }) +#define __efi_realign_stack __attribute__((force_align_arg_pointer)) + #ifdef CONFIG_KASAN /* * CONFIG_KASAN may redefine memset to __memset. __memset function is present diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 543df9a1379d121c..684ac27cdf7cabfe 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -7,3 +7,5 @@ obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \ obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o + +CFLAGS_efi_64.o := $(EFI_STACK_ALIGN) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 91d31ac422d6cde7..8033b4a338c4b431 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -846,7 +846,7 @@ void __init efi_thunk_runtime_setup(void) efi.query_capsule_caps = efi_thunk_query_capsule_caps; } -efi_status_t __init __no_sanitize_address +efi_status_t __init __no_sanitize_address __efi_realign_stack efi_set_virtual_address_map(unsigned long memory_map_size, unsigned long descriptor_size, u32 descriptor_version, diff --git a/arch/x86/platform/uv/Makefile b/arch/x86/platform/uv/Makefile index 1441dda8edf76879..cb4807ba4ef50f02 100644 --- a/arch/x86/platform/uv/Makefile +++ b/arch/x86/platform/uv/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_time.o uv_nmi.o +CFLAGS_bios_uv.o := $(EFI_STACK_ALIGN) diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index bf31af3d32d69cbc..d6b69f363aa1f2a9 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -20,8 +20,8 @@ unsigned long uv_systab_phys __ro_after_init = EFI_INVALID_TABLE_ADDR; struct uv_systab *uv_systab; -static s64 __uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, - u64 a4, u64 a5) +static s64 __efi_realign_stack +__uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) { struct uv_systab *tab = uv_systab; s64 ret; diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e489fefd23dae0bc..db3f8c1fbc1d8a54 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -9,6 +9,7 @@ # in efi_call_virt() will cause crash if this code instrumented. # KASAN_SANITIZE_runtime-wrappers.o := n +CFLAGS_runtime-wrappers.o := $(EFI_STACK_ALIGN) obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index dfec5969dbaba417..2db9e0b3c2842e50 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -35,6 +35,10 @@ #include +#ifndef __efi_realign_stack +#define __efi_realign_stack +#endif + /* * Wrap around the new efi_call_virt_generic() macros so that the * code doesn't get too cluttered: @@ -213,7 +217,7 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock); * Calls the appropriate efi_runtime_service() with the appropriate * arguments. */ -static void efi_call_rts(struct work_struct *work) +static void __efi_realign_stack efi_call_rts(struct work_struct *work) { const union efi_rts_args *args = efi_rts_work.args; efi_status_t status = EFI_NOT_FOUND; @@ -436,7 +440,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, return status; } -static efi_status_t +static efi_status_t __efi_realign_stack virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data) { @@ -470,7 +474,7 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, return status; } -static efi_status_t +static efi_status_t __efi_realign_stack virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space, u64 *remaining_space, u64 *max_variable_size) { @@ -500,10 +504,9 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) return status; } -static void virt_efi_reset_system(int reset_type, - efi_status_t status, - unsigned long data_size, - efi_char16_t *data) +static void __efi_realign_stack +virt_efi_reset_system(int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data) { if (down_trylock(&efi_runtime_lock)) { pr_warn("failed to invoke the reset_system() runtime service:\n" From patchwork Fri Aug 18 11:37:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715260 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 83A97C7113C for ; Fri, 18 Aug 2023 11:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376709AbjHRLiV (ORCPT ); Fri, 18 Aug 2023 07:38:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376710AbjHRLiM (ORCPT ); Fri, 18 Aug 2023 07:38:12 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBE4F2112 for ; Fri, 18 Aug 2023 04:38:11 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 585AF63FB9 for ; Fri, 18 Aug 2023 11:38:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ED03CC433C8; Fri, 18 Aug 2023 11:38:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692358690; bh=u2Qe/DFQYFdROgabTymAKmhbaOyvbe9/hjLZEwEHzOA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dAbm6Jo/ESvka3uLylNsmVQoyUrwgTT2OoHXiucAtOgm1aeilJtoKX2ZrGiEpRizU 0mHs+CPBX9iel8JWZRIlUrYI7QdEwl7y3UUCygYJ9TUOlQnUtlx8eESRdxtb1NGTPH dyuRGSfUCOAzLX9pn1SWkC2SD8Bk2Sjx0rDNbYbguLV7Im4SnX/d0P4SyBoxWPIcEx rxXl4S/+qQZO0AyQn7WdVvJ95JM0G72rUQGJZgGBXXQbGNpejaBfxSpnja2q6fpk6o xy3REHqp0tr1PgGuOj3gLPH/Qm99pHBWtUCmFolTmoV42cF1620INgQ6wqhDQ7dX4i 5vxnp3UtlxdXQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Paul Walmsley , Palmer Dabbelt , Albert Ou , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "Rafael J. Wysocki" , Nathan Chancellor , Nick Desaulniers Subject: [RFC PATCH v2 11/11] efi/x86: Rely on compiler to emit MS ABI calls Date: Fri, 18 Aug 2023 13:37:24 +0200 Message-Id: <20230818113724.368492-12-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818113724.368492-1-ardb@kernel.org> References: <20230818113724.368492-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3659; i=ardb@kernel.org; h=from:subject; bh=u2Qe/DFQYFdROgabTymAKmhbaOyvbe9/hjLZEwEHzOA=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV++Jd/oToLY3XPr5ZgPLVzcoWNVNO7+UwqAr9zpqUfd ttSazupo5SFQYyDQVZMkUVg9t93O09PlKp1niULM4eVCWQIAxenAExE1Ybhv4N5Wtb6eSabFWZ+ OVHo+NHwcOwnrnaHVXmSUi/TRSN1+hj+x8494HRhusez14asjN5/HnldeuB05tFfpdk8bS39r0r W8QIA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org When EFI support was added to the x86_64 port originally, GCC did not implement support for emitting procedure calls using the MS calling convention, which deviates from the SysV one used in Linux. However, this support has been added a long time ago, and the EFI stub (which runs in a different execution context) has already been updated to simply rely on the __attribute__((ms_abi)) annotations of the EFI function pointers, resulting in both GCC and Clang doing the right thing, as long as the correct stack alignment is being used. The EFI stub runs on the stack provided by the firmware, and maintains 16 byte alignment internally, but the core x86_64 code does not, so explicit stack realignment is needed, and this has been dealt with in a previous patch. So the asm wrapper has become redundant, and can be dropped. Note that one of the EFI runtime services returns void so a trick is needed to make the compiler ignore the return value in that case, or an error will be triggered. Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/efi.h | 11 +++----- arch/x86/platform/efi/Makefile | 4 +-- arch/x86/platform/efi/efi_stub_64.S | 27 -------------------- 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index c47f2d49e6bc6a09..f5ac4dbecafe7f37 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -94,19 +94,14 @@ static inline void efi_fpu_end(void) #else /* !CONFIG_X86_32 */ #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT -extern asmlinkage u64 __efi_call(void *fp, ...); - extern bool efi_disable_ibt_for_runtime; -#define efi_call(...) ({ \ - __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ - __efi_call(__VA_ARGS__); \ -}) - #undef arch_efi_call_virt #define arch_efi_call_virt(p, f, args...) ({ \ u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ - ret = efi_call((void *)p->f, args); \ + ret = __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof((p)->f(args)),void),\ + ((p)->f(args), EFI_ABORTED), (p)->f(args)); \ ibt_restore(ibt); \ ret; \ }) diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 684ac27cdf7cabfe..6dbd9533c4ce088c 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -2,8 +2,8 @@ KASAN_SANITIZE := n GCOV_PROFILE := n -obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \ - efi_stub_$(BITS).o +obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o +obj-$(CONFIG_X86_32) += efi_stub_32.o obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S deleted file mode 100644 index 2206b8bc47b8a757..0000000000000000 --- a/arch/x86/platform/efi/efi_stub_64.S +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Function calling ABI conversion from Linux to EFI for x86_64 - * - * Copyright (C) 2007 Intel Corp - * Bibo Mao - * Huang Ying - */ - -#include -#include - -SYM_FUNC_START(__efi_call) - pushq %rbp - movq %rsp, %rbp - and $~0xf, %rsp - mov 16(%rbp), %rax - subq $48, %rsp - mov %r9, 32(%rsp) - mov %rax, 40(%rsp) - mov %r8, %r9 - mov %rcx, %r8 - mov %rsi, %rcx - CALL_NOSPEC rdi - leave - RET -SYM_FUNC_END(__efi_call)