This also moves the PSSCR update in nested entry to avoid a SPR
scoreboard stall.

-45 cycles (6276) POWER9 virt-mode NULL hcall

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c          |  7 +++++--
 arch/powerpc/kvm/book3s_hv_p9_entry.c | 26 +++++++++++++++++++-------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index c7cf771d3351..91bbd0a8f6b6 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3756,7 +3756,9 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu 
*vcpu, u64 time_limit, uns
 
        load_vcpu_state(vcpu, &host_os_sprs);
 
-       mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr);
+       if (vcpu->arch.psscr != host_psscr)
+               mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr);
+
        kvmhv_save_hv_regs(vcpu, &hvregs);
        hvregs.lpcr = lpcr;
        vcpu->arch.regs.msr = vcpu->arch.shregs.msr;
@@ -3797,7 +3799,6 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu 
*vcpu, u64 time_limit, uns
        vcpu->arch.shregs.dar = mfspr(SPRN_DAR);
        vcpu->arch.shregs.dsisr = mfspr(SPRN_DSISR);
        vcpu->arch.psscr = mfspr(SPRN_PSSCR_PR);
-       mtspr(SPRN_PSSCR_PR, host_psscr);
 
        store_vcpu_state(vcpu);
 
@@ -3810,6 +3811,8 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu 
*vcpu, u64 time_limit, uns
        timer_rearm_host_dec(*tb);
 
        restore_p9_host_os_sprs(vcpu, &host_os_sprs);
+       if (vcpu->arch.psscr != host_psscr)
+               mtspr(SPRN_PSSCR_PR, host_psscr);
 
        return trap;
 }
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c 
b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index f305d1d6445c..4bab56c10254 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -621,6 +621,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        unsigned long host_dawr0;
        unsigned long host_dawrx0;
        unsigned long host_psscr;
+       unsigned long host_hpsscr;
        unsigned long host_pidr;
        unsigned long host_dawr1;
        unsigned long host_dawrx1;
@@ -638,7 +639,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
 
        host_hfscr = mfspr(SPRN_HFSCR);
        host_ciabr = mfspr(SPRN_CIABR);
-       host_psscr = mfspr(SPRN_PSSCR);
+       host_psscr = mfspr(SPRN_PSSCR_PR);
+       if (cpu_has_feature(CPU_FTRS_POWER9_DD2_2))
+               host_hpsscr = mfspr(SPRN_PSSCR);
        host_pidr = mfspr(SPRN_PID);
 
        if (dawr_enabled()) {
@@ -719,8 +722,14 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        if (vcpu->arch.ciabr != host_ciabr)
                mtspr(SPRN_CIABR, vcpu->arch.ciabr);
 
-       mtspr(SPRN_PSSCR, vcpu->arch.psscr | PSSCR_EC |
-             (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
+
+       if (cpu_has_feature(CPU_FTRS_POWER9_DD2_2)) {
+               mtspr(SPRN_PSSCR, vcpu->arch.psscr | PSSCR_EC |
+                     (local_paca->kvm_hstate.fake_suspend << 
PSSCR_FAKE_SUSPEND_LG));
+       } else {
+               if (vcpu->arch.psscr != host_psscr)
+                       mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr);
+       }
 
        mtspr(SPRN_HFSCR, vcpu->arch.hfscr);
 
@@ -905,7 +914,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
 
        vcpu->arch.ic = mfspr(SPRN_IC);
        vcpu->arch.pid = mfspr(SPRN_PID);
-       vcpu->arch.psscr = mfspr(SPRN_PSSCR) & PSSCR_GUEST_VIS;
+       vcpu->arch.psscr = mfspr(SPRN_PSSCR_PR);
 
        vcpu->arch.shregs.sprg0 = mfspr(SPRN_SPRG0);
        vcpu->arch.shregs.sprg1 = mfspr(SPRN_SPRG1);
@@ -948,9 +957,12 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        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));
+       if (cpu_has_feature(CPU_FTRS_POWER9_DD2_2)) {
+               /* Preserve PSSCR[FAKE_SUSPEND] until we've called 
kvmppc_save_tm_hv */
+               mtspr(SPRN_PSSCR, host_hpsscr |
+                     (local_paca->kvm_hstate.fake_suspend << 
PSSCR_FAKE_SUSPEND_LG));
+       }
+
        mtspr(SPRN_HFSCR, host_hfscr);
        if (vcpu->arch.ciabr != host_ciabr)
                mtspr(SPRN_CIABR, host_ciabr);
-- 
2.23.0

Reply via email to