linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: James Morse <james.morse@arm.com>
To: Marc Zyngier <maz@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	kvm@vger.kernel.org, Suzuki K Poulose <suzuki.poulose@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Julien Thierry <julien.thierry.kdev@gmail.com>,
	Will Deacon <will@kernel.org>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 4/5] arm64: KVM: Prevent speculative S1 PTW when restoring vcpu context
Date: Thu, 3 Oct 2019 12:09:30 +0100	[thread overview]
Message-ID: <0d52783d-2cff-0d2e-8421-74f815b90c47@arm.com> (raw)
In-Reply-To: <20190925111941.88103-5-maz@kernel.org>

Hi Marc,

On 25/09/2019 12:19, Marc Zyngier wrote:
> When handling erratum 1319367, we must ensure that the page table
> walker cannot parse the S1 page tables while the guest is in an
> inconsistent state. This is done as follows:
> 
> On guest entry:
> - TCR_EL1.EPD{0,1} are set, ensuring that no PTW can occur
> - all system registers are restored, except for TCR_EL1 and SCTLR_EL1
> - stage-2 is restored
> - SCTLR_EL1 and TCR_EL1 are restored
> 
> On guest exit:
> - SCTLR_EL1.M and TCR_EL1.EPD{0,1} are set, ensuring that no PTW can occur
> - stage-2 is disabled
> - All host system registers are restored

> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index e6adb90c12ae..4df47d013bec 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -156,6 +170,23 @@ static void __hyp_text __deactivate_traps_nvhe(void)
>  {
>  	u64 mdcr_el2 = read_sysreg(mdcr_el2);
>  
> +	if (cpus_have_const_cap(ARM64_WORKAROUND_1319367)) {
> +		u64 val;
> +
> +		/*
> +		 * Set the TCR and SCTLR registers in the exact opposite
> +		 * sequence as __activate_traps_nvhe (first prevent walks,
> +		 * then force the MMU on). A generous sprinkling of isb()
> +		 * ensure that things happen in this exact order.
> +		 */
> +		val = read_sysreg_el1(SYS_TCR);
> +		write_sysreg_el1(val | TCR_EPD1_MASK | TCR_EPD0_MASK, SYS_TCR);
> +		isb();
> +		val = read_sysreg_el1(SYS_SCTLR);
> +		write_sysreg_el1(val | SCTLR_ELx_M, SYS_SCTLR);
> +		isb();
> +	}

We are exiting the guest, and heading back to the host.
This change forces stage-1 off. Stage-2 is still enabled, but its about to be disabled and
have the host VMID restore in __deactivate_vm(). All good so far.

Then we hit __sysreg_restore_state_nvhe() for the host, which calls
__sysreg_restore_el1_state()...


> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index 7ddbc849b580..adabdceacc10 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -117,12 +117,22 @@ static void __hyp_text __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
>  {
>  	write_sysreg(ctxt->sys_regs[MPIDR_EL1],		vmpidr_el2);
>  	write_sysreg(ctxt->sys_regs[CSSELR_EL1],	csselr_el1);
> -	write_sysreg_el1(ctxt->sys_regs[SCTLR_EL1],	SYS_SCTLR);
> +
> +	/* Must only be done for guest registers, hence the context test */
> +	if (cpus_have_const_cap(ARM64_WORKAROUND_1319367) &&
> +	    !ctxt->__hyp_running_vcpu) {
> +		write_sysreg_el1(ctxt->sys_regs[TCR_EL1] |
> +				 TCR_EPD1_MASK | TCR_EPD0_MASK,	SYS_TCR);
> +		isb();
> +	} else {

... which will come in here.

> +		write_sysreg_el1(ctxt->sys_regs[SCTLR_EL1],	SYS_SCTLR);
> +		write_sysreg_el1(ctxt->sys_regs[TCR_EL1],	SYS_TCR);

This reverses what we did in __deactivate_traps_nvhe(), but we haven't restored the host
TTBRs yet. I don't think the vttbr_el2 write has been sync'd either.

A speculative AT at this point could see the TCR EPDx bits clear, but the guest's TTBR
values. It may also see the guest-VMID.


I think the change to this function needs splitting up. Restore of guest state needs to be
as you have it here, before the guest TTBRs are written.

Restore of the host state needs to only clear the EPDx bits after the TTBRs are written,
and sync'd.


Assuming I'm making sense ... with that:
Reviewed-by: James Morse <james.morse@arm.com>

for the series.


> +	}
> +
>  	write_sysreg(ctxt->sys_regs[ACTLR_EL1],		actlr_el1);
>  	write_sysreg_el1(ctxt->sys_regs[CPACR_EL1],	SYS_CPACR);
>  	write_sysreg_el1(ctxt->sys_regs[TTBR0_EL1],	SYS_TTBR0);
>  	write_sysreg_el1(ctxt->sys_regs[TTBR1_EL1],	SYS_TTBR1);
> -	write_sysreg_el1(ctxt->sys_regs[TCR_EL1],	SYS_TCR);
>  	write_sysreg_el1(ctxt->sys_regs[ESR_EL1],	SYS_ESR);
>  	write_sysreg_el1(ctxt->sys_regs[AFSR0_EL1],	SYS_AFSR0);
>  	write_sysreg_el1(ctxt->sys_regs[AFSR1_EL1],	SYS_AFSR1);


Thanks,

James

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-10-03 11:09 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-25 11:19 [PATCH 0/5] arm64: KVM: Add workaround for errata 1319367 and 1319537 Marc Zyngier
2019-09-25 11:19 ` [PATCH 1/5] arm64: Add ARM64_WORKAROUND_1319367 for all A57 and A72 versions Marc Zyngier
2019-09-27  8:33   ` Suzuki K Poulose
2019-09-27  9:03   ` Catalin Marinas
2019-09-25 11:19 ` [PATCH 2/5] arm64: KVM: Reorder system register restoration and stage-2 activation Marc Zyngier
2019-09-25 11:19 ` [PATCH 3/5] arm64: KVM: Disable EL1 PTW when invalidating S2 TLBs Marc Zyngier
2019-10-03 11:10   ` James Morse
2019-09-25 11:19 ` [PATCH 4/5] arm64: KVM: Prevent speculative S1 PTW when restoring vcpu context Marc Zyngier
2019-10-03 11:09   ` James Morse [this message]
2019-09-25 11:19 ` [PATCH 5/5] arm64: Enable and document ARM errata 1319367 and 1319537 Marc Zyngier
2019-09-27  9:03   ` Catalin Marinas
2019-10-03 11:11   ` James Morse
2019-10-07  9:31     ` Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0d52783d-2cff-0d2e-8421-74f815b90c47@arm.com \
    --to=james.morse@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=julien.thierry.kdev@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).