Skip to content

Commit da2e743

Browse files
Alexandru Eliseioupton
authored andcommitted
KVM: arm64: VHE: Save and restore host MDCR_EL2 value correctly
Prior to commit 75a5fba ("KVM: arm64: Compute MDCR_EL2 at vcpu_load()"), host MDCR_EL2 was saved correctly: kvm_arch_vcpu_load() kvm_vcpu_load_debug() /* Doesn't touch hardware MDCR_EL2. */ kvm_vcpu_load_vhe() __activate_traps_common() /* Saves host MDCR_EL2. */ *host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2) /* Writes VCPU MDCR_EL2. */ write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2) The MDCR_EL2 value saved previously was restored in kvm_arch_vcpu_put() -> kvm_vcpu_put_vhe(). After the aforementioned commit, host MDCR_EL2 is never saved: kvm_arch_vcpu_load() kvm_vcpu_load_debug() /* Writes VCPU MDCR_EL2 */ kvm_vcpu_load_vhe() __activate_traps_common() /* Saves **VCPU** MDCR_EL2. */ *host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2) /* Writes VCPU MDCR_EL2 a second time. */ write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2) kvm_arch_vcpu_put() -> kvm_vcpu_put_vhe() then restores the VCPU MDCR_EL2 value. Also VCPU's MDCR_EL2 value gets written to hardware twice now. Fix this by saving the host MDCR_EL2 in kvm_arch_vcpu_load() before it gets overwritten by the VCPU's MDCR_EL2 value, and restore it on VCPU put. Signed-off-by: Alexandru Elisei <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent efad60e commit da2e743

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

arch/arm64/kvm/debug.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)
145145
/* Must be called before kvm_vcpu_load_vhe() */
146146
KVM_BUG_ON(vcpu_get_flag(vcpu, SYSREGS_ON_CPU), vcpu->kvm);
147147

148+
if (has_vhe())
149+
*host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2);
150+
148151
/*
149152
* Determine which of the possible debug states we're in:
150153
*
@@ -191,6 +194,9 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)
191194

192195
void kvm_vcpu_put_debug(struct kvm_vcpu *vcpu)
193196
{
197+
if (has_vhe())
198+
write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
199+
194200
if (likely(!(vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
195201
return;
196202

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,6 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
431431
vcpu_set_flag(vcpu, PMUSERENR_ON_CPU);
432432
}
433433

434-
*host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2);
435-
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
436-
437434
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
438435
u64 hcrx = vcpu->arch.hcrx_el2;
439436
if (is_nested_ctxt(vcpu)) {
@@ -454,8 +451,6 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
454451
{
455452
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
456453

457-
write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
458-
459454
write_sysreg(0, hstr_el2);
460455
if (system_supports_pmuv3()) {
461456
write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ extern void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc);
5050
static void __activate_traps(struct kvm_vcpu *vcpu)
5151
{
5252
___activate_traps(vcpu, vcpu->arch.hcr_el2);
53+
54+
*host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2);
55+
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
56+
5357
__activate_traps_common(vcpu);
5458
__activate_cptr_traps(vcpu);
5559

@@ -93,6 +97,8 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
9397
isb();
9498
}
9599

100+
write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
101+
96102
__deactivate_traps_common(vcpu);
97103

98104
write_sysreg_hcr(this_cpu_ptr(&kvm_init_params)->hcr_el2);

0 commit comments

Comments
 (0)