* [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE
@ 2023-10-12 20:54 Oliver Upton
2023-10-12 20:54 ` [PATCH v2 1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host() Oliver Upton
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
Clearly my half-assed attempt at this series needed a bit of TLC.
Respinning with Marc's diff to make sure the stage-2 is in a consistent
state after VMID rollover and MMU notifiers triggering TLB invalidation.
v2: https://lore.kernel.org/kvmarm/20231006093600.1250986-1-oliver.upton@linux.dev/
Marc Zyngier (2):
KVM: arm64: Restore the stage-2 context in VHE's
__tlb_switch_to_host()
KVM: arm64: Reload stage-2 for VMID change on VHE
Oliver Upton (3):
KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host()
KVM: arm64: Rename helpers for VHE vCPU load/put
KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()
arch/arm64/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_hyp.h | 2 ++
arch/arm64/kvm/arm.c | 9 +++++---
arch/arm64/kvm/hyp/vhe/switch.c | 33 ++++++++++++++++++------------
arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 11 ++++------
arch/arm64/kvm/hyp/vhe/tlb.c | 18 ++++++++++++----
arch/arm64/kvm/vmid.c | 11 +++++++---
7 files changed, 57 insertions(+), 33 deletions(-)
base-commit: 6465e260f48790807eef06b583b38ca9789b6072
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host()
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
@ 2023-10-12 20:54 ` Oliver Upton
2023-10-12 20:54 ` [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host() Oliver Upton
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
HCR_EL2.TGE=0 is sufficient to disable stage-2 translation, so there's
no need to explicitly zero VTTBR_EL2.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/hyp/vhe/tlb.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index 46bd43f61d76..f3f2e142e4f4 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -66,7 +66,6 @@ static void __tlb_switch_to_host(struct tlb_inv_context *cxt)
* We're done with the TLB operation, let's restore the host's
* view of HCR_EL2.
*/
- write_sysreg(0, vttbr_el2);
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
isb();
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host()
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
2023-10-12 20:54 ` [PATCH v2 1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host() Oliver Upton
@ 2023-10-12 20:54 ` Oliver Upton
2023-10-18 7:00 ` Zenghui Yu
2023-10-12 20:54 ` [PATCH v2 3/5] KVM: arm64: Reload stage-2 for VMID change on VHE Oliver Upton
` (3 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
From: Marc Zyngier <maz@kernel.org>
An MMU notifier could cause us to clobber the stage-2 context loaded on
a CPU when we switch to another VM's context to invalidate. This isn't
an issue right now as the stage-2 context gets reloaded on every guest
entry, but is disastrous when moving __load_stage2() into the
vcpu_load() path.
Restore the previous stage-2 context on the way out of a TLB
invalidation if we installed something else. Deliberately do this after
TGE=1 is synchronized to keep things safe in light of the speculative AT
errata.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/hyp/vhe/tlb.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index f3f2e142e4f4..ef21153ce5fa 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -11,18 +11,25 @@
#include <asm/tlbflush.h>
struct tlb_inv_context {
- unsigned long flags;
- u64 tcr;
- u64 sctlr;
+ struct kvm_s2_mmu *mmu;
+ unsigned long flags;
+ u64 tcr;
+ u64 sctlr;
};
static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
struct tlb_inv_context *cxt)
{
+ struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
u64 val;
local_irq_save(cxt->flags);
+ if (vcpu && mmu != vcpu->arch.hw_mmu)
+ cxt->mmu = mmu;
+ else
+ cxt->mmu = NULL;
+
if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
/*
* For CPUs that are affected by ARM errata 1165522 or 1530923,
@@ -69,6 +76,10 @@ static void __tlb_switch_to_host(struct tlb_inv_context *cxt)
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
isb();
+ /* ... and the stage-2 MMU context that we switched away from */
+ if (cxt->mmu)
+ __load_stage2(cxt->mmu, cxt->mmu->arch);
+
if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
/* Restore the registers to what they were */
write_sysreg_el1(cxt->tcr, SYS_TCR);
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/5] KVM: arm64: Reload stage-2 for VMID change on VHE
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
2023-10-12 20:54 ` [PATCH v2 1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host() Oliver Upton
2023-10-12 20:54 ` [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host() Oliver Upton
@ 2023-10-12 20:54 ` Oliver Upton
2023-10-12 20:54 ` [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put Oliver Upton
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
From: Marc Zyngier <maz@kernel.org>
Naturally, a change to the VMID for an MMU implies a new value for
VTTBR. Reload on VMID change in anticipation of loading stage-2 on
vcpu_load() instead of every guest entry.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/include/asm/kvm_host.h | 2 +-
arch/arm64/kvm/arm.c | 5 ++++-
arch/arm64/kvm/vmid.c | 11 ++++++++---
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index af06ccb7ee34..be0ab101c557 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1025,7 +1025,7 @@ int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
extern unsigned int __ro_after_init kvm_arm_vmid_bits;
int __init kvm_arm_vmid_alloc_init(void);
void __init kvm_arm_vmid_alloc_free(void);
-void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
+bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
void kvm_arm_vmid_clear_active(void);
static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 4866b3f7b4ea..3ab904adbd64 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -950,7 +950,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* making a thread's VMID inactive. So we need to call
* kvm_arm_vmid_update() in non-premptible context.
*/
- kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid);
+ if (kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid) &&
+ has_vhe())
+ __load_stage2(vcpu->arch.hw_mmu,
+ vcpu->arch.hw_mmu->arch);
kvm_pmu_flush_hwstate(vcpu);
diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
index 7fe8ba1a2851..806223b7022a 100644
--- a/arch/arm64/kvm/vmid.c
+++ b/arch/arm64/kvm/vmid.c
@@ -135,10 +135,11 @@ void kvm_arm_vmid_clear_active(void)
atomic64_set(this_cpu_ptr(&active_vmids), VMID_ACTIVE_INVALID);
}
-void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
+bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
{
unsigned long flags;
u64 vmid, old_active_vmid;
+ bool updated = false;
vmid = atomic64_read(&kvm_vmid->id);
@@ -156,17 +157,21 @@ void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
if (old_active_vmid != 0 && vmid_gen_match(vmid) &&
0 != atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
old_active_vmid, vmid))
- return;
+ return false;
raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
/* Check that our VMID belongs to the current generation. */
vmid = atomic64_read(&kvm_vmid->id);
- if (!vmid_gen_match(vmid))
+ if (!vmid_gen_match(vmid)) {
vmid = new_vmid(kvm_vmid);
+ updated = true;
+ }
atomic64_set(this_cpu_ptr(&active_vmids), vmid);
raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
+
+ return updated;
}
/*
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
` (2 preceding siblings ...)
2023-10-12 20:54 ` [PATCH v2 3/5] KVM: arm64: Reload stage-2 for VMID change on VHE Oliver Upton
@ 2023-10-12 20:54 ` Oliver Upton
2023-10-18 7:10 ` Zenghui Yu
2023-10-12 20:54 ` [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe() Oliver Upton
2023-10-17 7:58 ` [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
5 siblings, 1 reply; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
The names for the helpers we expose to the 'generic' KVM code are a bit
imprecise; we switch the EL0 + EL1 sysreg context and setup trap
controls that do not need to change for every guest entry/exit. Rename +
shuffle things around a bit in preparation for loading the stage-2 MMU
context on vcpu_load().
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/include/asm/kvm_host.h | 4 ++--
arch/arm64/include/asm/kvm_hyp.h | 2 ++
arch/arm64/kvm/arm.c | 4 ++--
arch/arm64/kvm/hyp/vhe/switch.c | 18 +++++++++++++++---
arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 11 ++++-------
5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index be0ab101c557..759adee42018 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1109,8 +1109,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
}
#endif
-void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu);
-void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu);
+void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
+void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu);
int __init kvm_set_ipa_limit(void);
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 66efd67ea7e8..80c779d1307a 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -93,6 +93,8 @@ void __timer_disable_traps(struct kvm_vcpu *vcpu);
void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt);
void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt);
#else
+void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu);
+void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu);
void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt);
void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt);
void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3ab904adbd64..584be562b1d4 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -448,7 +448,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
kvm_vgic_load(vcpu);
kvm_timer_vcpu_load(vcpu);
if (has_vhe())
- kvm_vcpu_load_sysregs_vhe(vcpu);
+ kvm_vcpu_load_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
@@ -472,7 +472,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arch_vcpu_put_debug_state_flags(vcpu);
kvm_arch_vcpu_put_fp(vcpu);
if (has_vhe())
- kvm_vcpu_put_sysregs_vhe(vcpu);
+ kvm_vcpu_put_vhe(vcpu);
kvm_timer_vcpu_put(vcpu);
kvm_vgic_put(vcpu);
kvm_vcpu_pmu_restore_host(vcpu);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 6537f58b1a8c..d05b6a08dcde 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -93,12 +93,12 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
NOKPROBE_SYMBOL(__deactivate_traps);
/*
- * Disable IRQs in {activate,deactivate}_traps_vhe_{load,put}() to
+ * Disable IRQs in __vcpu_{load,put}_{activate,deactivate}_traps() to
* prevent a race condition between context switching of PMUSERENR_EL0
* in __{activate,deactivate}_traps_common() and IPIs that attempts to
* update PMUSERENR_EL0. See also kvm_set_pmuserenr().
*/
-void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
+static void __vcpu_load_activate_traps(struct kvm_vcpu *vcpu)
{
unsigned long flags;
@@ -107,7 +107,7 @@ void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
local_irq_restore(flags);
}
-void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
+static void __vcpu_put_deactivate_traps(struct kvm_vcpu *vcpu)
{
unsigned long flags;
@@ -116,6 +116,18 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
local_irq_restore(flags);
}
+void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu)
+{
+ __vcpu_load_switch_sysregs(vcpu);
+ __vcpu_load_activate_traps(vcpu);
+}
+
+void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
+{
+ __vcpu_put_deactivate_traps(vcpu);
+ __vcpu_put_switch_sysregs(vcpu);
+}
+
static const exit_handler_fn hyp_exit_handlers[] = {
[0 ... ESR_ELx_EC_MAX] = NULL,
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index b35a178e7e0d..8e1e0d5033b6 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -52,7 +52,7 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt)
NOKPROBE_SYMBOL(sysreg_restore_guest_state_vhe);
/**
- * kvm_vcpu_load_sysregs_vhe - Load guest system registers to the physical CPU
+ * __vcpu_load_switch_sysregs - Load guest system registers to the physical CPU
*
* @vcpu: The VCPU pointer
*
@@ -62,7 +62,7 @@ NOKPROBE_SYMBOL(sysreg_restore_guest_state_vhe);
* and loading system register state early avoids having to load them on
* every entry to the VM.
*/
-void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
+void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
struct kvm_cpu_context *host_ctxt;
@@ -92,12 +92,10 @@ void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
__sysreg_restore_el1_state(guest_ctxt);
vcpu_set_flag(vcpu, SYSREGS_ON_CPU);
-
- activate_traps_vhe_load(vcpu);
}
/**
- * kvm_vcpu_put_sysregs_vhe - Restore host system registers to the physical CPU
+ * __vcpu_put_switch_syregs - Restore host system registers to the physical CPU
*
* @vcpu: The VCPU pointer
*
@@ -107,13 +105,12 @@ void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
* and deferring saving system register state until we're no longer running the
* VCPU avoids having to save them on every exit from the VM.
*/
-void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu)
+void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
struct kvm_cpu_context *host_ctxt;
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
- deactivate_traps_vhe_put(vcpu);
__sysreg_save_el1_state(guest_ctxt);
__sysreg_save_user_state(guest_ctxt);
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
` (3 preceding siblings ...)
2023-10-12 20:54 ` [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put Oliver Upton
@ 2023-10-12 20:54 ` Oliver Upton
2023-10-18 7:17 ` Zenghui Yu
2023-10-17 7:58 ` [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
5 siblings, 1 reply; 11+ messages in thread
From: Oliver Upton @ 2023-10-12 20:54 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
To date the VHE code has aggressively reloaded the stage-2 MMU context
on every guest entry, despite the fact that this isn't necessary. This
was probably done for consistency with the nVHE code, which needs to
switch in/out the stage-2 MMU context as both the host and guest run at
EL1.
Hoist __stage2_load() into kvm_vcpu_load_vhe(), thus avoiding a reload
on every guest entry/exit. This is likely to be beneficial to systems
with one of the speculative AT errata, as there is now one fewer context
synchronization event on the guest entry path. Additionally, it is
possible that implementations have hitched correctness mitigations on
writes to VTTBR_EL2, which are now elided on guest re-entry.
Note that __tlb_switch_to_guest() is deliberately left untouched as it
can be called outside the context of a running vCPU, or possibly be
called in a MMU notifier that needs to switch to a different stage-2
context.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/hyp/vhe/switch.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index d05b6a08dcde..b0cafd7c5f8f 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -120,6 +120,7 @@ void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu)
{
__vcpu_load_switch_sysregs(vcpu);
__vcpu_load_activate_traps(vcpu);
+ __load_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch);
}
void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
@@ -182,17 +183,11 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_save_host_state_vhe(host_ctxt);
/*
- * ARM erratum 1165522 requires us to configure both stage 1 and
- * stage 2 translation for the guest context before we clear
- * HCR_EL2.TGE.
- *
- * We have already configured the guest's stage 1 translation in
- * kvm_vcpu_load_sysregs_vhe above. We must now call
- * __load_stage2 before __activate_traps, because
- * __load_stage2 configures stage 2 translation, and
- * __activate_traps clear HCR_EL2.TGE (among other things).
+ * Note that ARM erratum 1165522 requires us to configure both stage 1
+ * and stage 2 translation for the guest context before we clear
+ * HCR_EL2.TGE. The stage 1 and stage 2 guest context has already been
+ * loaded on the CPU in kvm_vcpu_load_vhe().
*/
- __load_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch);
__activate_traps(vcpu);
__kvm_adjust_pc(vcpu);
--
2.42.0.655.g421f12c284-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
` (4 preceding siblings ...)
2023-10-12 20:54 ` [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe() Oliver Upton
@ 2023-10-17 7:58 ` Oliver Upton
5 siblings, 0 replies; 11+ messages in thread
From: Oliver Upton @ 2023-10-17 7:58 UTC (permalink / raw)
To: kvmarm, Oliver Upton
Cc: Marc Zyngier, kvm, James Morse, Zenghui Yu, Suzuki K Poulose
On Thu, 12 Oct 2023 20:54:17 +0000, Oliver Upton wrote:
> Clearly my half-assed attempt at this series needed a bit of TLC.
> Respinning with Marc's diff to make sure the stage-2 is in a consistent
> state after VMID rollover and MMU notifiers triggering TLB invalidation.
>
> v2: https://lore.kernel.org/kvmarm/20231006093600.1250986-1-oliver.upton@linux.dev/
>
> Marc Zyngier (2):
> KVM: arm64: Restore the stage-2 context in VHE's
> __tlb_switch_to_host()
> KVM: arm64: Reload stage-2 for VMID change on VHE
>
> [...]
Applied to kvmarm/next, thanks!
[1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host()
https://git.kernel.org/kvmarm/kvmarm/c/65221c1f57f6
[2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host()
https://git.kernel.org/kvmarm/kvmarm/c/35a647ce2419
[3/5] KVM: arm64: Reload stage-2 for VMID change on VHE
https://git.kernel.org/kvmarm/kvmarm/c/052166906b67
[4/5] KVM: arm64: Rename helpers for VHE vCPU load/put
https://git.kernel.org/kvmarm/kvmarm/c/8f7d6be28d46
[5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()
https://git.kernel.org/kvmarm/kvmarm/c/0556bbf8a5ed
--
Best,
Oliver
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host()
2023-10-12 20:54 ` [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host() Oliver Upton
@ 2023-10-18 7:00 ` Zenghui Yu
2023-10-18 7:05 ` Oliver Upton
0 siblings, 1 reply; 11+ messages in thread
From: Zenghui Yu @ 2023-10-18 7:00 UTC (permalink / raw)
To: Oliver Upton; +Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose
On 2023/10/13 4:54, Oliver Upton wrote:
> From: Marc Zyngier <maz@kernel.org>
>
> An MMU notifier could cause us to clobber the stage-2 context loaded on
> a CPU when we switch to another VM's context to invalidate. This isn't
> an issue right now as the stage-2 context gets reloaded on every guest
> entry, but is disastrous when moving __load_stage2() into the
> vcpu_load() path.
>
> Restore the previous stage-2 context on the way out of a TLB
> invalidation if we installed something else. Deliberately do this after
> TGE=1 is synchronized to keep things safe in light of the speculative AT
> errata.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> ---
> arch/arm64/kvm/hyp/vhe/tlb.c | 17 ++++++++++++++---
> 1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
> index f3f2e142e4f4..ef21153ce5fa 100644
> --- a/arch/arm64/kvm/hyp/vhe/tlb.c
> +++ b/arch/arm64/kvm/hyp/vhe/tlb.c
> @@ -11,18 +11,25 @@
> #include <asm/tlbflush.h>
>
> struct tlb_inv_context {
> - unsigned long flags;
> - u64 tcr;
> - u64 sctlr;
> + struct kvm_s2_mmu *mmu;
> + unsigned long flags;
> + u64 tcr;
> + u64 sctlr;
> };
>
> static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
> struct tlb_inv_context *cxt)
> {
> + struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
> u64 val;
>
> local_irq_save(cxt->flags);
>
> + if (vcpu && mmu != vcpu->arch.hw_mmu)
> + cxt->mmu = mmu;
Shouldn't this be
cxt->mm = vcpu->arch.hw_mmu (the "previous" S2 context)?
Thanks,
Zenghui
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host()
2023-10-18 7:00 ` Zenghui Yu
@ 2023-10-18 7:05 ` Oliver Upton
0 siblings, 0 replies; 11+ messages in thread
From: Oliver Upton @ 2023-10-18 7:05 UTC (permalink / raw)
To: Zenghui Yu; +Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose
On Wed, Oct 18, 2023 at 03:00:42PM +0800, Zenghui Yu wrote:
> On 2023/10/13 4:54, Oliver Upton wrote:
> > From: Marc Zyngier <maz@kernel.org>
> >
> > An MMU notifier could cause us to clobber the stage-2 context loaded on
> > a CPU when we switch to another VM's context to invalidate. This isn't
> > an issue right now as the stage-2 context gets reloaded on every guest
> > entry, but is disastrous when moving __load_stage2() into the
> > vcpu_load() path.
> >
> > Restore the previous stage-2 context on the way out of a TLB
> > invalidation if we installed something else. Deliberately do this after
> > TGE=1 is synchronized to keep things safe in light of the speculative AT
> > errata.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> > ---
> > arch/arm64/kvm/hyp/vhe/tlb.c | 17 ++++++++++++++---
> > 1 file changed, 14 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
> > index f3f2e142e4f4..ef21153ce5fa 100644
> > --- a/arch/arm64/kvm/hyp/vhe/tlb.c
> > +++ b/arch/arm64/kvm/hyp/vhe/tlb.c
> > @@ -11,18 +11,25 @@
> > #include <asm/tlbflush.h>
> > struct tlb_inv_context {
> > - unsigned long flags;
> > - u64 tcr;
> > - u64 sctlr;
> > + struct kvm_s2_mmu *mmu;
> > + unsigned long flags;
> > + u64 tcr;
> > + u64 sctlr;
> > };
> > static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
> > struct tlb_inv_context *cxt)
> > {
> > + struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
> > u64 val;
> > local_irq_save(cxt->flags);
> > + if (vcpu && mmu != vcpu->arch.hw_mmu)
> > + cxt->mmu = mmu;
>
> Shouldn't this be
>
> cxt->mm = vcpu->arch.hw_mmu (the "previous" S2 context)?
It absolutely should, and Marc had it right the first time.
--
Thanks,
Oliver
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put
2023-10-12 20:54 ` [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put Oliver Upton
@ 2023-10-18 7:10 ` Zenghui Yu
0 siblings, 0 replies; 11+ messages in thread
From: Zenghui Yu @ 2023-10-18 7:10 UTC (permalink / raw)
To: Oliver Upton; +Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose
On 2023/10/13 4:54, Oliver Upton wrote:
> -void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
The declaration in kvm_hyp.h can be removed now. Same for
deactivate_traps_vhe_put().
Thanks,
Zenghui
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()
2023-10-12 20:54 ` [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe() Oliver Upton
@ 2023-10-18 7:17 ` Zenghui Yu
0 siblings, 0 replies; 11+ messages in thread
From: Zenghui Yu @ 2023-10-18 7:17 UTC (permalink / raw)
To: Oliver Upton; +Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose
On 2023/10/13 4:54, Oliver Upton wrote:
> Hoist __stage2_load() into kvm_vcpu_load_vhe(), thus avoiding a reload
nit: s/__stage2_load/__load_stage2/
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-10-18 7:17 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-12 20:54 [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
2023-10-12 20:54 ` [PATCH v2 1/5] KVM: arm64: Don't zero VTTBR in __tlb_switch_to_host() Oliver Upton
2023-10-12 20:54 ` [PATCH v2 2/5] KVM: arm64: Restore the stage-2 context in VHE's __tlb_switch_to_host() Oliver Upton
2023-10-18 7:00 ` Zenghui Yu
2023-10-18 7:05 ` Oliver Upton
2023-10-12 20:54 ` [PATCH v2 3/5] KVM: arm64: Reload stage-2 for VMID change on VHE Oliver Upton
2023-10-12 20:54 ` [PATCH v2 4/5] KVM: arm64: Rename helpers for VHE vCPU load/put Oliver Upton
2023-10-18 7:10 ` Zenghui Yu
2023-10-12 20:54 ` [PATCH v2 5/5] KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe() Oliver Upton
2023-10-18 7:17 ` Zenghui Yu
2023-10-17 7:58 ` [PATCH v2 0/5] KVM: arm64: Load stage-2 in vcpu_load() on VHE Oliver Upton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox