Avoid interleaving mfSPR and mtSPR to reduce SPR scoreboard stalls.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c          |  8 ++++----
 arch/powerpc/kvm/book3s_hv_p9_entry.c | 19 +++++++++++--------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index f3c052b8b7ee..823d64047d01 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -4308,10 +4308,6 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, 
u64 time_limit,
 
        store_spr_state(vcpu);
 
-       timer_rearm_host_dec(*tb);
-
-       restore_p9_host_os_sprs(vcpu, &host_os_sprs);
-
        store_fp_state(&vcpu->arch.fp);
 #ifdef CONFIG_ALTIVEC
        store_vr_state(&vcpu->arch.vr);
@@ -4326,6 +4322,10 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, 
u64 time_limit,
 
        switch_pmu_to_host(vcpu, &host_os_sprs);
 
+       timer_rearm_host_dec(*tb);
+
+       restore_p9_host_os_sprs(vcpu, &host_os_sprs);
+
        vc->entry_exit_map = 0x101;
        vc->in_guest = 0;
 
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c 
b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index 2bd96d8256d1..bd0021cd3a67 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -228,6 +228,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
                host_dawrx1 = mfspr(SPRN_DAWRX1);
        }
 
+       local_paca->kvm_hstate.host_purr = mfspr(SPRN_PURR);
+       local_paca->kvm_hstate.host_spurr = mfspr(SPRN_SPURR);
+
        if (vc->tb_offset) {
                u64 new_tb = *tb + vc->tb_offset;
                mtspr(SPRN_TBU40, new_tb);
@@ -244,8 +247,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        mtspr(SPRN_DPDES, vc->dpdes);
        mtspr(SPRN_VTB, vc->vtb);
 
-       local_paca->kvm_hstate.host_purr = mfspr(SPRN_PURR);
-       local_paca->kvm_hstate.host_spurr = mfspr(SPRN_SPURR);
        mtspr(SPRN_PURR, vcpu->arch.purr);
        mtspr(SPRN_SPURR, vcpu->arch.spurr);
 
@@ -448,10 +449,8 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        /* Advance host PURR/SPURR by the amount used by guest */
        purr = mfspr(SPRN_PURR);
        spurr = mfspr(SPRN_SPURR);
-       mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr +
-             purr - vcpu->arch.purr);
-       mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr +
-             spurr - vcpu->arch.spurr);
+       local_paca->kvm_hstate.host_purr += purr - vcpu->arch.purr;
+       local_paca->kvm_hstate.host_spurr += spurr - vcpu->arch.spurr;
        vcpu->arch.purr = purr;
        vcpu->arch.spurr = spurr;
 
@@ -464,6 +463,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        vcpu->arch.shregs.sprg2 = mfspr(SPRN_SPRG2);
        vcpu->arch.shregs.sprg3 = mfspr(SPRN_SPRG3);
 
+       vc->dpdes = mfspr(SPRN_DPDES);
+       vc->vtb = mfspr(SPRN_VTB);
+
        dec = mfspr(SPRN_DEC);
        if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */
                dec = (s32) dec;
@@ -481,6 +483,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
                vc->tb_offset_applied = 0;
        }
 
+       mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr);
+       mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr);
+
        /* Preserve PSSCR[FAKE_SUSPEND] until we've called kvmppc_save_tm_hv */
        mtspr(SPRN_PSSCR, host_psscr |
              (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
@@ -509,8 +514,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        if (cpu_has_feature(CPU_FTR_ARCH_31))
                asm volatile(PPC_CP_ABORT);
 
-       vc->dpdes = mfspr(SPRN_DPDES);
-       vc->vtb = mfspr(SPRN_VTB);
        mtspr(SPRN_DPDES, 0);
        if (vc->pcr)
                mtspr(SPRN_PCR, PCR_MASK);
-- 
2.23.0

Reply via email to