linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Will Deacon <will@kernel.org>
To: kvmarm@lists.cs.columbia.edu
Cc: Will Deacon <will@kernel.org>, Ard Biesheuvel <ardb@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Catalin Marinas <catalin.marinas@arm.com>,
	James Morse <james.morse@arm.com>,
	Chao Peng <chao.p.peng@linux.intel.com>,
	Quentin Perret <qperret@google.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Michael Roth <michael.roth@amd.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Fuad Tabba <tabba@google.com>, Oliver Upton <oupton@google.com>,
	Marc Zyngier <maz@kernel.org>,
	kernel-team@android.com, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 82/89] KVM: arm64: Support TLB invalidation in guest context
Date: Thu, 19 May 2022 14:41:57 +0100	[thread overview]
Message-ID: <20220519134204.5379-83-will@kernel.org> (raw)
In-Reply-To: <20220519134204.5379-1-will@kernel.org>

Typically, TLB invalidation of guest stage-2 mappings using nVHE is
performed by a hypercall originating from the host. For the invalidation
instruction to be effective, therefore, __tlb_switch_to_{guest,host}()
swizzle the active stage-2 context around the TLBI instruction.

With guest-to-host memory sharing and unsharing hypercalls originating
from the guest under pKVM, there is now a need to support both guest
and host VMID invalidations issued from guest context.

Replace the __tlb_switch_to_{guest,host}() functions with a more general
{enter,exit}_vmid_context() implementation which supports being invoked
from guest context and acts as a no-op if the target context matches the
running context.

Signed-off-by: Will Deacon <will@kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/tlb.c | 96 ++++++++++++++++++++++++++++-------
 1 file changed, 78 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c
index d296d617f589..3f5601176fab 100644
--- a/arch/arm64/kvm/hyp/nvhe/tlb.c
+++ b/arch/arm64/kvm/hyp/nvhe/tlb.c
@@ -11,26 +11,62 @@
 #include <nvhe/mem_protect.h>
 
 struct tlb_inv_context {
-	u64		tcr;
+	struct kvm_s2_mmu	*mmu;
+	u64			tcr;
+	u64			sctlr;
 };
 
-static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
-				  struct tlb_inv_context *cxt)
+static void enter_vmid_context(struct kvm_s2_mmu *mmu,
+			       struct tlb_inv_context *cxt)
 {
+	struct kvm_s2_mmu *host_mmu = &host_kvm.arch.mmu;
+	struct kvm_cpu_context *host_ctxt;
+	struct kvm_vcpu *vcpu;
+
+	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	vcpu = host_ctxt->__hyp_running_vcpu;
+	cxt->mmu = NULL;
+
+	/*
+	 * If we're already in the desired context, then there's nothing
+	 * to do.
+	 */
+	if (vcpu) {
+		if (mmu == vcpu->arch.hw_mmu || WARN_ON(mmu != host_mmu))
+			return;
+	} else if (mmu == host_mmu) {
+		return;
+	}
+
+	cxt->mmu = mmu;
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		u64 val;
 
 		/*
 		 * For CPUs that are affected by ARM 1319367, we need to
-		 * avoid a host Stage-1 walk while we have the guest's
-		 * VMID set in the VTTBR in order to invalidate TLBs.
-		 * We're guaranteed that the S1 MMU is enabled, so we can
-		 * simply set the EPD bits to avoid any further TLB fill.
+		 * avoid a Stage-1 walk with the old VMID while we have
+		 * the new VMID set in the VTTBR in order to invalidate TLBs.
+		 * We're guaranteed that the host S1 MMU is enabled, so
+		 * we can simply set the EPD bits to avoid any further
+		 * TLB fill. For guests, we ensure that the S1 MMU is
+		 * temporarily enabled in the next context.
 		 */
 		val = cxt->tcr = read_sysreg_el1(SYS_TCR);
 		val |= TCR_EPD1_MASK | TCR_EPD0_MASK;
 		write_sysreg_el1(val, SYS_TCR);
 		isb();
+
+		if (vcpu) {
+			val = cxt->sctlr = read_sysreg_el1(SYS_SCTLR);
+			if (!(val & SCTLR_ELx_M)) {
+				val |= SCTLR_ELx_M;
+				write_sysreg_el1(val, SYS_SCTLR);
+				isb();
+			}
+		} else {
+			/* The host S1 MMU is always enabled. */
+			cxt->sctlr = SCTLR_ELx_M;
+		}
 	}
 
 	/*
@@ -39,20 +75,44 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
 	 * ensuring that we always have an ISB, but not two ISBs back
 	 * to back.
 	 */
