Skip to content

Commit b96b0c5

Browse files
Suzuki K Poulosebonzini
authored andcommitted
KVM: arm64: nvhe: Save the SPE context early
The nVHE KVM hyp drains and disables the SPE buffer, before entering the guest, as the EL1&0 translation regime is going to be loaded with that of the guest. But this operation is performed way too late, because : - The owning translation regime of the SPE buffer is transferred to EL2. (MDCR_EL2_E2PB == 0) - The guest Stage1 is loaded. Thus the flush could use the host EL1 virtual address, but use the EL2 translations instead of host EL1, for writing out any cached data. Fix this by moving the SPE buffer handling early enough. The restore path is doing the right thing. Fixes: 014c4c7 ("KVM: arm64: Improve debug register save/restore flow") Cc: [email protected] Cc: Christoffer Dall <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Alexandru Elisei <[email protected]> Reviewed-by: Alexandru Elisei <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 4691453 commit b96b0c5

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

arch/arm64/include/asm/kvm_hyp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt);
8383
void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
8484
void __debug_switch_to_host(struct kvm_vcpu *vcpu);
8585

86+
#ifdef __KVM_NVHE_HYPERVISOR__
87+
void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu);
88+
void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
89+
#endif
90+
8691
void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
8792
void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
8893

arch/arm64/kvm/hyp/nvhe/debug-sr.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,24 @@ static void __debug_restore_spe(u64 pmscr_el1)
5858
write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
5959
}
6060

61-
void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
61+
void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
6262
{
6363
/* Disable and flush SPE data generation */
6464
__debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
65+
}
66+
67+
void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
68+
{
6569
__debug_switch_to_guest_common(vcpu);
6670
}
6771

68-
void __debug_switch_to_host(struct kvm_vcpu *vcpu)
72+
void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
6973
{
7074
__debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
75+
}
76+
77+
void __debug_switch_to_host(struct kvm_vcpu *vcpu)
78+
{
7179
__debug_switch_to_host_common(vcpu);
7280
}
7381

arch/arm64/kvm/hyp/nvhe/switch.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
192192
pmu_switch_needed = __pmu_switch_to_guest(host_ctxt);
193193

194194
__sysreg_save_state_nvhe(host_ctxt);
195+
/*
196+
* We must flush and disable the SPE buffer for nVHE, as
197+
* the translation regime(EL1&0) is going to be loaded with
198+
* that of the guest. And we must do this before we change the
199+
* translation regime to EL2 (via MDCR_EL2_E2PB == 0) and
200+
* before we load guest Stage1.
201+
*/
202+
__debug_save_host_buffers_nvhe(vcpu);
195203

196204
__adjust_pc(vcpu);
197205

@@ -234,11 +242,12 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
234242
if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED)
235243
__fpsimd_save_fpexc32(vcpu);
236244

245+
__debug_switch_to_host(vcpu);
237246
/*
238247
* This must come after restoring the host sysregs, since a non-VHE
239248
* system may enable SPE here and make use of the TTBRs.
240249
*/
241-
__debug_switch_to_host(vcpu);
250+
__debug_restore_host_buffers_nvhe(vcpu);
242251

243252
if (pmu_switch_needed)
244253
__pmu_switch_to_host(host_ctxt);

0 commit comments

Comments
 (0)