From patchwork Thu Sep 30 18:11:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12529003 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 43D30C433F5 for ; Thu, 30 Sep 2021 18:17:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B67C61A03 for ; Thu, 30 Sep 2021 18:17:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353372AbhI3SSq (ORCPT ); Thu, 30 Sep 2021 14:18:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:57390 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353361AbhI3SSq (ORCPT ); Thu, 30 Sep 2021 14:18:46 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 6EFF9615A2; Thu, 30 Sep 2021 18:17:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1633025823; bh=Ligfk65RNCu9Wfnj8w1o9wWT+oXrugBbw3Zc0UyzhDI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=orE1HHE0WiXPu9RVEPLLac/3EQSvoEFfPxg0F/Klo4S4pRp/cGnqKQrLFjvEV1t5f H3VgDgRqaHgvWgIP2JRNhHaGmv8Ls7dZIlS4mzv5SiDgfdpVsHQOhtsKhBgydEJX1G /GvelwXfxDnhdrQIrMf5Zb9RhpOKtZDsVpsTMQG7yL2+/rDNviU34EeTBl3q3GVK6B S0ug/FMStQlI1hCRDBqGWBOB3Wa/LGT7/e/JzpnWckKLjz9ruaM4osJQEcbnEmcnXq S2VNqmwug+01s2e1g5KLv29tozhp7tjLgSMbw8ZiLIHsYRg1EGmisPf1Oqexg/gL85 ZTVQknDgBs0Nw== 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 v1 30/38] arm64/sme: Save and restore streaming mode over EFI runtime calls Date: Thu, 30 Sep 2021 19:11:36 +0100 Message-Id: <20210930181144.10029-31-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210930181144.10029-1-broonie@kernel.org> References: <20210930181144.10029-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3623; h=from:subject; bh=Ligfk65RNCu9Wfnj8w1o9wWT+oXrugBbw3Zc0UyzhDI=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhVf3Z3Z4URt3YakTzqE8HXT0uHTUk9nnOtvV9wKCq kDL2sAqJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYVX92QAKCRAk1otyXVSH0D8wB/ 4nKQB6faEFSew6nmB3bQ9Hz7uAvFVgq1PIAK0y4WUqktN0j7kqM/Q9JOQPHRe8Rkc1ZkZulmmOp6Ju EaD9bW7Q4W9OId5HmsjqpWkUK/uLOIqWmFRkcTJc70PLQI35lO4M82RTK4HXx0TWEiI+hzNjWt01vu VXOMafAGIn6pymdTWDjFHr3WMpBX+B5gjB72vYyrTh8Y6eje4t3dtS4K3g+mbAX8yopud/x+NLT5fU OfMDsah2rUHGrdmvKv+TKngazT/Z1AGYblwusemQDhbm+aN2N/wcMzjlJ4RCUvTUkCj7JH/s2mTu11 Tq6I/WFiyuBJ79WTLHqdRRyGgdpV24 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 c34d32360502..62f8789f97cc 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1051,21 +1051,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; @@ -1824,6 +1828,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 @@ -1858,12 +1863,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)); } @@ -1886,11 +1907,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 {