Commit 9a1e530b authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

KVM: PPC: Book3S HV P9: Avoid SPR scoreboard stalls

Avoid interleaving mfSPR and mtSPR to reduce SPR scoreboard stalls.
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211123095231.1036501-26-npiggin@gmail.com
parent cb2553a0
...@@ -4321,10 +4321,6 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, ...@@ -4321,10 +4321,6 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
store_spr_state(vcpu); store_spr_state(vcpu);
timer_rearm_host_dec(*tb);
restore_p9_host_os_sprs(vcpu, &host_os_sprs);
store_fp_state(&vcpu->arch.fp); store_fp_state(&vcpu->arch.fp);
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
store_vr_state(&vcpu->arch.vr); store_vr_state(&vcpu->arch.vr);
...@@ -4339,6 +4335,10 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, ...@@ -4339,6 +4335,10 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
switch_pmu_to_host(vcpu, &host_os_sprs); 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->entry_exit_map = 0x101;
vc->in_guest = 0; vc->in_guest = 0;
......
...@@ -228,6 +228,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc ...@@ -228,6 +228,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
host_dawrx1 = mfspr(SPRN_DAWRX1); 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) { if (vc->tb_offset) {
u64 new_tb = *tb + vc->tb_offset; u64 new_tb = *tb + vc->tb_offset;
mtspr(SPRN_TBU40, new_tb); mtspr(SPRN_TBU40, new_tb);
...@@ -244,8 +247,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc ...@@ -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_DPDES, vc->dpdes);
mtspr(SPRN_VTB, vc->vtb); 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_PURR, vcpu->arch.purr);
mtspr(SPRN_SPURR, vcpu->arch.spurr); 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 ...@@ -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 */ /* Advance host PURR/SPURR by the amount used by guest */
purr = mfspr(SPRN_PURR); purr = mfspr(SPRN_PURR);
spurr = mfspr(SPRN_SPURR); spurr = mfspr(SPRN_SPURR);
mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr + local_paca->kvm_hstate.host_purr += purr - vcpu->arch.purr;
purr - vcpu->arch.purr); local_paca->kvm_hstate.host_spurr += spurr - vcpu->arch.spurr;
mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr +
spurr - vcpu->arch.spurr);
vcpu->arch.purr = purr; vcpu->arch.purr = purr;
vcpu->arch.spurr = spurr; vcpu->arch.spurr = spurr;
...@@ -464,6 +463,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc ...@@ -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.sprg2 = mfspr(SPRN_SPRG2);
vcpu->arch.shregs.sprg3 = mfspr(SPRN_SPRG3); vcpu->arch.shregs.sprg3 = mfspr(SPRN_SPRG3);
vc->dpdes = mfspr(SPRN_DPDES);
vc->vtb = mfspr(SPRN_VTB);
dec = mfspr(SPRN_DEC); dec = mfspr(SPRN_DEC);
if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */ if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */
dec = (s32) dec; dec = (s32) dec;
...@@ -481,6 +483,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc ...@@ -481,6 +483,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
vc->tb_offset_applied = 0; 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 */ /* Preserve PSSCR[FAKE_SUSPEND] until we've called kvmppc_save_tm_hv */
mtspr(SPRN_PSSCR, host_psscr | mtspr(SPRN_PSSCR, host_psscr |
(local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG)); (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 ...@@ -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)) if (cpu_has_feature(CPU_FTR_ARCH_31))
asm volatile(PPC_CP_ABORT); asm volatile(PPC_CP_ABORT);
vc->dpdes = mfspr(SPRN_DPDES);
vc->vtb = mfspr(SPRN_VTB);
mtspr(SPRN_DPDES, 0); mtspr(SPRN_DPDES, 0);
if (vc->pcr) if (vc->pcr)
mtspr(SPRN_PCR, PCR_MASK); mtspr(SPRN_PCR, PCR_MASK);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment