]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
KVM: arm64: Write arch.mdcr_el2 changes since last vcpu_load on VHE
authorAndrew Murray <andrew.murray@arm.com>
Fri, 31 Jan 2020 15:15:43 +0000 (12:15 -0300)
committerKhalid Elmously <khalid.elmously@canonical.com>
Fri, 14 Feb 2020 04:33:08 +0000 (23:33 -0500)
BugLink: https://bugs.launchpad.net/bugs/1860657
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>
(backported from commit 4942dc6638b07b5326b6d2faa142635c559e7cd5)
[cascardo: backport considering context and changes up to 5.0]
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
arch/arm64/kvm/debug.c

index fa63b28c65e08a37e269b8d55fa6197e77b42b40..87ed43c941de97667b4aab6763ad18a2befa28db 100644 (file)
@@ -108,6 +108,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.debug_flags & KVM_ARM64_DEBUG_DIRTY);
+       unsigned long orig_mdcr_el2 = vcpu->arch.mdcr_el2;
 
        trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
 
@@ -193,6 +194,10 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
        if (trap_debug)
                vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+       /* 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_sys_reg(vcpu, MDSCR_EL1));
 }