From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5396EC433F5 for ; Tue, 25 Jan 2022 16:53:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Subject:Cc:To:From:Message-ID:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=XwvN/T9TCPUhL1buNfTMxqglaMxeefQDtTWuf8tjMW4=; b=kt+DDxM3xjnSWF ZMk5r9R8XDS1yjb3Bn5OurJORnIlypoC62hMu1icJVpoCqFHpLPY28Y2oLNFjdEYNyhqShxBFy3U/ YGd1KKTk+8eY34kpuHjZB7jH7JZUin1VssBig7Qer+AJ6hF4MwcD+gPdKqtIpniaTE6pk7bAKP2MT X0QXLSVPKw8o8fixVMJn5v0mpzLqUg/82KyJEtnhWQa/EmlSQNVjPhp6epGBKX6+JCkfGN31WOcvs TUZ7tqbjGFxYe5xLrzFtAev313qdDBpDn//rXuUgfA6nef7mvUW7R/CXCtBM031s191eWFFEqjDdY TVj3qqMTYPYdvKs+5ttg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP2w-008nV9-BA; Tue, 25 Jan 2022 16:51:54 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP2r-008nUM-At for linux-arm-kernel@lists.infradead.org; Tue, 25 Jan 2022 16:51:51 +0000 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 dfw.source.kernel.org (Postfix) with ESMTPS id CEB4560B3A; Tue, 25 Jan 2022 16:51:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 244CAC340E6; Tue, 25 Jan 2022 16:51:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643129508; bh=ba6hZXXKEBXmXsK6VF/eKcgxP0IeTJCJUtv09CRILFw=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=bDUUDgnyS81xYtrpJlQTunvEtxpv8qpQV9E2CVBZnCI2a1lpdFKyS9ItUb5s+ay23 7DVRXADQSqr2raQEArU1lYLOuUH9ruTyH+srlPFKymIvSHi5qWIThf4oIQC/U+GqYy 6JgNsEyajzQK9fcTm7yfULVMas3FSaaddz/FYkPQWIRxjt4peUaFjdcHBgl6uXvK65 rISL+xRt21uK72F4vz8rx/qMiSJYVx2AhXeQnTspeRu2NQcC1hpcUjAG6rjEKzMerE PEkrQ1EAs0EO0iOKGmoPb0hHXsYkVx2wdf30S1M8nbLrKMhRG1x14d64Yvn/D8llcD r88HjGhLKC1hw== Received: from sofa.misterjones.org ([185.219.108.64] helo=why.misterjones.org) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nCP2o-002yKd-5T; Tue, 25 Jan 2022 16:51:46 +0000 Date: Tue, 25 Jan 2022 16:51:45 +0000 Message-ID: <87mtjj7o7y.wl-maz@kernel.org> From: Marc Zyngier To: James Morse Cc: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Catalin Marinas , Will Deacon , Alexandru Elisei , Suzuki K Poulose , Anshuman Khandual Subject: Re: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and PAC trap errata In-Reply-To: <20220125153803.549084-5-james.morse@arm.com> References: <20220125153803.549084-1-james.morse@arm.com> <20220125153803.549084-5-james.morse@arm.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/27.1 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: james.morse@arm.com, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will@kernel.org, alexandru.elisei@arm.com, suzuki.poulose@arm.com, anshuman.khandual@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220125_085149_491539_26DBABDC X-CRM114-Status: GOOD ( 49.05 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi James, Thanks for this. I guess. On Tue, 25 Jan 2022 15:38:03 +0000, James Morse wrote: > > Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when > single-stepping authenticated ERET instructions. A single step is > expected, but a pointer authentication trap is taken instead. The > erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow > EL1 to cause a return to EL2 with a guest controlled ELR_EL2. > > Because the conditions require an ERET into active-not-pending state, > this is only a problem for the EL2 when EL2 is stepping EL1. In this case > the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be > restored. Urgh. That's pretty nasty :-(. > > Cc: stable@vger.kernel.org # ${GITHASHHERE}: arm64: Add Cortex-A510 CPU part definition > Cc: stable@vger.kernel.org > Signed-off-by: James Morse > --- > Documentation/arm64/silicon-errata.rst | 2 ++ > arch/arm64/Kconfig | 16 ++++++++++++++++ > arch/arm64/kernel/cpu_errata.c | 8 ++++++++ > arch/arm64/kvm/hyp/include/hyp/switch.h | 24 +++++++++++++++++++++--- > arch/arm64/tools/cpucaps | 1 + > 5 files changed, 48 insertions(+), 3 deletions(-) > > diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst > index 5342e895fb60..ac1ae34564c9 100644 > --- a/Documentation/arm64/silicon-errata.rst > +++ b/Documentation/arm64/silicon-errata.rst > @@ -92,6 +92,8 @@ stable kernels. > +----------------+-----------------+-----------------+-----------------------------+ > | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | > +----------------+-----------------+-----------------+-----------------------------+ > +| ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 | > ++----------------+-----------------+-----------------+-----------------------------+ > | ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | > +----------------+-----------------+-----------------+-----------------------------+ > | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > index 6978140edfa4..02b542ec18c8 100644 > --- a/arch/arm64/Kconfig > +++ b/arch/arm64/Kconfig > @@ -670,6 +670,22 @@ config ARM64_ERRATUM_1508412 > config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE > bool > > +config ARM64_ERRATUM_2077057 > + bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2" > + help > + This option adds the workaround for ARM Cortex-A510 erratum 2077057. > + Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is > + expected, but a Pointer Authentication trap is taken instead. The > + erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow > + EL1 to cause a return to EL2 with a guest controlled ELR_EL2. > + > + This can only happen when EL2 is stepping EL1. > + > + When these conditions occur, the SPSR_EL2 value is unchanged from the > + previous guest entry, and can be restored from the in-memory copy. > + > + If unsure, say Y. > + > config ARM64_ERRATUM_2119858 > bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode" > default y > diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c > index 9e1c1aef9ebd..04a014c63251 100644 > --- a/arch/arm64/kernel/cpu_errata.c > +++ b/arch/arm64/kernel/cpu_errata.c > @@ -597,6 +597,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { > .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, > CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus), > }, > +#endif > +#ifdef CONFIG_ARM64_ERRATUM_2077057 > + { > + .desc = "ARM erratum 2077057", > + .capability = ARM64_WORKAROUND_2077057, > + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, > + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2), > + }, > #endif > { > } > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h > index 331dd10821df..93bf140cc972 100644 > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h > @@ -409,6 +409,8 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code) > */ > static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) > { > + u8 esr_ec; > + > /* > * Save PSTATE early so that we can evaluate the vcpu mode > * early on. > @@ -421,13 +423,13 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) > */ > early_exit_filter(vcpu, exit_code); > > - if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) > + if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) { > vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR); > + esr_ec = kvm_vcpu_trap_get_class(vcpu); > + } > > if (ARM_SERROR_PENDING(*exit_code) && > ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) { > - u8 esr_ec = kvm_vcpu_trap_get_class(vcpu); > - > /* > * HVC already have an adjusted PC, which we need to > * correct in order to return to after having injected > @@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) > write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR); > } > > + /* > + * Check for the conditions of Cortex-A510's #2077057. When these occur > + * SPSR_EL2 can't be trusted, but isn't needed either as it is > + * unchanged from the value in vcpu_gp_regs(vcpu)->pstate. > + * Did we just take a PAC exception when a step exception was expected? > + */ > + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) && nit: we can drop this IS_ENABLED()... > + cpus_have_const_cap(ARM64_WORKAROUND_2077057) && and make this a final cap. Being a ARM64_CPUCAP_LOCAL_CPU_ERRATUM, we won't accept late CPUs on a system that wasn't affected until then. > + ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ && > + esr_ec == ESR_ELx_EC_PAC && > + vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { > + /* Active-not-pending? */ > + if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS) > + write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR); Err... Isn't this way too late? The function starts with: vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR); which is just another way to write: *vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR); By that time, the vcpu's PSTATE is terminally corrupted. I think you need to hoist this workaround way up, before we call into early_exit_filter() as it will assume that the guest pstate is correct (this is used by both pKVM and the NV code). Something like this (untested): diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 93bf140cc972..a8a1502db237 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -402,6 +402,26 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code) return false; } +static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu, + u64 *exit_code) +{ + /* + * Check for the conditions of Cortex-A510's #2077057. When these occur + * SPSR_EL2 can't be trusted, but isn't needed either as it is + * unchanged from the value in vcpu_gp_regs(vcpu)->pstate. + * Did we just take a PAC exception when a step exception (being in the + * Active-not-pending state) was expected? + */ + if (cpus_have_final_cap(ARM64_WORKAROUND_2077057) && + ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ && + kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_PAC && + vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && + *vcpu_cpsr(vcpu) & DBG_SPSR_SS) + write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR); + + *vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR); +} + /* * Return true when we were able to fixup the guest exit and should return to * the guest, false when we should restore the host state and return to the @@ -415,7 +435,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) * Save PSTATE early so that we can evaluate the vcpu mode * early on. */ - vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR); + synchronize_vcpu_pstate(vcpu, exit_code); /* * Check whether we want to repaint the state one way or @@ -442,22 +462,6 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR); } - /* - * Check for the conditions of Cortex-A510's #2077057. When these occur - * SPSR_EL2 can't be trusted, but isn't needed either as it is - * unchanged from the value in vcpu_gp_regs(vcpu)->pstate. - * Did we just take a PAC exception when a step exception was expected? - */ - if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) && - cpus_have_const_cap(ARM64_WORKAROUND_2077057) && - ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ && - esr_ec == ESR_ELx_EC_PAC && - vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { - /* Active-not-pending? */ - if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS) - write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR); - } - /* * We're using the raw exception code in order to only process * the trap if no SError is pending. We will come back to the > + } > + > /* > * We're using the raw exception code in order to only process > * the trap if no SError is pending. We will come back to the > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps > index 870c39537dd0..2e7cd3fecca6 100644 > --- a/arch/arm64/tools/cpucaps > +++ b/arch/arm64/tools/cpucaps > @@ -55,6 +55,7 @@ WORKAROUND_1418040 > WORKAROUND_1463225 > WORKAROUND_1508412 > WORKAROUND_1542419 > +WORKAROUND_2077057 > WORKAROUND_TRBE_OVERWRITE_FILL_MODE > WORKAROUND_TSB_FLUSH_FAILURE > WORKAROUND_TRBE_WRITE_OUT_OF_RANGE Other than that, I'm happy to take the series as a whole ASAP, if only for the two pretty embarrassing bug fixes. If you can respin it shortly and address the comments above, I'd like it into -rc2. Thanks, M. -- Without deviation from the norm, progress is not possible. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel