| From 1d9b5f78665f25b6cd5188d958418914006c38ba Mon Sep 17 00:00:00 2001 |
| From: Andrew Murray <andrew.murray@arm.com> |
| Date: Fri, 17 Jan 2020 13:43:24 +0000 |
| Subject: [PATCH] KVM: arm64: Write arch.mdcr_el2 changes since last vcpu_load |
| on VHE |
| |
| commit 4942dc6638b07b5326b6d2faa142635c559e7cd5 upstream. |
| |
| On VHE systems arch.mdcr_el2 is written to mdcr_el2 at vcpu_load time to |
| set options for self-hosted debug and the performance monitors |
| extension. |
| |
| Unfortunately the value of arch.mdcr_el2 is not calculated until |
| kvm_arm_setup_debug() in the run loop after the vcpu has been loaded. |
| This means that the initial brief iterations of the run loop use a zero |
| value of mdcr_el2 - until the vcpu is preempted. This also results in a |
| delay between changes to vcpu->guest_debug taking effect. |
| |
| Fix this by writing to mdcr_el2 in kvm_arm_setup_debug() on VHE systems |
| when a change to arch.mdcr_el2 has been detected. |
| |
| Fixes: d5a21bcc2995 ("KVM: arm64: Move common VHE/non-VHE trap config in separate functions") |
| Cc: <stable@vger.kernel.org> # 4.17.x- |
| Suggested-by: James Morse <james.morse@arm.com> |
| Acked-by: Will Deacon <will@kernel.org> |
| Reviewed-by: Marc Zyngier <maz@kernel.org> |
| Signed-off-by: Andrew Murray <andrew.murray@arm.com> |
| Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c |
| index 43487f035385..7a7e425616b5 100644 |
| --- a/arch/arm64/kvm/debug.c |
| +++ b/arch/arm64/kvm/debug.c |
| @@ -101,7 +101,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) |
| void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) |
| { |
| bool trap_debug = !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY); |
| - unsigned long mdscr; |
| + unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2; |
| |
| trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); |
| |
| @@ -197,6 +197,10 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) |
| if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) |
| vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; |
| |
| + /* Write mdcr_el2 changes since vcpu_load on VHE systems */ |
| + if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) |
| + write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); |
| + |
| trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); |
| trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1)); |
| } |
| -- |
| 2.7.4 |
| |