-	__load_stage2(mmu, kern_hyp_va(mmu->arch));
+	if (vcpu)
+		__load_host_stage2();
+	else
+		__load_stage2(mmu, kern_hyp_va(mmu->arch));
+
 	asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT));
 }
 
-static void __tlb_switch_to_host(struct tlb_inv_context *cxt)
+static void exit_vmid_context(struct tlb_inv_context *cxt)
 {
-	__load_host_stage2();
+	struct kvm_s2_mmu *mmu = cxt->mmu;
+	struct kvm_cpu_context *host_ctxt;
+	struct kvm_vcpu *vcpu;
+
+	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	vcpu = host_ctxt->__hyp_running_vcpu;
+
+	if (!mmu)
+		return;
+
+	if (vcpu)
+		__load_stage2(mmu, kern_hyp_va(mmu->arch));
+	else
+		__load_host_stage2();
 
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
-		/* Ensure write of the host VMID */
+		/* Ensure write of the old VMID */
 		isb();
-		/* Restore the host's TCR_EL1 */
+
+		if (!(cxt->sctlr & SCTLR_ELx_M)) {
+			write_sysreg_el1(cxt->sctlr, SYS_SCTLR);
+			isb();
+		}
+
 		write_sysreg_el1(cxt->tcr, SYS_TCR);
 	}
+
+	cxt->mmu = NULL;
 }
 
 void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
@@ -63,7 +123,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
 	dsb(ishst);
 
 	/* Switch to requested VMID */
-	__tlb_switch_to_guest(mmu, &cxt);
+	enter_vmid_context(mmu, &cxt);
 
 	/*
 	 * We could do so much better if we had the VA as well.
@@ -106,7 +166,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
 	if (icache_is_vpipt())
 		icache_inval_all_pou();
 
-	__tlb_switch_to_host(&cxt);
+	exit_vmid_context(&cxt);
 }
 
 void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
@@ -116,13 +176,13 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
 	dsb(ishst);
 
 	/* Switch to requested VMID */
-	__tlb_switch_to_guest(mmu, &cxt);
+	enter_vmid_context(mmu, &cxt);
 
 	__tlbi(vmalls12e1is);
 	dsb(ish);
 	isb();
 
-	__tlb_switch_to_host(&cxt);
+	exit_vmid_context(&cxt);
 }
 
 void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
@@ -130,14 +190,14 @@ void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
 	struct tlb_inv_context cxt;
 
 	/* Switch to requested VMID */
-	__tlb_switch_to_guest(mmu, &cxt);
+	enter_vmid_context(mmu, &cxt);
 
 	__tlbi(vmalle1);
 	asm volatile("ic iallu");
 	dsb(nsh);
 	isb();
 
-	__tlb_switch_to_host(&cxt);
+	exit_vmid_context(&cxt);
 }
 
 void __kvm_flush_vm_context(void)
