From patchwork Mon Oct 18 19:08:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12567809 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57525C433EF for ; Mon, 18 Oct 2021 19:11:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3FC7C61355 for ; Mon, 18 Oct 2021 19:11:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233192AbhJRTNr (ORCPT ); Mon, 18 Oct 2021 15:13:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:38906 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232892AbhJRTNr (ORCPT ); Mon, 18 Oct 2021 15:13:47 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2F33A60ED3; Mon, 18 Oct 2021 19:11:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634584295; bh=kR7awZvTzXuEKAfrnLLcHvoHgJDUyuE+raCW49n/OSk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j62y/Z+Fz37v90b5bZTrEqCiyQuSlpATXTNdscJsys67o10C1j02q7WOKcug8TpIt ZgMXYg5YyYw9e35qDcokzqNeDyhGFZIB1q0LVDJqpWy53IR+BH8OhUn2s033/Fs3R+ RJ0KOQ24k31TQMiC8lJyPtK7/DRJ9ucjlJ6eAtR0Z03JSSMNGs4h5wU+xgKrgtQrnN Z3feTV1FsvT3J6F3rPP/bZvmNmouQz2rbd2zAzRMqKDJEmpv5o4jO0NNp1nvYdZ926 a8MVY+rEzsO7QRs0o07ExrmddyujnTSFAuDANicUKbAkw6zwONFjzD7R8U6vWvF498 ESz3lxxhhyemQ== From: Mark Brown To: Catalin Marinas , Will Deacon , Shuah Khan , Shuah Khan Cc: Alan Hayward , Luis Machado , Salil Akerkar , Basant Kumar Dwivedi , Szabolcs Nagy , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown Subject: [PATCH v2 33/42] arm64/sme: Save and restore streaming mode over EFI runtime calls Date: Mon, 18 Oct 2021 20:08:49 +0100 Message-Id: <20211018190858.2119209-34-broonie@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211018190858.2119209-1-broonie@kernel.org> References: <20211018190858.2119209-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3623; h=from:subject; bh=kR7awZvTzXuEKAfrnLLcHvoHgJDUyuE+raCW49n/OSk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhbcZBNs3kd6fDK+ew3FeJhTxe35l3fHpQ4OnqukbQ aiewNLOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYW3GQQAKCRAk1otyXVSH0Dq4B/ 9cmPLjObf+4H8gr1oP0p/dFOpPJLS/zUnI6EzA7nhmHds668QyxhExkI6pV494JgFCTLWqQEkMbHlI QEECF2mupBIkNmYrwCxEEv3Ar8kxpW4Kr0UgvVywjg9C6cDNyv34CdYLAg5z2w6LmMkZkSGIwjiYiC gzN605yfy3A08+nhcxjMxDtZR5qkoPeHK0JWZUlm85MME7n5GvkKHEcRaK4FjjMnoz62OTV9avqgYh Deu5aRUkVRZ7yy9TLMzUGQTEs26213QRjrAdJdaoVSjlYkvo++364Y36nXLU/lG1W57PlJApSlxoH9 wmr4O2KbJHWjctb9EoiA6s9g1tHU4M X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org When saving and restoring the floating point state over an EFI runtime call ensure that we handle streaming mode, only handling FFR if we are not in streaming mode and ensuring that we are in normal mode over the call into runtime services. We currently assume that ZA will not be modified by runtime services, the specification is not yet finalised so this may need updating if that changes. Signed-off-by: Mark Brown --- arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index d3665d7f6e78..bd9a0eddf533 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1049,21 +1049,25 @@ int vec_verify_vq_map(enum vec_type type) static void __init sve_efi_setup(void) { - struct vl_info *info = &vl_info[ARM64_VEC_SVE]; + int max_vl = 0; + int i; if (!IS_ENABLED(CONFIG_EFI)) return; + for (i = 0; i < ARRAY_SIZE(vl_info); i++) + max_vl = max(vl_info[i].max_vl, max_vl); + /* * alloc_percpu() warns and prints a backtrace if this goes wrong. * This is evidence of a crippled system and we are returning void, * so no attempt is made to handle this situation here. */ - if (!sve_vl_valid(info->max_vl)) + if (!sve_vl_valid(max_vl)) goto fail; efi_sve_state = __alloc_percpu( - SVE_SIG_REGS_SIZE(sve_vq_from_vl(info->max_vl)), SVE_VQ_BYTES); + SVE_SIG_REGS_SIZE(sve_vq_from_vl(max_vl)), SVE_VQ_BYTES); if (!efi_sve_state) goto fail; @@ -1830,6 +1834,7 @@ EXPORT_SYMBOL(kernel_neon_end); static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state); static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); static DEFINE_PER_CPU(bool, efi_sve_state_used); +static DEFINE_PER_CPU(bool, efi_sm_state); /* * EFI runtime services support functions @@ -1864,12 +1869,28 @@ void __efi_fpsimd_begin(void) */ if (system_supports_sve() && likely(efi_sve_state)) { char *sve_state = this_cpu_ptr(efi_sve_state); + bool ffr = true; + u64 svcr; __this_cpu_write(efi_sve_state_used, true); + /* If we are in streaming mode don't touch FFR */ + if (system_supports_sme()) { + svcr = read_sysreg_s(SYS_SVCR_EL0); + + ffr = svcr & SYS_SVCR_EL0_SM_MASK; + + __this_cpu_write(efi_sm_state, ffr); + } + sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()), &this_cpu_ptr(&efi_fpsimd_state)->fpsr, - true); + ffr); + + if (system_supports_sme()) + sysreg_clear_set_s(SYS_SVCR_EL0, + SYS_SVCR_EL0_SM_MASK, 0); + } else { fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state)); } @@ -1892,11 +1913,25 @@ void __efi_fpsimd_end(void) if (system_supports_sve() && likely(__this_cpu_read(efi_sve_state_used))) { char const *sve_state = this_cpu_ptr(efi_sve_state); + bool ffr = true; + + /* + * Restore streaming mode; EFI calls are + * normal function calls so should not return in + * streaming mode. + */ + if (system_supports_sme()) { + if (__this_cpu_read(efi_sm_state)) { + sysreg_clear_set_s(SYS_SVCR_EL0, + 0, + SYS_SVCR_EL0_SM_MASK); + ffr = false; + } + } - sve_set_vq(sve_vq_from_vl(sve_get_vl()) - 1); sve_load_state(sve_state + sve_ffr_offset(sve_max_vl()), &this_cpu_ptr(&efi_fpsimd_state)->fpsr, - true); + ffr); __this_cpu_write(efi_sve_state_used, false); } else {