From patchwork Tue Jan 25 00:11:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12723044 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 9499DC3526C for ; Tue, 25 Jan 2022 00:30:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S3409274AbiAYAZU (ORCPT ); Mon, 24 Jan 2022 19:25:20 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:57634 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2374433AbiAYARD (ORCPT ); Mon, 24 Jan 2022 19:17:03 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1245AB81229 for ; Tue, 25 Jan 2022 00:17:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 62715C340E7; Tue, 25 Jan 2022 00:16:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643069819; bh=2K+d8/DMqd4mvE9cJnbibgkPl3KrRBgwnPSoHVE0UAo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T9Cw6u62W8QyCHh1tpR9fa83mjVkWzolYK3fcXx/0Y5wRchwP2JRmOAWwjS8LNMU/ lxz3ZMsYEv7i+1teXE5D0aiFo8vRdu8ZO40/punibI1p9fE6gJEjZYcTg/XE0eoH66 0NU7GYsSL7gwwgkfhOzZTkYctt7TerRrAjrlkwjUX1SWRLjj/Yvjw8dD9X1B1e9p5M dZB6vdq8Xq8j7OjtQuM3j3EHLk0eDHfjdRqJhIWQe16kVlh31uleuXXeWfypqHf/Ly /GagRF+SQTR0g6K8uZFtBAW/06In4XWyf2f9w/tngGBXi/D1cnYUqiM7qyFcfONb37 GPLOz5snoA+iA== From: Mark Brown To: Catalin Marinas , Will Deacon , Marc Zyngier , Shuah Khan , Shuah Khan Cc: Alan Hayward , Luis Machado , Salil Akerkar , Basant Kumar Dwivedi , Szabolcs Nagy , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Mark Brown Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest Date: Tue, 25 Jan 2022 00:11:01 +0000 Message-Id: <20220125001114.193425-26-broonie@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220125001114.193425-1-broonie@kernel.org> References: <20220125001114.193425-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4227; h=from:subject; bh=2K+d8/DMqd4mvE9cJnbibgkPl3KrRBgwnPSoHVE0UAo=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBh70AU4a/+cDNf4VWDVga58hP9R5fF3nkKlfdqnkaZ L59Va9SJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYe9AFAAKCRAk1otyXVSH0DpPB/ 9VMrjTiZOfN6iNY8J7x9KzEbjpM1EngHYL3i5lUPC6Rc6Qse8VJV54DOpaH/+XE8zwZA0bx3myYH5H Qfh3zVYN4jPbEYDEGc7nvwtSXUXW37GbcOQbvmlhUvkkwGKUjgWZaML8fi4u4mV9LfwSjnrPI1lhRu j2IYPIyRklkbKjOdF38ef0ivvnK7YO4hkwpQhRv3Dg1T+N1KaMj83i4kciAe7svg2rZvAUvQuh7sh2 TcXBLgtp7lFpALu5Nqw25z1HEHL/RlCKtLJD+xSzXYywckUBHKwqzYU2aUVWmf1PlHLHk3ArqTOhz1 T3jWHntOmtfMuFkORB7t8oTrrJY/fc X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org SME defines two new traps which need to be enabled for guests to ensure that they can't use SME, one for the main SME operations which mirrors the traps for SVE and another for access to TPIDR2 in SCTLR_EL2. For VHE manage SMEN along with ZEN in activate_traps() and the FP state management callbacks. For nVHE the value to be used for CPTR_EL2 in the guest is stored in vcpu->arch.cptr_el2, set TSM there during initialisation. It will be cleared in __deactivate_traps_common() by virtue of not being set in CPTR_EL2_DEFAULT. For both VHE and nVHE cases handle SCTLR_EL2.EnTPIDR2 in the shared __active_traps_common() and __deactivate_traps_common(), there is no existing dynamic management of SCTLR_EL2. Signed-off-by: Mark Brown --- arch/arm64/kvm/hyp/nvhe/switch.c | 30 ++++++++++++++++++++++++++++++ arch/arm64/kvm/hyp/vhe/switch.c | 10 +++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 6410d21d8695..184bf6bd79b9 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -47,10 +47,25 @@ static void __activate_traps(struct kvm_vcpu *vcpu) val |= CPTR_EL2_TFP | CPTR_EL2_TZ; __activate_traps_fpsimd32(vcpu); } + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME)) + val |= CPTR_EL2_TSM; write_sysreg(val, cptr_el2); write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) && + cpus_have_final_cap(ARM64_HAS_FGT)) { + val = read_sysreg_s(SYS_HFGRTR_EL2); + val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK | + HFGxTR_EL2_nSMPRI_EL1_MASK); + write_sysreg_s(val, SYS_HFGRTR_EL2); + + val = read_sysreg_s(SYS_HFGWTR_EL2); + val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK | + HFGxTR_EL2_nSMPRI_EL1_MASK); + write_sysreg_s(val, SYS_HFGWTR_EL2); + } + if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; @@ -94,9 +109,24 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) && + cpus_have_final_cap(ARM64_HAS_FGT)) { + u64 val; + + val = read_sysreg_s(SYS_HFGRTR_EL2); + val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK; + write_sysreg_s(val, SYS_HFGRTR_EL2); + + val = read_sysreg_s(SYS_HFGWTR_EL2); + val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK; + write_sysreg_s(val, SYS_HFGWTR_EL2); + } + cptr = CPTR_EL2_DEFAULT; if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED)) cptr |= CPTR_EL2_TZ; + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME)) + cptr &= ~CPTR_EL2_TSM; write_sysreg(cptr, cptr_el2); write_sysreg(__kvm_hyp_host_vector, vbar_el2); diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 11d053fdd604..f5630579f577 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -38,7 +38,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu) val = read_sysreg(cpacr_el1); val |= CPACR_EL1_TTA; - val &= ~CPACR_EL1_ZEN; + val &= ~(CPACR_EL1_ZEN | CPACR_EL1_SMEN); /* * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to @@ -59,6 +59,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu) __activate_traps_fpsimd32(vcpu); } + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME)) + write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2, + sctlr_el2); + write_sysreg(val, cpacr_el1); write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); @@ -80,6 +84,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) */ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); + if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME)) + write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2, + sctlr_el2); + write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); write_sysreg(vectors, vbar_el1); }