-- 
2.36.1.124.g0e6072fb45-goog


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

  parent reply	other threads:[~2022-05-19 14:47 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 13:40 [PATCH 00/89] KVM: arm64: Base support for the pKVM hypervisor at EL2 Will Deacon
2022-05-19 13:40 ` [PATCH 01/89] KVM: arm64: Handle all ID registers trapped for a protected VM Will Deacon
2022-05-19 13:40 ` [PATCH 02/89] KVM: arm64: Remove redundant hyp_assert_lock_held() assertions Will Deacon
2022-05-19 13:40 ` [PATCH 03/89] KVM: arm64: Return error from kvm_arch_init_vm() on allocation failure Will Deacon
2022-05-20 15:55   ` Alexandru Elisei
2022-05-31 16:15     ` Will Deacon
2022-05-19 13:40 ` [PATCH 04/89] KVM: arm64: Ignore 'kvm-arm.mode=protected' when using VHE Will Deacon
2022-05-19 13:40 ` [PATCH 05/89] KVM: arm64: Extend comment in has_vhe() Will Deacon
2022-05-19 13:40 ` [PATCH 06/89] KVM: arm64: Drop stale comment Will Deacon
2022-05-19 13:40 ` [PATCH 07/89] KVM: arm64: Move hyp refcount manipulation helpers Will Deacon
2022-05-19 13:40 ` [PATCH 08/89] KVM: arm64: Back hyp_vmemmap for all of memory Will Deacon
2022-05-19 13:40 ` [PATCH 09/89] KVM: arm64: Unify identifiers used to distinguish host and hypervisor Will Deacon
2022-05-19 13:40 ` [PATCH 10/89] KVM: arm64: Implement do_donate() helper for donating memory Will Deacon
2022-05-19 13:40 ` [PATCH 11/89] KVM: arm64: Prevent the donation of no-map pages Will Deacon
2022-05-19 13:40 ` [PATCH 12/89] KVM: arm64: Add helpers to pin memory shared with hyp Will Deacon
2022-05-19 13:40 ` [PATCH 13/89] KVM: arm64: Include asm/kvm_mmu.h in nvhe/mem_protect.h Will Deacon
2022-05-19 13:40 ` [PATCH 14/89] KVM: arm64: Add hyp_spinlock_t static initializer Will Deacon
2022-05-19 13:40 ` [PATCH 15/89] KVM: arm64: Introduce shadow VM state at EL2 Will Deacon
2022-05-19 13:40 ` [PATCH 16/89] KVM: arm64: Instantiate VM shadow data from EL1 Will Deacon
2022-05-19 13:40 ` [PATCH 17/89] KVM: arm64: Make hyp stage-1 refcnt correct on the whole range Will Deacon
2022-05-19 13:40 ` [PATCH 18/89] KVM: arm64: Factor out private range VA allocation Will Deacon
2022-05-19 13:40 ` [PATCH 19/89] KVM: arm64: Add pcpu fixmap infrastructure at EL2 Will Deacon
2022-05-19 13:40 ` [PATCH 20/89] KVM: arm64: Provide I-cache invalidation by VA " Will Deacon
2022-05-19 13:40 ` [PATCH 21/89] KVM: arm64: Allow non-coallescable pages in a hyp_pool Will Deacon
2022-05-19 13:40 ` [PATCH 22/89] KVM: arm64: Add generic hyp_memcache helpers Will Deacon
2022-05-19 13:40 ` [PATCH 23/89] KVM: arm64: Instantiate guest stage-2 page-tables at EL2 Will Deacon
2022-05-19 13:40 ` [PATCH 24/89] KVM: arm64: Return guest memory from EL2 via dedicated teardown memcache Will Deacon
2022-05-19 13:41 ` [PATCH 25/89] KVM: arm64: Add flags to struct hyp_page Will Deacon
2022-05-19 13:41 ` [PATCH 26/89] KVM: arm64: Provide a hypercall for the host to reclaim guest memory Will Deacon
2022-05-19 13:41 ` [PATCH 27/89] KVM: arm64: Extend memory sharing to allow host-to-guest transitions Will Deacon
2022-05-19 13:41 ` [PATCH 28/89] KVM: arm64: Consolidate stage-2 init in one function Will Deacon
2022-05-19 13:41 ` [PATCH 29/89] KVM: arm64: Check for PTE validity when checking for executable/cacheable Will Deacon
2022-05-19 13:41 ` [PATCH 30/89] KVM: arm64: Do not allow memslot changes after first VM run under pKVM Will Deacon
2022-05-19 13:41 ` [PATCH 31/89] KVM: arm64: Disallow dirty logging and RO memslots with pKVM Will Deacon
2022-05-19 13:41 ` [PATCH 32/89] KVM: arm64: Use the shadow vCPU structure in handle___kvm_vcpu_run() Will Deacon
2022-05-19 13:41 ` [PATCH 33/89] KVM: arm64: Handle guest stage-2 page-tables entirely at EL2 Will Deacon
2022-05-20 16:03   ` Alexandru Elisei
2022-05-31 16:45     ` Will Deacon
2022-06-08  1:16       ` Huang, Shaoqin
2022-07-27  9:59         ` Alexandru Elisei
2022-07-28  6:50           ` Huang, Shaoqin
2022-05-19 13:41 ` [PATCH 34/89] KVM: arm64: Don't access kvm_arm_hyp_percpu_base at EL1 Will Deacon
2022-05-19 13:41 ` [PATCH 35/89] KVM: arm64: Unmap kvm_arm_hyp_percpu_base from the host Will Deacon
2022-05-19 13:41 ` [PATCH 36/89] KVM: arm64: Maintain a copy of 'kvm_arm_vmid_bits' at EL2 Will Deacon
2022-05-19 13:41 ` [PATCH 37/89] KVM: arm64: Explicitly map kvm_vgic_global_state " Will Deacon
2022-05-19 13:41 ` [PATCH 38/89] KVM: arm64: Don't map host sections in pkvm Will Deacon
2022-05-19 13:41 ` [PATCH 39/89] KVM: arm64: Extend memory donation to allow host-to-guest transitions Will Deacon
2022-05-19 13:41 ` [PATCH 40/89] KVM: arm64: Split up nvhe/fixed_config.h Will Deacon
2022-05-19 13:41 ` [PATCH 41/89] KVM: arm64: Make vcpu_{read, write}_sys_reg available to HYP code Will Deacon
2022-05-19 13:41 ` [PATCH 42/89] KVM: arm64: Simplify vgic-v3 hypercalls Will Deacon
2022-05-19 13:41 ` [PATCH 43/89] KVM: arm64: Add the {flush, sync}_vgic_state() primitives Will Deacon
2022-05-19 13:41 ` [PATCH 44/89] KVM: arm64: Introduce predicates to check for protected state Will Deacon
2022-05-19 13:41 ` [PATCH 45/89] KVM: arm64: Add the {flush, sync}_timer_state() primitives Will Deacon
2022-05-19 13:41 ` [PATCH 46/89] KVM: arm64: Introduce the pkvm_vcpu_{load, put} hypercalls Will Deacon
2022-05-19 13:41 ` [PATCH 47/89] KVM: arm64: Add current vcpu and shadow_state lookup primitive Will Deacon
2022-05-19 13:41 ` [PATCH 48/89] KVM: arm64: Skip __kvm_adjust_pc() for protected vcpus Will Deacon
2022-05-19 13:41 ` [PATCH 49/89] KVM: arm64: Add hyp per_cpu variable to track current physical cpu number Will Deacon
2022-05-19 13:41 ` [PATCH 50/89] KVM: arm64: Ensure that TLBs and I-cache are private to each vcpu Will Deacon
2022-05-19 13:41 ` [PATCH 51/89] KVM: arm64: Introduce per-EC entry/exit handlers Will Deacon
2022-05-19 13:41 ` [PATCH 52/89] KVM: arm64: Introduce lazy-ish state sync for non-protected VMs Will Deacon
2022-05-19 13:41 ` [PATCH 53/89] KVM: arm64: Lazy host FP save/restore Will Deacon
2022-05-19 13:41 ` [PATCH 54/89] KVM: arm64: Reduce host/shadow vcpu state copying Will Deacon
2022-05-19 13:41 ` [PATCH 55/89] KVM: arm64: Do not pass the vcpu to __pkvm_host_map_guest() Will Deacon
2022-05-19 13:41 ` [PATCH 56/89] KVM: arm64: Check directly whether the vcpu is protected Will Deacon
2022-05-19 13:41 ` [PATCH 57/89] KVM: arm64: Trap debug break and watch from guest Will Deacon
2022-05-19 13:41 ` [PATCH 58/89] KVM: arm64: Restrict protected VM capabilities Will Deacon
2022-05-19 13:41 ` [PATCH 59/89] KVM: arm64: Do not support MTE for protected VMs Will Deacon
2022-05-26 20:08   ` Peter Collingbourne
2022-05-27  7:55     ` Fuad Tabba
2022-06-03  3:00       ` Peter Collingbourne
2022-06-04  8:26         ` Marc Zyngier
2022-06-07  0:20           ` Peter Collingbourne
2022-06-08 18:41             ` Catalin Marinas
2022-06-07  0:42   ` Peter Collingbourne
2022-06-08  7:40     ` Fuad Tabba
2022-06-08 17:39       ` Peter Collingbourne
2022-05-19 13:41 ` [PATCH 60/89] KVM: arm64: Refactor reset_mpidr to extract its computation Will Deacon
2022-05-19 13:41 ` [PATCH 61/89] KVM: arm64: Reset sysregs for protected VMs Will Deacon
2022-05-19 13:41 ` [PATCH 62/89] KVM: arm64: Move pkvm_vcpu_init_traps to shadow vcpu init Will Deacon
2022-05-19 13:41 ` [PATCH 63/89] KVM: arm64: Fix initializing traps in protected mode Will Deacon
2022-05-19 13:41 ` [PATCH 64/89] KVM: arm64: Advertise GICv3 sysreg interface to protected guests Will Deacon
2022-05-19 13:41 ` [PATCH 65/89] KVM: arm64: Force injection of a data abort on NISV MMIO exit Will Deacon
2022-05-19 13:41 ` [PATCH 66/89] KVM: arm64: Donate memory to protected guests Will Deacon
2022-05-19 13:41 ` [PATCH 67/89] KVM: arm64: Add EL2 entry/exit handlers for pKVM guests Will Deacon
2022-05-19 13:41 ` [PATCH 68/89] KVM: arm64: Move vgic state between host and shadow vcpu structures Will Deacon
2022-05-19 13:41 ` [PATCH 69/89] KVM: arm64: Do not update virtual timer state for protected VMs Will Deacon
2022-05-19 13:41 ` [PATCH 70/89] KVM: arm64: Refactor kvm_vcpu_enable_ptrauth() for hyp use Will Deacon
2022-05-19 13:41 ` [PATCH 71/89] KVM: arm64: Initialize shadow vm state at hyp Will Deacon
2022-05-19 13:41 ` [PATCH 72/89] KVM: arm64: Track the SVE state in the shadow vcpu Will Deacon
2022-05-19 13:41 ` [PATCH 73/89] KVM: arm64: Add HVC handling for protected guests at EL2 Will Deacon
2022-05-19 13:41 ` [PATCH 74/89] KVM: arm64: Move pstate reset values to kvm_arm.h Will Deacon
2022-05-19 13:41 ` [PATCH 75/89] KVM: arm64: Move some kvm_psci functions to a shared header Will Deacon
2022-05-19 13:41 ` [PATCH 76/89] KVM: arm64: Factor out vcpu_reset code for core registers and PSCI Will Deacon
2022-05-19 13:41 ` [PATCH 77/89] KVM: arm64: Handle PSCI for protected VMs in EL2 Will Deacon
2022-05-19 13:41 ` [PATCH 78/89] KVM: arm64: Don't expose TLBI hypercalls after de-privilege Will Deacon
2022-05-19 13:41 ` [PATCH 79/89] KVM: arm64: Add is_pkvm_initialized() helper Will Deacon
2022-05-19 13:41 ` [PATCH 80/89] KVM: arm64: Refactor enter_exception64() Will Deacon
2022-05-19 13:41 ` [PATCH 81/89] KVM: arm64: Inject SIGSEGV on illegal accesses Will Deacon
2022-05-19 13:41 ` Will Deacon [this message]
2022-05-19 13:41 ` [PATCH 83/89] KVM: arm64: Avoid BBM when changing only s/w bits in Stage-2 PTE Will Deacon
2022-05-19 13:41 ` [PATCH 84/89] KVM: arm64: Extend memory sharing to allow guest-to-host transitions Will Deacon
2022-05-19 13:42 ` [PATCH 85/89] KVM: arm64: Document the KVM/arm64-specific calls in hypercalls.rst Will Deacon
2022-05-19 13:42 ` [PATCH 86/89] KVM: arm64: Reformat/beautify PTP hypercall documentation Will Deacon
2022-05-19 13:42 ` [PATCH 87/89] KVM: arm64: Expose memory sharing hypercalls to protected guests Will Deacon
2022-05-19 13:42 ` [PATCH 88/89] KVM: arm64: Introduce KVM_VM_TYPE_ARM_PROTECTED machine type for PVMs Will Deacon
2022-05-19 13:42 ` [PATCH 89/89] Documentation: KVM: Add some documentation for Protected KVM on arm64 Will Deacon
2022-06-07 22:39   ` Peter Collingbourne

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=20220519134204.5379-83-will@kernel.org \
    --to=will@kernel.org \
    --cc=alexandru.elisei@arm.com \
    --cc=ardb@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=chao.p.peng@linux.intel.com \
    --cc=james.morse@arm.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=luto@amacapital.net \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=michael.roth@amd.com \
    --cc=oupton@google.com \
    --cc=qperret@google.com \
    --cc=seanjc@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    /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).