From patchwork Thu Aug 1 12:06:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13750393 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A00CFC3DA4A for ; Thu, 1 Aug 2024 12:58:59 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 266BF6B00B0; Thu, 1 Aug 2024 08:58:59 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1ED476B00B2; Thu, 1 Aug 2024 08:58:59 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 018006B00B3; Thu, 1 Aug 2024 08:58:58 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id CC1566B00B0 for ; Thu, 1 Aug 2024 08:58:58 -0400 (EDT) Received: from smtpin09.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 8DBCFA6BF3 for ; Thu, 1 Aug 2024 12:58:58 +0000 (UTC) X-FDA: 82403681556.09.5DFCB01 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf27.hostedemail.com (Postfix) with ESMTP id ACE8340005 for ; Thu, 1 Aug 2024 12:58:56 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=Lc2VtrSa; dmarc=pass (policy=none) header.from=kernel.org; spf=pass (imf27.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722517131; a=rsa-sha256; cv=none; b=wQKPkZkXIrd8bcAt8INpXoL1jXDZ7+kovJzj4XOtkO1bhSbtCxWwYWyQIAf4LJz5jg3fzv ofAZtpJqKKJ/SLTqqf1RBcNcFiS9134kmVI1jPkSX10y2tJxA//DFHUAk3ca0K8XcMy7Gi N1KAo/LEPudLagDyGAxF161LTeIHtF4= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=Lc2VtrSa; dmarc=pass (policy=none) header.from=kernel.org; spf=pass (imf27.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722517131; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=MB9ShdJ//AJKp7KnVC+clON/hX2YB6kjPPmxeq9uxO4=; b=qcGs4nYP2eFq4lV9iNNfmsI/ObsKi3o2lOzhgiDXz5g78xZYl1RWx5oWQ5brzHYsSFKYk3 KlTMRB5zzLrZUSsReJvIh+CntKXAezwr/F806l0zXzZcf3E4OE6qOqR3b2hCOrgCM6FKoM 3U8sgCLE1dT0+cwtmRzVluZWOwxswb0= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id EB5776285D; Thu, 1 Aug 2024 12:58:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 46D56C4AF11; Thu, 1 Aug 2024 12:58:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722517135; bh=xossS2HqrkBDMWtdlnAZqELtip1cq4iphga412zWfzk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Lc2VtrSaehDUjYoWf6PiYqYXnkQ2kQkoazm1+3KZubpXUot4ouPvk1P0FJa7crvjk OuEEX/+dGLXLPyD97VPDi78n7Bc85R0iDJtNEjDgdGTsTXZUu6JZhCq8O8ZXTIJhSq vM1R0ZusO3AzfHvtCDIlCkAGmgYJWGP74hDad3EzyE4n+fR0msuI0NEdfAeGWub7/d ciCU57Y5d+cWjf6OKVUbKxy1FjO2/NBUPoSp/6Ez8yKcok890u6Y4lUL7l4oz6+w+G lk0Z+0ySarwCOucvlnjrL3j7W5vHx4KlQBpXsUnCMKfUsX2SWQhgEdz/j61dGPS4j3 cfBMN+01zQnNw== From: Mark Brown Date: Thu, 01 Aug 2024 13:06:41 +0100 Subject: [PATCH v10 14/40] KVM: arm64: Manage GCS access and registers for guests MIME-Version: 1.0 Message-Id: <20240801-arm64-gcs-v10-14-699e2bd2190b@kernel.org> References: <20240801-arm64-gcs-v10-0-699e2bd2190b@kernel.org> In-Reply-To: <20240801-arm64-gcs-v10-0-699e2bd2190b@kernel.org> To: Catalin Marinas , Will Deacon , Jonathan Corbet , Andrew Morton , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Arnd Bergmann , Oleg Nesterov , Eric Biederman , Shuah Khan , "Rick P. Edgecombe" , Deepak Gupta , Ard Biesheuvel , Szabolcs Nagy , Kees Cook Cc: "H.J. Lu" , Paul Walmsley , Palmer Dabbelt , Albert Ou , Florian Weimer , Christian Brauner , Thiago Jung Bauermann , Ross Burton , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Brown X-Mailer: b4 0.15-dev-37811 X-Developer-Signature: v=1; a=openpgp-sha256; l=7311; i=broonie@kernel.org; h=from:subject:message-id; bh=xossS2HqrkBDMWtdlnAZqELtip1cq4iphga412zWfzk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmq4YQ/T+BB+Z93oQBSjZAywi/P+Nx8EVKjuUaS715 C9vL/8SJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZquGEAAKCRAk1otyXVSH0Ji/B/ 9Gg1j9In0idh/ZRjEUDTjt8HHhczhLSqbVnta3Nad46+7NVICzVQiIH0haNI8X86B71oW7+8QeS2iS dBH9gx1Bz1Br5B4oTkJyCdeSdqge4aMj1GtbA6VItWCtZVWUZt7T0a6KlKufaTLzV5hAqN3P7jH/v0 pAdU7FxnO5fKHLUOYPsYl1Kca9qL8ENLHmBH/CFhgC1srsTe/akQ4Qv3R0QTDYHNu1yh9Jwg0q/EID cqpayNozEMBaZsM4rl1/LjpKDktWRm+553aFHHp7Bd9JUi/akSUl+YN3Wca7UtEWpKMEzJdTReQebq IkiBtDNAzSHU3CRtznbt1BXVC/4Tm+ X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Rspam-User: X-Rspamd-Queue-Id: ACE8340005 X-Rspamd-Server: rspam01 X-Stat-Signature: soybcgf4w9thzwhawjxinob3hebie6mr X-HE-Tag: 1722517136-538227 X-HE-Meta: U2FsdGVkX1/QNDgku3iEF09APzhBrX3Ft8QSrUvdLsdFgVgVBtAgG8TcBaO9XK4+9HeYNan/sxPCWPuXImvQi6m0Oe2moJeaoEIvv6lUIk6zUZ4I3hA8xOyu0IWX75CtlvE2BXyPcy5I/izSOUjpqczn0vIf282QT2xfF6HeJbkD7OTyhiveYZwwg/khmgCeii1nfseVxSWx3s+yck0EiCM8K/3VrhjyBnHlnuVKWx3H0HoiFgGdqzh3vIu5fd75e3kKuwkCuDVS7SxZIyMhFWYf3GCTqvOYXFzSl8VJ9JDYucroYHE6YNLwmLbvB5YJIRstQbdo/7FZEmjafSQTZH+0mwENovEor7xpdoXmqEQoMaz/Z8T+btnFkmQRuqTDVQOrBUAilAi/A2lPwKr8LFLSSjnryFo0kMHYEf7R/XQ6ZqNCbdpoGQqcdiju58jahCnYrIo2egR0Dsswy2IKO68kOpHOw04MYuvmofiiOBvptTT8umHdXlv0jPvxe7aAUUUfrPJXij7n33ydeRmrCnb9Y8CgXJ30FkDqmgIHrEO0wujyxAuTk6893a08SM6uT71Y+k4lcfJFi7yS6OHkqIVDzjGzktuwyZPrIeiKYg/HCKBIdDlTVB1DqIxOCxoWXw4/S6ONAx/kz8S4J5QFnrvWmyRcdnSpMIPC3r99VFxyLXIFIto9QGtJip7rE9jmHfNWzb+/tmo+J2Sqav5plqDDAJzHemUaUmLo+NmPQ0UbgWUqLTNngVpYQbEbfXFqSeuOv6pzR+KbmnK50mnWrLyg82V5kwdEBrq2atf8oWE+TspPUCdDzhUujlzZSieelHS3pGywWGfyIFo08AluE+xTA0Cc+YzHkIIbbpDrW2rlIAjoEQV/7V7Qav5Kh9ctCMnFdZeV6hmmSVv6uxTwgAoUnTPkEsXaN77RE3NhAA7uYdfwOx88GXHbgLQbJW/629NTdVulxl6wegRuky+ 0iosQIKg r9s4AF93fwNvHsZuBX+ulQO9X/mWK86UqvyiyZH2CWhvY56OTpnnzq4GOmvnf+gFas3hOAch0URfQTFXyRyRWpSWgM2fq37oL19RkKTvC/3C6OIzDIVQFUuh+3BJ/3xeBB4SFtrZQWfl99J+8k24WSKOuEdVmT26B0vgHSbSfoRhFg0PvbNuNCACx8h57H8dhKWRfXRhieCbkn0+xOLo4Qc2CVCsW2iddepM4vb9B7B1jqibRRbx7ZervUZ4AoiwBAQ0+4ex4Z/H3pHJLIImJLq6fQDd7wGpKc5HGaIcIyEecH9n4AedsZjs7fZ2tT8PDmyN6 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: GCS introduces a number of system registers for EL1 and EL0, on systems with GCS we need to context switch them and expose them to VMMs to allow guests to use GCS. In order to allow guests to use GCS we also need to configure HCRX_EL2.GCSEn, if this is not set GCS instructions will be noops and CHKFEAT will report GCS as disabled. Also enable fine grained traps for access to the GCS registers by guests which do not have the feature enabled. Signed-off-by: Mark Brown --- arch/arm64/include/asm/kvm_host.h | 8 +++++ arch/arm64/include/asm/vncr_mapping.h | 2 ++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 49 ++++++++++++++++++++++++------ arch/arm64/kvm/sys_regs.c | 12 ++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index a33f5996ca9f..5818e4a1c2d1 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -446,6 +446,10 @@ enum vcpu_sysreg { GCR_EL1, /* Tag Control Register */ TFSRE0_EL1, /* Tag Fault Status Register (EL0) */ + /* Guarded Control Stack registers */ + GCSCRE0_EL1, /* Guarded Control Stack Control (EL0) */ + GCSPR_EL0, /* Guarded Control Stack Pointer (EL0) */ + /* 32bit specific registers. */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ @@ -517,6 +521,10 @@ enum vcpu_sysreg { VNCR(PIR_EL1), /* Permission Indirection Register 1 (EL1) */ VNCR(PIRE0_EL1), /* Permission Indirection Register 0 (EL1) */ + /* Guarded Control Stack registers */ + VNCR(GCSPR_EL1), /* Guarded Control Stack Pointer (EL1) */ + VNCR(GCSCR_EL1), /* Guarded Control Stack Control (EL1) */ + VNCR(HFGRTR_EL2), VNCR(HFGWTR_EL2), VNCR(HFGITR_EL2), diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h index df2c47c55972..5e83e6f579fd 100644 --- a/arch/arm64/include/asm/vncr_mapping.h +++ b/arch/arm64/include/asm/vncr_mapping.h @@ -88,6 +88,8 @@ #define VNCR_PMSIRR_EL1 0x840 #define VNCR_PMSLATFR_EL1 0x848 #define VNCR_TRFCR_EL1 0x880 +#define VNCR_GCSPR_EL1 0x8C0 +#define VNCR_GCSCR_EL1 0x8D0 #define VNCR_MPAM1_EL1 0x900 #define VNCR_MPAMHCR_EL2 0x930 #define VNCR_MPAMVPMV_EL2 0x938 diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h index 4c0fdabaf8ae..ac29352e225a 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h @@ -16,6 +16,27 @@ #include #include +static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; + + if (!vcpu) + vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); + + return vcpu; +} + +static inline bool ctxt_has_gcs(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu; + + if (!cpus_have_final_cap(ARM64_HAS_GCS)) + return false; + + vcpu = ctxt_to_vcpu(ctxt); + return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64PFR1_EL1, GCS, IMP); +} + static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, MDSCR_EL1) = read_sysreg(mdscr_el1); @@ -25,16 +46,10 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, TPIDR_EL0) = read_sysreg(tpidr_el0); ctxt_sys_reg(ctxt, TPIDRRO_EL0) = read_sysreg(tpidrro_el0); -} - -static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) -{ - struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; - - if (!vcpu) - vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); - - return vcpu; + if (ctxt_has_gcs(ctxt)) { + ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0); + ctxt_sys_reg(ctxt, GCSCRE0_EL1) = read_sysreg_s(SYS_GCSCRE0_EL1); + } } static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) @@ -79,6 +94,10 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) if (ctxt_has_s1pie(ctxt)) { ctxt_sys_reg(ctxt, PIR_EL1) = read_sysreg_el1(SYS_PIR); ctxt_sys_reg(ctxt, PIRE0_EL1) = read_sysreg_el1(SYS_PIRE0); + if (ctxt_has_gcs(ctxt)) { + ctxt_sys_reg(ctxt, GCSPR_EL1) = read_sysreg_el1(SYS_GCSPR); + ctxt_sys_reg(ctxt, GCSCR_EL1) = read_sysreg_el1(SYS_GCSCR); + } } } ctxt_sys_reg(ctxt, ESR_EL1) = read_sysreg_el1(SYS_ESR); @@ -126,6 +145,11 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) { write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL0), tpidr_el0); write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0), tpidrro_el0); + if (ctxt_has_gcs(ctxt)) { + write_sysreg_s(ctxt_sys_reg(ctxt, GCSPR_EL0), SYS_GCSPR_EL0); + write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1), + SYS_GCSCRE0_EL1); + } } static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) @@ -157,6 +181,11 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) if (ctxt_has_s1pie(ctxt)) { write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR); write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0); + + if (ctxt_has_gcs(ctxt)) { + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1), SYS_GCSPR); + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1), SYS_GCSCR); + } } } write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL1), SYS_ESR); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c90324060436..ac98d3237130 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2446,6 +2446,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { PTRAUTH_KEY(APDB), PTRAUTH_KEY(APGA), + { SYS_DESC(SYS_GCSCR_EL1), NULL, reset_val, GCSCR_EL1, 0 }, + { SYS_DESC(SYS_GCSPR_EL1), NULL, reset_unknown, GCSPR_EL1 }, + { SYS_DESC(SYS_GCSCRE0_EL1), NULL, reset_val, GCSCRE0_EL1, 0 }, + { SYS_DESC(SYS_SPSR_EL1), access_spsr}, { SYS_DESC(SYS_ELR_EL1), access_elr}, @@ -2535,6 +2539,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { CTR_EL0_IDC_MASK | CTR_EL0_DminLine_MASK | CTR_EL0_IminLine_MASK), + { SYS_DESC(SYS_GCSPR_EL0), NULL, reset_unknown, GCSPR_EL0 }, { SYS_DESC(SYS_SVCR), undef_access }, { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr, @@ -4560,6 +4565,9 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu) if (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP)) vcpu->arch.hcrx_el2 |= HCRX_EL2_TCR2En; + + if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP)) + vcpu->arch.hcrx_el2 |= HCRX_EL2_GCSEn; } if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags)) @@ -4604,6 +4612,10 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu) kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1); + if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP)) + kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nGCS_EL0 | + HFGxTR_EL2_nGCS_EL1); + if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP)) kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 | HAFGRTR_EL2_RES1);