KVM: arm64: Improve debug register save/restore flow
authorChristoffer Dall <christoffer.dall@linaro.org>
Tue, 10 Oct 2017 18:10:08 +0000 (20:10 +0200)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 19 Mar 2018 10:53:12 +0000 (10:53 +0000)
Instead of having multiple calls from the world switch path to the debug
logic, each figuring out if the dirty bit is set and if we should
save/restore the debug registers, let's just provide two hooks to the
debug save/restore functionality, one for switching to the guest
context, and one for switching to the host context, and we get the
benefit of only having to evaluate the dirty flag once on each path,
plus we give the compiler some more room to inline some of this
functionality.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm64/include/asm/kvm_hyp.h
arch/arm64/kvm/hyp/debug-sr.c
arch/arm64/kvm/hyp/switch.c

index f26f9cd70c721a5ae078c6294eae15ede20a8708..aeda2a7773659e53c8f6786121f546a90e90de5b 100644 (file)
@@ -138,14 +138,8 @@ void __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt);
 void __sysreg32_save_state(struct kvm_vcpu *vcpu);
 void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
 
-void __debug_save_state(struct kvm_vcpu *vcpu,
-                       struct kvm_guest_debug_arch *dbg,
-                       struct kvm_cpu_context *ctxt);
-void __debug_restore_state(struct kvm_vcpu *vcpu,
-                          struct kvm_guest_debug_arch *dbg,
-                          struct kvm_cpu_context *ctxt);
-void __debug_cond_save_host_state(struct kvm_vcpu *vcpu);
-void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu);
+void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
+void __debug_switch_to_host(struct kvm_vcpu *vcpu);
 
 void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
 void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
index 74f71fb5e36d8b5428f204abbf2bf20a9a3b5ffb..3e717f66f011d43ad8a8d0b1424c9c0c66d21daa 100644 (file)
@@ -110,16 +110,13 @@ static void __hyp_text __debug_restore_spe_nvhe(u64 pmscr_el1)
        write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
 }
 
-void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
-                                  struct kvm_guest_debug_arch *dbg,
-                                  struct kvm_cpu_context *ctxt)
+static void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
+                                         struct kvm_guest_debug_arch *dbg,
+                                         struct kvm_cpu_context *ctxt)
 {
        u64 aa64dfr0;
        int brps, wrps;
 
-       if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
-               return;
-
        aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
        brps = (aa64dfr0 >> 12) & 0xf;
        wrps = (aa64dfr0 >> 20) & 0xf;
@@ -132,16 +129,13 @@ void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
        ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
 }
 
-void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
-                                     struct kvm_guest_debug_arch *dbg,
-                                     struct kvm_cpu_context *ctxt)
+static void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
+                                            struct kvm_guest_debug_arch *dbg,
+                                            struct kvm_cpu_context *ctxt)
 {
        u64 aa64dfr0;
        int brps, wrps;
 
-       if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
-               return;
-
        aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
 
        brps = (aa64dfr0 >> 12) & 0xf;
@@ -155,10 +149,12 @@ void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
        write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
 }
 
-void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
+void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
 {
-       __debug_save_state(vcpu, &vcpu->arch.host_debug_state.regs,
-                          kern_hyp_va(vcpu->arch.host_cpu_context));
+       struct kvm_cpu_context *host_ctxt;
+       struct kvm_cpu_context *guest_ctxt;
+       struct kvm_guest_debug_arch *host_dbg;
+       struct kvm_guest_debug_arch *guest_dbg;
 
        /*
         * Non-VHE: Disable and flush SPE data generation
@@ -166,15 +162,39 @@ void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
         */
        if (!has_vhe())
                __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1);
+
+       if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
+               return;
+
+       host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+       guest_ctxt = &vcpu->arch.ctxt;
+       host_dbg = &vcpu->arch.host_debug_state.regs;
+       guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+       __debug_save_state(vcpu, host_dbg, host_ctxt);
+       __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
 }
 
-void __hyp_text __debug_cond_restore_host_state(struct kvm_vcpu *vcpu)
+void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
 {
+       struct kvm_cpu_context *host_ctxt;
+       struct kvm_cpu_context *guest_ctxt;
+       struct kvm_guest_debug_arch *host_dbg;
+       struct kvm_guest_debug_arch *guest_dbg;
+
        if (!has_vhe())
                __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1);
 
-       __debug_restore_state(vcpu, &vcpu->arch.host_debug_state.regs,
-                             kern_hyp_va(vcpu->arch.host_cpu_context));
+       if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
+               return;
+
+       host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+       guest_ctxt = &vcpu->arch.ctxt;
+       host_dbg = &vcpu->arch.host_debug_state.regs;
+       guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+       __debug_save_state(vcpu, guest_dbg, guest_ctxt);
+       __debug_restore_state(vcpu, host_dbg, host_ctxt);
 
        vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
 }
index c3e88ba81e26932305f83a3a2b31a0b8d5f9d8d2..35f3bbe1708417a90c59abbf64700fa3348e141a 100644 (file)
@@ -305,7 +305,6 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
        guest_ctxt = &vcpu->arch.ctxt;
 
        __sysreg_save_host_state(host_ctxt);
-       __debug_cond_save_host_state(vcpu);
 
        __activate_traps(vcpu);
        __activate_vm(vcpu);
@@ -319,7 +318,7 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
         */
        __sysreg32_restore_state(vcpu);
        __sysreg_restore_guest_state(guest_ctxt);
-       __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
+       __debug_switch_to_guest(vcpu);
 
        /* Jump in the fire! */
 again:
@@ -416,12 +415,11 @@ again:
                __fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs);
        }
 
-       __debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
        /*
         * This must come after restoring the host sysregs, since a non-VHE
         * system may enable SPE here and make use of the TTBRs.
         */
-       __debug_cond_restore_host_state(vcpu);
+       __debug_switch_to_host(vcpu);
 
        return exit_code;
 }